forked from andrew-hardin/cmake-git-version-tracking
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
272 lines (231 loc) · 14.3 KB
/
CMakeLists.txt
File metadata and controls
272 lines (231 loc) · 14.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
cmake_minimum_required(VERSION 3.2...3.27)
project(gtml LANGUAGES CXX)
set(NBL_GTML_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
function(_nbl_gtml_validate_identifier VALUE KIND)
if(NOT VALUE MATCHES "^[a-zA-Z0-9_]+$")
message(FATAL_ERROR "${KIND} \"${VALUE}\" contains illegal characters and must match '^[a-zA-Z0-9_]+$'.")
endif()
endfunction()
function(_nbl_gtml_make_header_guard GTML_HEADER_PATH OUT_VAR)
string(MAKE_C_IDENTIFIER "${GTML_HEADER_PATH}" _guard)
string(TOUPPER "${_guard}" _guard)
set(${OUT_VAR} "_${_guard}_INCLUDED_" PARENT_SCOPE)
endfunction()
function(_nbl_gtml_require_runtime_config OUT_TARGET OUT_NAMESPACE OUT_IGITINFO_HEADER OUT_JSON_FORMATTER_HEADER)
get_property(_runtime_target GLOBAL PROPERTY NBL_GTML_RUNTIME_TARGET)
if(NOT _runtime_target)
message(FATAL_ERROR "NBL_CONFIGURE_GIT_TRACKING_META_RUNTIME must be called before NBL_ADD_GIT_TRACKING_META_LIBRARY.")
endif()
get_property(_runtime_namespace GLOBAL PROPERTY NBL_GTML_RUNTIME_NAMESPACE)
get_property(_runtime_igitinfo_header GLOBAL PROPERTY NBL_GTML_RUNTIME_IGITINFO_HEADER)
get_property(_runtime_json_formatter_header GLOBAL PROPERTY NBL_GTML_RUNTIME_JSON_FORMATTER_HEADER)
set(${OUT_TARGET} "${_runtime_target}" PARENT_SCOPE)
set(${OUT_NAMESPACE} "${_runtime_namespace}" PARENT_SCOPE)
set(${OUT_IGITINFO_HEADER} "${_runtime_igitinfo_header}" PARENT_SCOPE)
set(${OUT_JSON_FORMATTER_HEADER} "${_runtime_json_formatter_header}" PARENT_SCOPE)
endfunction()
function(_nbl_gtml_parse_repo_pairs OUT_NAMES OUT_DIRS)
set(_args ${ARGN})
list(LENGTH _args _count)
math(EXPR _mod "${_count} % 2")
if(NOT _mod EQUAL 0)
message(FATAL_ERROR "REPOS must contain <name> <working_dir> pairs.")
endif()
set(_names)
set(_dirs)
while(_args)
list(POP_FRONT _args _name)
list(POP_FRONT _args _dir)
_nbl_gtml_validate_identifier("${_name}" "Repo name")
list(APPEND _names "${_name}")
list(APPEND _dirs "${_dir}")
endwhile()
set(${OUT_NAMES} "${_names}" PARENT_SCOPE)
set(${OUT_DIRS} "${_dirs}" PARENT_SCOPE)
endfunction()
function(_nbl_gtml_define_symbolic_stamp STAMP_FILE)
add_custom_command(
OUTPUT "${STAMP_FILE}"
COMMAND "${CMAKE_COMMAND}" -E echo_append ""
VERBATIM
)
set_source_files_properties("${STAMP_FILE}" PROPERTIES SYMBOLIC TRUE)
endfunction()
function(_nbl_gtml_add_repo_source OUT_CPP OUT_JSON)
cmake_parse_arguments(REPO "" "NAME;WORKING_DIR;OUTPUT_DIR;HEADER_PATH;NAMESPACE;STAMP_FILE;RUNTIME_NAMESPACE;RUNTIME_IGITINFO_HEADER_PATH" "" ${ARGN})
if(NOT DEFINED REPO_NAME OR NOT DEFINED REPO_WORKING_DIR OR NOT DEFINED REPO_OUTPUT_DIR OR NOT DEFINED REPO_HEADER_PATH OR NOT DEFINED REPO_NAMESPACE OR NOT DEFINED REPO_STAMP_FILE OR NOT DEFINED REPO_RUNTIME_NAMESPACE OR NOT DEFINED REPO_RUNTIME_IGITINFO_HEADER_PATH)
message(FATAL_ERROR "_nbl_gtml_add_repo_source missing required argument.")
endif()
set(SRC_DIR "${CMAKE_CURRENT_FUNCTION_LIST_DIR}")
set(PRE_CONFIGURE_FILE "${SRC_DIR}/template_git_info.cpp.in")
set(PRE_CONFIGURE_FILE_JSON "${SRC_DIR}/template_git_info.json.in")
set(GTML_INFO "/* This file is auto-generated by CMake's configure_file function from the template: `template_git_info.cpp.in`. * Do not edit this file manually. */")
set(GTML_NAME "${REPO_NAME}")
set(GTML_NAMESPACE "${REPO_NAMESPACE}")
set(GTML_HEADER_PATH "${REPO_HEADER_PATH}")
set(GTML_RUNTIME_NAMESPACE "${REPO_RUNTIME_NAMESPACE}")
set(GTML_RUNTIME_IGITINFO_HEADER_PATH "${REPO_RUNTIME_IGITINFO_HEADER_PATH}")
set(POST_CONFIGURE_FILE "${REPO_OUTPUT_DIR}/${REPO_NAME}_git_info.cpp")
set(POST_CONFIGURE_FILE_JSON "${REPO_OUTPUT_DIR}/${REPO_NAME}_git_info.json")
set(GIT_STATE_FILE "${REPO_OUTPUT_DIR}/${REPO_NAME}-git-state-hash")
set(GIT_WORKING_DIR "${REPO_WORKING_DIR}")
set(NBL_GTML_STAMP_FILE "${REPO_STAMP_FILE}")
include("${SRC_DIR}/git_watcher.cmake")
set(${OUT_CPP} "${POST_CONFIGURE_FILE}" PARENT_SCOPE)
set(${OUT_JSON} "${POST_CONFIGURE_FILE_JSON}" PARENT_SCOPE)
endfunction()
function(NBL_CONFIGURE_GIT_TRACKING_META_RUNTIME)
cmake_parse_arguments(GTML "" "TARGET;NAMESPACE;IGITINFO_HEADER_PATH;JSON_FORMATTER_HEADER_PATH" "" ${ARGN})
if(NOT DEFINED GTML_TARGET OR GTML_TARGET STREQUAL "")
message(FATAL_ERROR "NBL_CONFIGURE_GIT_TRACKING_META_RUNTIME requires TARGET <target>.")
endif()
if(NOT DEFINED GTML_NAMESPACE OR GTML_NAMESPACE STREQUAL "")
message(FATAL_ERROR "NBL_CONFIGURE_GIT_TRACKING_META_RUNTIME requires NAMESPACE <namespace>.")
endif()
if(NOT DEFINED GTML_IGITINFO_HEADER_PATH OR GTML_IGITINFO_HEADER_PATH STREQUAL "")
message(FATAL_ERROR "NBL_CONFIGURE_GIT_TRACKING_META_RUNTIME requires IGITINFO_HEADER_PATH <relative_header_path>.")
endif()
if(NOT DEFINED GTML_JSON_FORMATTER_HEADER_PATH OR GTML_JSON_FORMATTER_HEADER_PATH STREQUAL "")
message(FATAL_ERROR "NBL_CONFIGURE_GIT_TRACKING_META_RUNTIME requires JSON_FORMATTER_HEADER_PATH <relative_header_path>.")
endif()
if(TARGET "${GTML_TARGET}")
message(FATAL_ERROR "Target \"${GTML_TARGET}\" already exists.")
endif()
get_property(_runtime_target GLOBAL PROPERTY NBL_GTML_RUNTIME_TARGET)
if(_runtime_target)
message(FATAL_ERROR "Git tracking runtime was already configured for target \"${_runtime_target}\".")
endif()
set(_runtime_binary_dir "${NBL_GTML_BINARY_DIR}/${GTML_TARGET}")
set(_runtime_include_root "${_runtime_binary_dir}/include")
set(_igitinfo_output "${_runtime_include_root}/${GTML_IGITINFO_HEADER_PATH}")
set(_json_formatter_output "${_runtime_include_root}/${GTML_JSON_FORMATTER_HEADER_PATH}")
get_filename_component(_igitinfo_output_dir "${_igitinfo_output}" DIRECTORY)
get_filename_component(_json_formatter_output_dir "${_json_formatter_output}" DIRECTORY)
file(MAKE_DIRECTORY "${_runtime_binary_dir}" "${_runtime_include_root}" "${_igitinfo_output_dir}" "${_json_formatter_output_dir}")
_nbl_gtml_make_header_guard("${GTML_IGITINFO_HEADER_PATH}" GTML_RUNTIME_IGITINFO_HEADER_GUARD)
_nbl_gtml_make_header_guard("${GTML_JSON_FORMATTER_HEADER_PATH}" GTML_RUNTIME_JSON_FORMATTER_HEADER_GUARD)
set(GTML_INFO "/* This file is auto-generated by CMake's configure_file function from the template: `runtime_IGitInfo.h.in`.\n * Do not edit this file manually. */")
set(GTML_RUNTIME_NAMESPACE "${GTML_NAMESPACE}")
configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/runtime_IGitInfo.h.in" "${_igitinfo_output}" @ONLY)
set(GTML_INFO "/* This file is auto-generated by CMake's configure_file function from the template: `runtime_SJsonFormatter.h.in`.\n * Do not edit this file manually. */")
set(GTML_RUNTIME_IGITINFO_HEADER_PATH "${GTML_IGITINFO_HEADER_PATH}")
set(GTML_RUNTIME_JSON_FORMATTER_HEADER_PATH "${GTML_JSON_FORMATTER_HEADER_PATH}")
configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/runtime_SJsonFormatter.h.in" "${_json_formatter_output}" @ONLY)
set(GTML_INFO "/* This file is auto-generated by CMake's configure_file function from the template: `runtime_SJsonFormatter.cpp.in`.\n * Do not edit this file manually. */")
set(_json_formatter_cpp "${_runtime_binary_dir}/SJsonFormatter.cpp")
configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/runtime_SJsonFormatter.cpp.in" "${_json_formatter_cpp}" @ONLY)
add_library("${GTML_TARGET}" STATIC "${_json_formatter_cpp}")
target_include_directories("${GTML_TARGET}" SYSTEM PUBLIC "${_runtime_include_root}")
target_link_libraries("${GTML_TARGET}" PRIVATE nlohmann_json::nlohmann_json)
set_target_properties("${GTML_TARGET}" PROPERTIES UNITY_BUILD OFF DISABLE_PRECOMPILE_HEADERS ON CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)
set_property(GLOBAL PROPERTY NBL_GTML_RUNTIME_TARGET "${GTML_TARGET}")
set_property(GLOBAL PROPERTY NBL_GTML_RUNTIME_NAMESPACE "${GTML_NAMESPACE}")
set_property(GLOBAL PROPERTY NBL_GTML_RUNTIME_IGITINFO_HEADER "${GTML_IGITINFO_HEADER_PATH}")
set_property(GLOBAL PROPERTY NBL_GTML_RUNTIME_JSON_FORMATTER_HEADER "${GTML_JSON_FORMATTER_HEADER_PATH}")
set_property(GLOBAL PROPERTY NBL_GTML_RUNTIME_IGITINFO_OUTPUT "${_igitinfo_output}")
set_property(GLOBAL PROPERTY NBL_GTML_RUNTIME_JSON_FORMATTER_OUTPUT "${_json_formatter_output}")
endfunction()
function(NBL_GET_GIT_TRACKING_META_RUNTIME_OUTPUTS)
cmake_parse_arguments(GTML "" "IGITINFO_HEADER_OUTPUT_VAR;JSON_FORMATTER_HEADER_OUTPUT_VAR" "" ${ARGN})
get_property(_igitinfo_header GLOBAL PROPERTY NBL_GTML_RUNTIME_IGITINFO_OUTPUT)
get_property(_json_formatter_header GLOBAL PROPERTY NBL_GTML_RUNTIME_JSON_FORMATTER_OUTPUT)
if(DEFINED GTML_IGITINFO_HEADER_OUTPUT_VAR AND NOT GTML_IGITINFO_HEADER_OUTPUT_VAR STREQUAL "")
set(${GTML_IGITINFO_HEADER_OUTPUT_VAR} "${_igitinfo_header}" PARENT_SCOPE)
endif()
if(DEFINED GTML_JSON_FORMATTER_HEADER_OUTPUT_VAR AND NOT GTML_JSON_FORMATTER_HEADER_OUTPUT_VAR STREQUAL "")
set(${GTML_JSON_FORMATTER_HEADER_OUTPUT_VAR} "${_json_formatter_header}" PARENT_SCOPE)
endif()
endfunction()
function(NBL_ADD_GIT_TRACKING_META_LIBRARY)
cmake_parse_arguments(GTML "" "TARGET;NAMESPACE;HEADER_PATH" "REPOS" ${ARGN})
if(NOT DEFINED GTML_TARGET OR GTML_TARGET STREQUAL "")
message(FATAL_ERROR "NBL_ADD_GIT_TRACKING_META_LIBRARY requires TARGET <target>.")
endif()
if(NOT DEFINED GTML_NAMESPACE OR GTML_NAMESPACE STREQUAL "")
message(FATAL_ERROR "NBL_ADD_GIT_TRACKING_META_LIBRARY requires NAMESPACE <namespace>.")
endif()
if(NOT DEFINED GTML_HEADER_PATH OR GTML_HEADER_PATH STREQUAL "")
message(FATAL_ERROR "NBL_ADD_GIT_TRACKING_META_LIBRARY requires HEADER_PATH <relative_header_path>.")
endif()
if(NOT GTML_REPOS)
message(FATAL_ERROR "NBL_ADD_GIT_TRACKING_META_LIBRARY requires REPOS <name> <path> [<name> <path> ...].")
endif()
_nbl_gtml_validate_identifier("${GTML_TARGET}" "Target")
_nbl_gtml_parse_repo_pairs(_repo_names _repo_dirs ${GTML_REPOS})
_nbl_gtml_require_runtime_config(_runtime_target _runtime_namespace _runtime_igitinfo_header _runtime_json_formatter_header)
if(TARGET "${GTML_TARGET}")
message(FATAL_ERROR "Target \"${GTML_TARGET}\" already exists.")
endif()
set(_target_binary_dir "${NBL_GTML_BINARY_DIR}/${GTML_TARGET}")
set(_target_include_root "${_target_binary_dir}/include")
set(_header_output "${_target_include_root}/${GTML_HEADER_PATH}")
get_filename_component(_header_output_dir "${_header_output}" DIRECTORY)
file(MAKE_DIRECTORY "${_target_binary_dir}" "${_header_output_dir}")
set(_stamp_file "${_target_binary_dir}/stamp")
_nbl_gtml_define_symbolic_stamp("${_stamp_file}")
set(_repo_cpps)
set(_repo_jsons)
set(_repo_enums)
set(_repo_externs "")
set(_repo_array)
string(ASCII 59 _repo_semicolon)
list(LENGTH _repo_names _repo_count)
math(EXPR _repo_last "${_repo_count} - 1")
foreach(_repo_ix RANGE ${_repo_last})
list(GET _repo_names ${_repo_ix} _repo_name)
list(GET _repo_dirs ${_repo_ix} _repo_dir)
_nbl_gtml_add_repo_source(_repo_cpp _repo_json
NAME "${_repo_name}"
WORKING_DIR "${_repo_dir}"
OUTPUT_DIR "${_target_binary_dir}"
HEADER_PATH "${GTML_HEADER_PATH}"
NAMESPACE "${GTML_NAMESPACE}"
STAMP_FILE "${_stamp_file}"
RUNTIME_NAMESPACE "${_runtime_namespace}"
RUNTIME_IGITINFO_HEADER_PATH "${_runtime_igitinfo_header}"
)
list(APPEND _repo_cpps "${_repo_cpp}")
list(APPEND _repo_jsons "${_repo_json}")
string(TOUPPER "${_repo_name}" _repo_enum)
list(APPEND _repo_enums "EGRM_${_repo_enum}")
string(APPEND _repo_externs " extern const ::${_runtime_namespace}::IGitInfo& ${_repo_name}_git_info${_repo_semicolon}\n")
list(APPEND _repo_array "&${_repo_name}_git_info")
endforeach()
string(REPLACE ";" ", " GTML_ENUMS "${_repo_enums}")
set(GTML_EXTERNS "${_repo_externs}")
string(REPLACE ";" ", " GTML_ARRAY "${_repo_array}")
_nbl_gtml_make_header_guard("${GTML_HEADER_PATH}" GTML_HEADER_GUARD)
set(GTML_NAMESPACE "${GTML_NAMESPACE}")
set(GTML_HEADER_PATH "${GTML_HEADER_PATH}")
set(GTML_RUNTIME_NAMESPACE "${_runtime_namespace}")
set(GTML_RUNTIME_IGITINFO_HEADER_PATH "${_runtime_igitinfo_header}")
set(GTML_INFO "/* This file is auto-generated by CMake's configure_file function from the template: `git_info.h.in`.\n * Do not edit this file manually. */")
configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/git_info.h.in" "${_header_output}" @ONLY)
set(_aggregate_cpp "${_target_binary_dir}/git_info.cpp")
set(GTML_INFO "/* This file is auto-generated by CMake's configure_file function from the template: `git_info.cpp.in`.\n * Do not edit this file manually. */")
configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/git_info.cpp.in" "${_aggregate_cpp}" @ONLY)
add_library("${GTML_TARGET}" STATIC ${_repo_cpps} "${_aggregate_cpp}")
target_include_directories("${GTML_TARGET}" SYSTEM PUBLIC "${_target_include_root}")
target_link_libraries("${GTML_TARGET}" PUBLIC "${_runtime_target}")
if("${GTML_TARGET}" STREQUAL "${PROJECT_NAME}")
set_target_properties("${GTML_TARGET}" PROPERTIES UNITY_BUILD TRUE CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)
else()
set_target_properties("${GTML_TARGET}" PROPERTIES UNITY_BUILD OFF DISABLE_PRECOMPILE_HEADERS ON CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON)
endif()
set_property(GLOBAL PROPERTY "NBL_GTML_${GTML_TARGET}_HEADER_OUTPUT" "${_header_output}")
set_property(GLOBAL PROPERTY "NBL_GTML_${GTML_TARGET}_JSON_OUTPUTS" "${_repo_jsons}")
endfunction()
function(NBL_GET_GIT_TRACKING_META_OUTPUTS)
cmake_parse_arguments(GTML "" "TARGET;HEADER_OUTPUT_VAR;JSON_OUTPUTS_VAR" "" ${ARGN})
if(NOT DEFINED GTML_TARGET OR GTML_TARGET STREQUAL "")
message(FATAL_ERROR "NBL_GET_GIT_TRACKING_META_OUTPUTS requires TARGET <target>.")
endif()
get_property(_header GLOBAL PROPERTY "NBL_GTML_${GTML_TARGET}_HEADER_OUTPUT")
get_property(_jsons GLOBAL PROPERTY "NBL_GTML_${GTML_TARGET}_JSON_OUTPUTS")
if(DEFINED GTML_HEADER_OUTPUT_VAR AND NOT GTML_HEADER_OUTPUT_VAR STREQUAL "")
set(${GTML_HEADER_OUTPUT_VAR} "${_header}" PARENT_SCOPE)
endif()
if(DEFINED GTML_JSON_OUTPUTS_VAR AND NOT GTML_JSON_OUTPUTS_VAR STREQUAL "")
set(${GTML_JSON_OUTPUTS_VAR} "${_jsons}" PARENT_SCOPE)
endif()
endfunction()