├── .gitignore
├── .gitattributes
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
└── CONTRIBUTING.md
├── CHANGELOG.md
├── README.md
├── LICENSE
└── src
└── utils.cmake
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | temp/
3 | **/*.log
4 | /core
5 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.ico binary
3 | *.woff binary
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 |
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 | indent_style = space
10 | indent_size = 2
11 |
12 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: sagiegurari
7 |
8 | ---
9 |
10 | ### Feature Description
11 |
12 |
13 | ### Describe The Solution You'd Like
14 |
15 |
16 | ### Code Sample
17 |
18 | ```cmake
19 | # paste code here
20 | ```
21 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribution Guidelines
2 |
3 | ## Issues
4 |
5 | Found a bug? Got a question? Want some enhancement?
6 | First place to go is the repository issues section, and I'll try to help as much as possible.
7 |
8 | ## Pull Requests
9 |
10 | Fixed a bug or just want to provided additional functionality?
11 | Simply fork this repository, implement your changes and create a pull request.
12 | Please make sure to provide documentation as part of your changes.
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: sagiegurari
7 |
8 | ---
9 |
10 | ### Describe The Bug
11 |
12 |
13 | ### To Reproduce
14 |
15 |
16 | ### Error Stack
17 |
18 | ```console
19 | The error message
20 | ```
21 |
22 | ### Code Sample
23 |
24 | ```cmake
25 | # paste code here
26 | ```
27 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## CHANGELOG
2 |
3 | ### v0.5.1 (2023-09-21)
4 |
5 | * New utils_embed_example_source_in_readme function
6 |
7 | ### v0.5.0 (2023-08-12)
8 |
9 | * utils_uncrustify and utils_cppcheck now support optional ALL FALSE argument
10 | * New utils_build_file_increment function
11 | * New utils_xxd function
12 | * New utils_xxd_all function
13 |
14 | ### v0.4.1 (2023-01-02)
15 |
16 | * Setup tests now accepts additional library dependencies
17 | * New cpp check function
18 | * New uncrustify function
19 |
20 | ### v0.4.0 (2020-09-25)
21 |
22 | * New utils_setup_c_all_tests function
23 |
24 | ### v0.3.0 (2020-08-23)
25 |
26 | * Function utils_setup_c_test now supports a list of test names
27 | * Tag name is now optional parameter
28 |
29 | ### v0.2.0 (2020-08-23)
30 |
31 | * Changed all utilities to functions with named parameters
32 |
33 | ### v0.1.0 (2020-08-21)
34 |
35 | * Initial Release
36 |
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cmake-modules
2 |
3 | [](https://github.com/sagiegurari/cmake-modules/releases)
4 | [](https://github.com/sagiegurari/cmake-modules/blob/master/LICENSE)
5 |
6 | > Reusable cmake utilities for C projects.
7 |
8 | * [Overview](#overview)
9 | * [Usage](#usage)
10 | * [Contributing](.github/CONTRIBUTING.md)
11 | * [Release History](CHANGELOG.md)
12 | * [License](#license)
13 |
14 |
15 | ## Overview
16 | The cmake-modules contains basic reusable building blocks for cmake C projects.
17 | Those include:
18 |
19 | * Downloading git repository
20 | * Downloading github repository
21 | * Setting variables for sources, headers, etc... for downloaded repositories
22 | * Add test targets easily
23 | * Run ccpcheck
24 | * Run uncrustify
25 | * Create and increment build file
26 | * Run xxd on resource files
27 |
28 |
29 |
30 | Include the cmake modules in the module path
31 |
32 | ```cmake
33 | list(APPEND CMAKE_MODULE_PATH "cmake-modules/src")
34 | ```
35 |
36 | Load the cmake module
37 |
38 | ```cmake
39 | include(utils)
40 | ```
41 |
42 | Another way is to automatically download it if missing, for example:
43 |
44 | ```cmake
45 | if(NOT EXISTS "target/cmake-modules/src/utils.cmake")
46 | execute_process(COMMAND git clone https://github.com/sagiegurari/cmake-modules.git)
47 | endif()
48 | include("target/cmake-modules/src/utils.cmake")
49 | ```
50 |
51 | Use the different capabilities in your CMakeLists.txt for example:
52 |
53 | ```cmake
54 | utils_add_external_github_lib(
55 | REPO_USERNAME sagiegurari
56 | REPO_NAME c_scriptexec
57 | TAG_NAME "0.1.3"
58 | LIBRARY_NAME scriptexec
59 | LIBRARY_PARENT_DIRECTORY target
60 | )
61 |
62 | utils_setup_c_test(
63 | NAME
64 | stability
65 | long_run
66 | valid_input
67 | invalid_input
68 | ADDITIONAL_SOURCES "test/core.c;test/core.h"
69 | COMPILATION_FLAGS "-Werror -Wall -Wextra -Wcast-align -Wunused -Wshadow -Wpedantic"
70 | BINARY_DIRECTORY "target/bin"
71 | )
72 |
73 | utils_setup_c_all_tests(
74 | ADDITIONAL_SOURCES "test/core.c;test/core.h"
75 | COMPILATION_FLAGS "-Werror -Wall -Wextra -Wcast-align -Wunused -Wshadow -Wpedantic"
76 | BINARY_DIRECTORY "target/bin"
77 | )
78 | ```
79 |
80 | ## Contributing
81 | See [contributing guide](.github/CONTRIBUTING.md)
82 |
83 |
84 | ## Release History
85 |
86 | See [Changelog](CHANGELOG.md)
87 |
88 |
89 | ## License
90 | Developed by Sagie Gur-Ari and licensed under the Apache 2 open source license.
91 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/src/utils.cmake:
--------------------------------------------------------------------------------
1 |
2 | # Downloads a git repository
3 | #
4 | # Params:
5 | # * URL - Git repo URL
6 | # * REPO_NAME - Git repo name
7 | # * [TAG_NAME] - Optional git tag name
8 | function(utils_git_clone)
9 | set(oneValueArgs URL REPO_NAME TAG_NAME)
10 | cmake_parse_arguments(UTILS_GIT_CLONE "" "${oneValueArgs}" "" ${ARGN})
11 |
12 | message(
13 | "Cloning Git Repository: ${UTILS_GIT_CLONE_REPO_NAME} "
14 | "URL: ${UTILS_GIT_CLONE_URL} "
15 | "Tag: ${UTILS_GIT_CLONE_TAG_NAME}"
16 | )
17 |
18 | execute_process(
19 | COMMAND git clone ${UTILS_GIT_CLONE_URL}
20 | )
21 |
22 | if(UTILS_GIT_CLONE_TAG_NAME)
23 | execute_process(
24 | COMMAND git checkout tags/${UTILS_GIT_CLONE_TAG_NAME}
25 | WORKING_DIRECTORY ${UTILS_GIT_CLONE_REPO_NAME}
26 | )
27 | endif()
28 | endfunction(utils_git_clone)
29 |
30 | # Downloads a git repository
31 | #
32 | # Params:
33 | # * REPO_USERNAME - Github repo user name
34 | # * REPO_NAME - Github repo name
35 | # * [TAG_NAME] - Optional git tag name
36 | function(utils_github_clone_repo)
37 | set(oneValueArgs REPO_USERNAME REPO_NAME TAG_NAME)
38 | cmake_parse_arguments(UTILS_GITHUB_CLONE_REPO "" "${oneValueArgs}" "" ${ARGN})
39 |
40 | utils_git_clone(
41 | URL https://github.com/${UTILS_GITHUB_CLONE_REPO_REPO_USERNAME}/${UTILS_GITHUB_CLONE_REPO_REPO_NAME}.git
42 | REPO_NAME ${UTILS_GITHUB_CLONE_REPO_REPO_NAME}
43 | TAG_NAME ${UTILS_GITHUB_CLONE_REPO_TAG_NAME}
44 | )
45 | endfunction(utils_github_clone_repo)
46 |
47 | # Sets variables to an external library.
48 | #
49 | # Params:
50 | # * NAME - Library name
51 | # * PATH - Library path
52 | function(utils_set_standard_external_lib_variables)
53 | set(oneValueArgs NAME PATH)
54 | cmake_parse_arguments(UTILS_SET_STANDARD_EXTERNAL_LIB_VARIABLES "" "${oneValueArgs}" "" ${ARGN})
55 |
56 | string(TOUPPER "${UTILS_SET_STANDARD_EXTERNAL_LIB_VARIABLES_NAME}" X_EXTERNAL_LIB_NAME)
57 | set("X_EXTERNAL_LIB_NAME_ROOT" "${UTILS_SET_STANDARD_EXTERNAL_LIB_VARIABLES_PATH}")
58 | file(GLOB "X_EXTERNAL_LIB_NAME_SOURCES" "${X_EXTERNAL_LIB_NAME_ROOT}/src/*.c*")
59 | set("X_EXTERNAL_LIB_NAME_INCLUDE" "${X_EXTERNAL_LIB_NAME_ROOT}/include")
60 |
61 | set("X_EXTERNAL_LIB_NAME" "${X_EXTERNAL_LIB_NAME}" PARENT_SCOPE)
62 | set("${X_EXTERNAL_LIB_NAME}_ROOT" "${X_EXTERNAL_LIB_NAME_ROOT}" PARENT_SCOPE)
63 | set("${X_EXTERNAL_LIB_NAME}_SOURCES" "${X_EXTERNAL_LIB_NAME_SOURCES}" PARENT_SCOPE)
64 | set("${X_EXTERNAL_LIB_NAME}_INCLUDE" "${X_EXTERNAL_LIB_NAME_INCLUDE}" PARENT_SCOPE)
65 | endfunction(utils_set_standard_external_lib_variables)
66 |
67 | # Downloads an external repo from github and sets variables to the external
68 | # library source and header directories (if they are structured as expected).
69 | #
70 | # Params:
71 | # * REPO_USERNAME - Github repo user name
72 | # * REPO_NAME - Github repo name
73 | # * [TAG_NAME] - Optional git tag name
74 | # * LIBRARY_NAME - Library name
75 | # * LIBRARY_PARENT_DIRECTORY - Library parent directory
76 | function(utils_add_external_github_lib)
77 | set(oneValueArgs REPO_USERNAME REPO_NAME TAG_NAME LIBRARY_NAME LIBRARY_PARENT_DIRECTORY)
78 | cmake_parse_arguments(UTILS_ADD_EXTERNAL_GITHUB_LIB "" "${oneValueArgs}" "" ${ARGN})
79 |
80 | message(
81 | "Adding External Library: ${UTILS_ADD_EXTERNAL_GITHUB_LIB_LIBRARY_NAME} "
82 | "Github Repostiory: ${UTILS_ADD_EXTERNAL_GITHUB_LIB_REPO_USERNAME}/${UTILS_ADD_EXTERNAL_GITHUB_LIB_REPO_NAME} "
83 | "Tag: ${UTILS_ADD_EXTERNAL_GITHUB_LIB_TAG_NAME}"
84 | )
85 |
86 | utils_github_clone_repo(
87 | REPO_USERNAME ${UTILS_ADD_EXTERNAL_GITHUB_LIB_REPO_USERNAME}
88 | REPO_NAME ${UTILS_ADD_EXTERNAL_GITHUB_LIB_REPO_NAME}
89 | TAG_NAME ${UTILS_ADD_EXTERNAL_GITHUB_LIB_TAG_NAME}
90 | )
91 |
92 | utils_set_standard_external_lib_variables(
93 | NAME ${UTILS_ADD_EXTERNAL_GITHUB_LIB_LIBRARY_NAME}
94 | PATH "${UTILS_ADD_EXTERNAL_GITHUB_LIB_LIBRARY_PARENT_DIRECTORY}/${UTILS_ADD_EXTERNAL_GITHUB_LIB_REPO_NAME}"
95 | )
96 | # proxy variables
97 | set("${X_EXTERNAL_LIB_NAME}_ROOT" "${${X_EXTERNAL_LIB_NAME}_ROOT}" PARENT_SCOPE)
98 | set("${X_EXTERNAL_LIB_NAME}_SOURCES" "${${X_EXTERNAL_LIB_NAME}_SOURCES}" PARENT_SCOPE)
99 | set("${X_EXTERNAL_LIB_NAME}_INCLUDE" "${${X_EXTERNAL_LIB_NAME}_INCLUDE}" PARENT_SCOPE)
100 |
101 | message("External Library Variables:")
102 | message("${X_EXTERNAL_LIB_NAME}_ROOT ${X_EXTERNAL_LIB_NAME_ROOT}")
103 | message("${X_EXTERNAL_LIB_NAME}_SOURCES ${X_EXTERNAL_LIB_NAME_SOURCES}")
104 | message("${X_EXTERNAL_LIB_NAME}_INCLUDE ${X_EXTERNAL_LIB_NAME_INCLUDE}")
105 | endfunction(utils_add_external_github_lib)
106 |
107 | # Adds a test target/s with the given name/s.
108 | # Tests are expected to be located at the tests directory and should be named
109 | # as "test_.c"
110 | # In addition, the CMAKE_PROJECT_NAME variable is expected to be defined.
111 | #
112 | # Params:
113 | # * NAME - Test name/s
114 | # * ADDITIONAL_SOURCES - Additional test sources
115 | # * COMPILATION_FLAGS - Compliation flags
116 | # * BINARY_DIRECTORY - Binary directory
117 | # * LIBRARIES - Additional test libraries
118 | function(utils_setup_c_test)
119 | set(oneValueArgs COMPILATION_FLAGS BINARY_DIRECTORY)
120 | set(multiValueArgs NAME ADDITIONAL_SOURCES LIBRARIES)
121 | cmake_parse_arguments(UTILS_SETUP_C_TEST "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
122 |
123 | foreach(TEST_NAME ${UTILS_SETUP_C_TEST_NAME})
124 | message("Adding Test: ${TEST_NAME}")
125 | add_executable(test_${TEST_NAME} tests/test_${TEST_NAME}.c ${UTILS_SETUP_C_TEST_ADDITIONAL_SOURCES})
126 | target_link_libraries(test_${TEST_NAME} ${CMAKE_PROJECT_NAME} ${UTILS_SETUP_C_TEST_LIBRARIES})
127 | set_target_properties(
128 | test_${TEST_NAME}
129 | PROPERTIES COMPILE_FLAGS "${UTILS_SETUP_C_TEST_COMPILATION_FLAGS}"
130 | )
131 | add_test(
132 | NAME ${TEST_NAME}
133 | WORKING_DIRECTORY ${UTILS_SETUP_C_TEST_BINARY_DIRECTORY}
134 | COMMAND test_${TEST_NAME}
135 | )
136 | endforeach(TEST_NAME)
137 | endfunction(utils_setup_c_test)
138 |
139 | # Adds test targets for all test files found under the tests directory.
140 | # Tests are expected to be located at the tests directory and should be named
141 | # as "test_.c"
142 | # In addition, the CMAKE_PROJECT_NAME variable is expected to be defined.
143 | #
144 | # Params:
145 | # * ADDITIONAL_SOURCES - Additional test sources
146 | # * COMPILATION_FLAGS - Compliation flags
147 | # * BINARY_DIRECTORY - Binary directory
148 | # * LIBRARIES - Additional test libraries
149 | function(utils_setup_c_all_tests)
150 | set(oneValueArgs COMPILATION_FLAGS BINARY_DIRECTORY)
151 | set(multiValueArgs ADDITIONAL_SOURCES LIBRARIES)
152 | cmake_parse_arguments(UTILS_SETUP_C_ALL_TESTS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
153 |
154 | file(
155 | GLOB TEST_FILES
156 | LIST_DIRECTORIES false
157 | ./tests/test_*.c
158 | )
159 |
160 | foreach(TEST_NAME ${TEST_FILES})
161 | string(REGEX REPLACE ".*/tests/test_" "" TEST_NAME ${TEST_NAME})
162 | string(REGEX REPLACE "\\.c" "" TEST_NAME ${TEST_NAME})
163 |
164 | list(APPEND TEST_NAMES ${TEST_NAME})
165 | endforeach(TEST_NAME)
166 |
167 | message("Found Tests: ${TEST_NAMES}")
168 |
169 | utils_setup_c_test(
170 | NAME ${TEST_NAMES}
171 | ADDITIONAL_SOURCES "${UTILS_SETUP_C_ALL_TESTS_ADDITIONAL_SOURCES}"
172 | COMPILATION_FLAGS "${UTILS_SETUP_C_ALL_TESTS_COMPILATION_FLAGS}"
173 | BINARY_DIRECTORY "${UTILS_SETUP_C_ALL_TESTS_BINARY_DIRECTORY}"
174 | LIBRARIES ${UTILS_SETUP_C_ALL_TESTS_LIBRARIES}
175 | )
176 | endfunction(utils_setup_c_all_tests)
177 |
178 | # Adds test targets for all test files found under the tests directory.
179 | # Tests are expected to be located at the tests directory and should be named
180 | # as "test_.c"
181 | # In addition, the CMAKE_PROJECT_NAME variable is expected to be defined.
182 | #
183 | # Params:
184 | # * SOURCES - Test sources
185 | # * COMPILATION_FLAGS - Compliation flags
186 | function(utils_setup_test_lib)
187 | set(oneValueArgs COMPILATION_FLAGS)
188 | set(multiValueArgs SOURCES)
189 | cmake_parse_arguments(UTILS_SETUP_TEST_LIB "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
190 |
191 | add_library("Test" STATIC ${UTILS_SETUP_TEST_LIB_SOURCES})
192 | target_link_libraries("Test" ${CMAKE_PROJECT_NAME})
193 | set_target_properties(
194 | "Test"
195 | PROPERTIES COMPILE_FLAGS "${UTILS_SETUP_TEST_LIB_COMPILATION_FLAGS}"
196 | )
197 | endfunction(utils_setup_test_lib)
198 |
199 | # Adds linter target.
200 | #
201 | # Params:
202 | # * INCLUDE_DIRECTORY
203 | # * SOURCES - The sources to check
204 | # * WORKING_DIRECTORY
205 | # * [ALL] - FALSE for not ALL, otherwise any value (including undefined) is by default ALL
206 | function(utils_cppcheck)
207 | set(oneValueArgs INCLUDE_DIRECTORY WORKING_DIRECTORY ALL)
208 | set(multiValueArgs SOURCES)
209 | cmake_parse_arguments(UTILS_CPPCHECK "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
210 |
211 | find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
212 |
213 | if (CMAKE_CXX_CPPCHECK)
214 | if ("${UTILS_CPPCHECK_ALL}" STREQUAL "FALSE")
215 | set(ALL)
216 | else()
217 | set(ALL ALL)
218 | endif()
219 |
220 | add_custom_target(cppcheck ${ALL}
221 | ${CMAKE_CXX_CPPCHECK}
222 | --enable=all --inline-suppr --error-exitcode=1 --suppress=missingIncludeSystem -I ${UTILS_CPPCHECK_INCLUDE_DIRECTORY} ${UTILS_CPPCHECK_SOURCES}
223 | WORKING_DIRECTORY "${UTILS_CPPCHECK_WORKING_DIRECTORY}")
224 | endif()
225 | endfunction(utils_cppcheck)
226 |
227 | # Adds formatter target.
228 | #
229 | # Params:
230 | # * CONFIG_FILE - The uncrustify cfg
231 | # * SOURCES - The sources to format
232 | # * [ALL] - FALSE for not ALL, otherwise any value (including undefined) is by default ALL
233 | function(utils_uncrustify)
234 | set(oneValueArgs CONFIG_FILE ALL)
235 | set(multiValueArgs SOURCES)
236 | cmake_parse_arguments(UTILS_UNCRUSTIFY "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
237 |
238 | find_program(CMAKE_CXX_UNCRUSTIFY NAMES uncrustify)
239 |
240 | if (CMAKE_CXX_UNCRUSTIFY)
241 | if ("${UTILS_UNCRUSTIFY_ALL}" STREQUAL "FALSE")
242 | set(ALL)
243 | else()
244 | set(ALL ALL)
245 | endif()
246 |
247 | add_custom_target(uncrustify ${ALL}
248 | uncrustify
249 | -c ${UTILS_UNCRUSTIFY_CONFIG_FILE}
250 | --no-backup ${UTILS_UNCRUSTIFY_SOURCES})
251 | endif()
252 | endfunction(utils_uncrustify)
253 |
254 | # Increments the build file (or creates a new one is
255 | # does not exist) and sets the variable to the new value.
256 | # This can be wrapped via add_custom_command to a standalone cmake
257 | # file that can trigger this function.
258 | #
259 | # Params:
260 | # * BUILD_NUMBER_FILE - The path to the build number file
261 | # * NAME - The variable name to hold the new build number
262 | function(utils_build_file_increment)
263 | set(oneValueArgs BUILD_NUMBER_FILE NAME)
264 | cmake_parse_arguments(UTILS_BUILD_FILE_INCREMENT "" "${oneValueArgs}" "" ${ARGN})
265 |
266 | if(EXISTS ${UTILS_BUILD_FILE_INCREMENT_BUILD_NUMBER_FILE})
267 | file(READ ${UTILS_BUILD_FILE_INCREMENT_BUILD_NUMBER_FILE} BUILD_NUMBER)
268 | math(EXPR BUILD_NUMBER "${BUILD_NUMBER}+1")
269 | else()
270 | set(BUILD_NUMBER "1")
271 | endif()
272 |
273 | message("Build Number: ${BUILD_NUMBER}")
274 |
275 | file(WRITE ${UTILS_BUILD_FILE_INCREMENT_BUILD_NUMBER_FILE} "${BUILD_NUMBER}")
276 |
277 | set("${UTILS_BUILD_FILE_INCREMENT_NAME}" "${BUILD_NUMBER}" PARENT_SCOPE)
278 | endfunction(utils_build_file_increment)
279 |
280 | # Runs xxd on the given file to generate a C header content,
281 | # wraps it with header macros and writes it to a file.
282 | #
283 | # Params:
284 | # * INPUT_RAW_FILE - The input file to invoke the xxd on
285 | # * OUTPUT_HEADER_FILE - The output header file that will hold the generated content
286 | # * HEADER_NAME - Used in the header def macro
287 | # * ROOT_DIRECTORY - Used to get relative path to output file which impacts header content
288 | function(utils_xxd)
289 | set(oneValueArgs INPUT_RAW_FILE OUTPUT_HEADER_FILE HEADER_NAME ROOT_DIRECTORY)
290 | cmake_parse_arguments(UTILS_XXD "" "${oneValueArgs}" "" ${ARGN})
291 |
292 | get_filename_component(ROOT_DIRECTORY "${UTILS_XXD_ROOT_DIRECTORY}" ABSOLUTE)
293 | file(RELATIVE_PATH INPUT_RAW_FILE "${ROOT_DIRECTORY}" "${UTILS_XXD_INPUT_RAW_FILE}")
294 |
295 | message("Running xxd for file: ${INPUT_RAW_FILE}")
296 |
297 | execute_process(
298 | COMMAND "xxd" "-i" "${INPUT_RAW_FILE}"
299 | WORKING_DIRECTORY "${ROOT_DIRECTORY}"
300 | OUTPUT_VARIABLE HEADER_CONTENT
301 | COMMAND_ERROR_IS_FATAL ANY
302 | )
303 |
304 | set(HEADER_CONTENT "#ifndef ${UTILS_XXD_HEADER_NAME}_H\n#define ${UTILS_XXD_HEADER_NAME}_H\n${HEADER_CONTENT}\n#endif\n")
305 |
306 | if(EXISTS ${UTILS_XXD_OUTPUT_HEADER_FILE})
307 | file(READ ${UTILS_XXD_OUTPUT_HEADER_FILE} OLD_HEADER_CONTENT)
308 | if (NOT "${HEADER_CONTENT}" STREQUAL "${OLD_HEADER_CONTENT}")
309 | file(WRITE ${UTILS_XXD_OUTPUT_HEADER_FILE} "${HEADER_CONTENT}")
310 | endif()
311 | else()
312 | file(WRITE ${UTILS_XXD_OUTPUT_HEADER_FILE} "${HEADER_CONTENT}")
313 | endif()
314 |
315 | message(
316 | "Created Header File: ${UTILS_XXD_OUTPUT_HEADER_FILE}\n"
317 | "Content:\n${HEADER_CONTENT}"
318 | )
319 | endfunction(utils_xxd)
320 |
321 | # Runs xxd on all provided files and generate a C header file for them.
322 | #
323 | # Params:
324 | # * INPUT_RAW_FILES - All files to run xxd on
325 | # * ROOT_DIRECTORY - Used to get relative path to output file which impacts header content
326 | function(utils_xxd_all)
327 | set(oneValueArgs ROOT_DIRECTORY)
328 | set(multiValueArgs INPUT_RAW_FILES)
329 | cmake_parse_arguments(UTILS_XXD_ALL "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
330 |
331 | foreach(INPUT_RAW_FILE ${UTILS_XXD_ALL_INPUT_RAW_FILES})
332 | get_filename_component(OUTPUT_DIRECTORY ${INPUT_RAW_FILE} DIRECTORY)
333 | get_filename_component(BASE_FILENAME ${INPUT_RAW_FILE} NAME_WLE)
334 | set(OUTPUT_HEADER_FILE "${OUTPUT_DIRECTORY}/${BASE_FILENAME}_resource_template.h")
335 | string(TOUPPER "${BASE_FILENAME}_resource_template" HEADER_NAME)
336 |
337 | message(
338 | "XXD Args\n"
339 | "Raw File: ${INPUT_RAW_FILE}\n"
340 | "Output Header File: ${OUTPUT_HEADER_FILE}\n"
341 | "Header Name: ${HEADER_NAME}\n"
342 | "Root Directory: ${UTILS_XXD_ALL_ROOT_DIRECTORY}"
343 | )
344 |
345 | utils_xxd(
346 | INPUT_RAW_FILE "${INPUT_RAW_FILE}"
347 | OUTPUT_HEADER_FILE "${OUTPUT_HEADER_FILE}"
348 | HEADER_NAME "${HEADER_NAME}"
349 | ROOT_DIRECTORY "${UTILS_XXD_ALL_ROOT_DIRECTORY}"
350 | )
351 | endforeach(INPUT_RAW_FILE)
352 | endfunction(utils_xxd_all)
353 |
354 | # Reads the example source file and pushes the content into a marked
355 | # block inside the README.md file wrapped with code block characters.
356 | # It will search for prefix and suffix:
357 | #
358 | #
359 | # and push the content in between.
360 | # This can be wrapped via add_custom_command to a standalone cmake
361 | # file that can trigger this function.
362 | #
363 | # Params:
364 | # * EXAMPLE_FILE - The path to the example source file
365 | # * DOCUMENT_FILE - The path to the document file to modify
366 | # * SOURCE_TYPE - The type of source syntax for the markdown code block
367 | function(utils_embed_example_source_in_readme)
368 | set(oneValueArgs EXAMPLE_FILE DOCUMENT_FILE SOURCE_TYPE)
369 | cmake_parse_arguments(UTILS_EMBED_EXAMPLE_SOURCE_IN_README "" "${oneValueArgs}" "" ${ARGN})
370 |
371 | if(
372 | EXISTS ${UTILS_EMBED_EXAMPLE_SOURCE_IN_README_EXAMPLE_FILE}
373 | AND
374 | EXISTS ${UTILS_EMBED_EXAMPLE_SOURCE_IN_README_DOCUMENT_FILE}
375 | )
376 | file(READ ${UTILS_EMBED_EXAMPLE_SOURCE_IN_README_EXAMPLE_FILE} EXAMPLE_SOURCE)
377 | file(READ ${UTILS_EMBED_EXAMPLE_SOURCE_IN_README_DOCUMENT_FILE} README_CONTENT)
378 |
379 | string(STRIP "${EXAMPLE_SOURCE}" EXAMPLE_SOURCE)
380 |
381 | string(CONCAT MARKDOWN_SOURCE
382 | "\n```"
383 | "${UTILS_EMBED_EXAMPLE_SOURCE_IN_README_SOURCE_TYPE}"
384 | "\n"
385 | "${EXAMPLE_SOURCE}"
386 | "\n```\n")
387 | string(REGEX REPLACE ".*" "CMAKE_EXAMPLE_SOURCE_INJECT" README_CONTENT "${README_CONTENT}")
388 | string(REPLACE "CMAKE_EXAMPLE_SOURCE_INJECT" "${MARKDOWN_SOURCE}" README_CONTENT "${README_CONTENT}")
389 |
390 | file(WRITE ${UTILS_EMBED_EXAMPLE_SOURCE_IN_README_DOCUMENT_FILE} "${README_CONTENT}")
391 | endif()
392 | endfunction(utils_embed_example_source_in_readme)
393 |
394 |
--------------------------------------------------------------------------------