forked from jinja2cpp/Jinja2Cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CMakeLists.txt
357 lines (299 loc) · 12.9 KB
/
CMakeLists.txt
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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
cmake_minimum_required(VERSION 3.23.0)
if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()
project(Jinja2Cpp VERSION 1.3.2)
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
set(JINJA2CPP_IS_MAIN_PROJECT TRUE)
else()
set(JINJA2CPP_IS_MAIN_PROJECT FALSE)
endif()
# Options
set(JINJA2CPP_SANITIZERS address+undefined memory)
set(JINJA2CPP_WITH_SANITIZERS none CACHE STRING "Build with sanitizer")
set_property(CACHE JINJA2CPP_WITH_SANITIZERS PROPERTY STRINGS ${JINJA2CPP_SANITIZERS})
set(JINJA2CPP_SUPPORTED_REGEX std boost)
set(JINJA2CPP_USE_REGEX boost CACHE STRING "Use regex parser in lexer, boost works faster on most platforms")
set_property(CACHE JINJA2CPP_USE_REGEX PROPERTY STRINGS ${JINJA2CPP_SUPPORTED_REGEX})
set(JINJA2CPP_WITH_JSON_BINDINGS boost nlohmann rapid all none)
set(JINJA2CPP_WITH_JSON_BINDINGS boost CACHE STRING "Build with json support(boost|rapid)")
set_property(CACHE JINJA2CPP_WITH_JSON_BINDINGS PROPERTY STRINGS ${JINJA2CPP_WITH_JSON_BINDINGS})
set (JINJA2CPP_DEPS_MODE "internal" CACHE STRING "Jinja2Cpp dependency management mode (internal | external | external-boost | conan-build). See documentation for details. 'interal' is default.")
option(JINJA2CPP_BUILD_TESTS "Build Jinja2Cpp unit tests" ${JINJA2CPP_IS_MAIN_PROJECT})
option(JINJA2CPP_STRICT_WARNINGS "Enable additional warnings and treat them as errors" ON)
option(JINJA2CPP_BUILD_SHARED "Build shared linkage version of Jinja2Cpp" OFF)
option(JINJA2CPP_PIC "Control -fPIC option for library build" OFF)
option(JINJA2CPP_VERBOSE "Add extra debug output to the build scripts" OFF)
option(JINJA2CPP_INSTALL "Add installation rules for JinjaCpp targets" ${JINJA2CPP_IS_MAIN_PROJECT})
if (DEFINED BUILD_SHARED_LIBS)
set(JINJA2CPP_BUILD_SHARED ${BUILD_SHARED_LIBS})
endif ()
if (JINJA2CPP_BUILD_SHARED)
set(JINJA2CPP_PIC ON)
set(JINJA2CPP_MSVC_RUNTIME_TYPE "/MD")
endif ()
if (NOT JINJA2CPP_DEPS_MODE)
set(JINJA2CPP_DEPS_MODE "internal")
endif ()
if (JINJA2CPP_IS_MAIN_PROJECT OR NOT CMAKE_CXX_STANDARD)
set(JINJA2CPP_CXX_STANDARD 14 CACHE STRING "Jinja2Cpp C++ standard to build with. C++14 is default")
set(CMAKE_CXX_STANDARD ${JINJA2CPP_CXX_STANDARD})
endif ()
if (NOT JINJA2CPP_CXX_STANDARD)
set (JINJA2CPP_CXX_STANDARD ${CMAKE_CXX_STANDARD})
endif ()
if (JINJA2CPP_CXX_STANDARD LESS 14)
message(FATAL_ERROR "Jinja2Cpp is required C++14 or greater standard set. Currently selected standard: ${JINJA2CPP_CXX_STANDARD}")
else ()
message(STATUS "Jinja2Cpp C++ standard: ${JINJA2CPP_CXX_STANDARD}")
endif ()
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CLANG_CXX_FLAGS)
set(GCC_CXX_FLAGS)
set(MSVC_CXX_FLAGS)
if (JINJA2CPP_WITH_COVERAGE)
message(STATUS "This is DEBUG build with enabled Code Coverage")
set(CMAKE_BUILD_TYPE Debug)
set(JINJA2CPP_COVERAGE_TARGET "jinja2cpp_build_coverage")
include(coverage)
add_coverage_target("${JINJA2CPP_COVERAGE_TARGET}")
endif ()
if(NOT ${JINJA2CPP_WITH_SANITIZERS} STREQUAL "none")
message (STATUS "Build with sanitizers enabled: ${JINJA2CPP_WITH_SANITIZERS}")
set(_chosen_san)
list(FIND JINJA2CPP_SANITIZERS ${JINJA2CPP_WITH_SANITIZERS} _chosen_san)
if (${_chosen_san} EQUAL -1)
message(FATAL_ERROR "Wrong sanitizer type has been chosen, must be one of ${JINJA2CPP_SANITIZERS}")
endif()
include("sanitizer.${JINJA2CPP_WITH_SANITIZERS}")
set (JINJA2CPP_SANITIZE_TARGET "jinja2cpp_build_sanitizers")
add_sanitizer_target(${JINJA2CPP_SANITIZE_TARGET})
endif()
if (UNIX)
if (JINJA2CPP_PIC OR CONAN_CMAKE_POSITION_INDEPENDENT_CODE)
add_compile_options(-fPIC)
endif ()
if (DEFINED CONAN_SHARED_LINKER_FLAGS)
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} -Wl,${CONAN_SHARED_LINKER_FLAGS})
set(CLANG_CXX_FLAGS ${CLANG_CXX_FLAGS} -Wl,${CONAN_SHARED_LINKER_FLAGS})
endif ()
else ()
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} "-Wa,-mbig-obj" -O1)
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif ()
add_definitions(-DBOOST_ALL_NO_LIB)
set(MSVC_CXX_FLAGS ${MSVC_CXX_FLAGS} /wd4503 /bigobj)
if (CMAKE_BUILD_TYPE MATCHES "Debug" AND JINJA2CPP_MSVC_RUNTIME_TYPE)
set(JINJA2CPP_MSVC_RUNTIME_TYPE "${JINJA2CPP_MSVC_RUNTIME_TYPE}d")
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
if (JINJA2CPP_DEPS_MODE MATCHES "conan-build" OR CMAKE_BUILD_TYPE STREQUAL "")
if (NOT JINJA2CPP_MSVC_RUNTIME_TYPE STREQUAL "")
set(MSVC_RUNTIME_DEBUG ${JINJA2CPP_MSVC_RUNTIME_TYPE})
set(MSVC_RUNTIME_RELEASE ${JINJA2CPP_MSVC_RUNTIME_TYPE})
endif ()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${MSVC_RUNTIME_DEBUG}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${MSVC_RUNTIME_RELEASE}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${MSVC_RUNTIME_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/PROFILE")
set(Boost_USE_DEBUG_RUNTIME OFF)
elseif (CMAKE_BUILD_TYPE MATCHES "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${JINJA2CPP_MSVC_RUNTIME_TYPE}")
set(Boost_USE_DEBUG_RUNTIME ON)
else ()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${JINJA2CPP_MSVC_RUNTIME_TYPE}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${JINJA2CPP_MSVC_RUNTIME_TYPE}")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/PROFILE")
set(Boost_USE_DEBUG_RUNTIME OFF)
endif ()
message(STATUS "Selected MSVC runtime type for Jinja2C++ library: '${JINJA2CPP_MSVC_RUNTIME_TYPE}'")
endif ()
endif()
if (JINJA2CPP_BUILD_SHARED)
set(LIB_LINK_TYPE SHARED)
message(STATUS "Jinja2C++ library type: SHARED")
else()
set(LIB_LINK_TYPE STATIC)
message(STATUS "Jinja2C++ library type: STATIC")
endif()
include(collect_sources)
set (LIB_TARGET_NAME jinja2cpp)
CollectSources(Sources Headers ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
CollectSources(PublicSources PublicHeaders ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(${LIB_TARGET_NAME} ${LIB_LINK_TYPE}
${Sources}
${Headers}
${PublicHeaders}
)
target_sources(${LIB_TARGET_NAME}
PUBLIC FILE_SET HEADERS
FILES ${PublicHeaders}
BASE_DIRS include
)
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_CFG_NAME)
set(CURRENT_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BUILD_CFG_NAME}}")
set(JINJA2CPP_EXTRA_LIBS "" CACHE STRING "You can pass some libs that could used during link stage")
set(JINJA2CPP_PUBLIC_LIBS "${JINJA2CPP_EXTRA_LIBS}")
separate_arguments(JINJA2CPP_PUBLIC_LIBS)
if (JINJA2CPP_WITH_COVERAGE)
target_compile_options(
${JINJA2CPP_COVERAGE_TARGET}
INTERFACE
-g -O0
)
list(APPEND JINJA2CPP_PUBLIC_LIBS ${JINJA2CPP_COVERAGE_TARGET})
endif()
if (NOT JINJA2CPP_WITH_SANITIZERS STREQUAL "none")
target_compile_options(
${JINJA2CPP_SANITIZE_TARGET}
INTERFACE
-g -O2
)
list(APPEND JINJA2CPP_PUBLIC_LIBS ${JINJA2CPP_SANITIZE_TARGET})
endif()
set(JINJA2CPP_PRIVATE_LIBS "${JINJA2CPP_PRIVATE_LIBS}")
include(thirdparty/CMakeLists.txt)
target_link_libraries(
${LIB_TARGET_NAME}
PUBLIC
${JINJA2CPP_PUBLIC_LIBS}
PRIVATE
${JINJA2CPP_PRIVATE_LIBS}
)
target_include_directories(${LIB_TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
if (JINJA2CPP_STRICT_WARNINGS)
if (UNIX)
set(GCC_CXX_FLAGS ${GCC_CXX_FLAGS} -Wall -Werror)
set(CLANG_CXX_FLAGS ${CLANG_CXX_FLAGS} -Wall -Werror -Wno-unused-command-line-argument)
set(MSVC_CXX_FLAGS ${MSVC_CXX_FLAGS} /W4)
endif ()
endif ()
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(${LIB_TARGET_NAME} PRIVATE ${GCC_CXX_FLAGS})
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${LIB_TARGET_NAME} PRIVATE ${CLANG_CXX_FLAGS})
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(${LIB_TARGET_NAME} PRIVATE ${MSVC_CXX_FLAGS})
endif ()
if ("${JINJA2CPP_USE_REGEX}" STREQUAL "boost")
set(_regex_define "-DJINJA2CPP_USE_REGEX_BOOST")
endif()
if ("${JINJA2CPP_WITH_JSON_BINDINGS}" STREQUAL "boost")
set(_bindings_define "-DJINJA2CPP_WITH_JSON_BINDINGS_BOOST")
elseif("${JINJA2CPP_WITH_JSON_BINDINGS}" STREQUAL "rapid")
set(_bindings_define "-DJINJA2CPP_WITH_JSON_BINDINGS_RAPID")
endif()
target_compile_definitions(${LIB_TARGET_NAME}
PUBLIC
-DBOOST_SYSTEM_NO_DEPRECATED
-DBOOST_ERROR_CODE_HEADER_ONLY
-Dnsel_CONFIG_SELECT_EXPECTED=nsel_EXPECTED_NONSTD # C++23 std::expected is not 100% compatible
${_regex_define}
${_bindings_define}
)
if (JINJA2CPP_BUILD_SHARED)
target_compile_definitions(${LIB_TARGET_NAME} PRIVATE -DJINJA2CPP_BUILD_AS_SHARED PUBLIC -DJINJA2CPP_LINK_AS_SHARED)
endif ()
set_target_properties(${LIB_TARGET_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION 1
)
set_target_properties(${LIB_TARGET_NAME} PROPERTIES
CXX_STANDARD ${JINJA2CPP_CXX_STANDARD}
CXX_STANDARD_REQUIRED ON
)
configure_file(jinja2cpp.pc.in ${CMAKE_BINARY_DIR}/jinja2cpp.pc @ONLY)
if (JINJA2CPP_BUILD_TESTS)
enable_testing()
CollectSources(TestSources TestHeaders ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/test)
add_executable(jinja2cpp_tests ${TestSources} ${TestHeaders})
target_link_libraries(jinja2cpp_tests gtest gtest_main
nlohmann_json::nlohmann_json ${LIB_TARGET_NAME} ${EXTRA_TEST_LIBS} ${JINJA2CPP_PRIVATE_LIBS})
set_target_properties(jinja2cpp_tests PROPERTIES
CXX_STANDARD ${JINJA2CPP_CXX_STANDARD}
CXX_STANDARD_REQUIRED ON)
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(jinja2cpp_tests PRIVATE /bigobj)
endif ()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_data/simple_template1.j2tpl
COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/test/test_data ${CMAKE_CURRENT_BINARY_DIR}/test_data
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/test/test_data/simple_template1.j2tpl
COMMENT "Copy test data to the destination dir"
)
add_custom_target(CopyTestData ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/test_data/simple_template1.j2tpl
)
add_dependencies(jinja2cpp_tests CopyTestData)
add_test(NAME jinja2cpp_tests COMMAND jinja2cpp_tests)
endif ()
set (JINJA2CPP_INSTALL_CONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/${LIB_TARGET_NAME}")
set (JINJA2CPP_TMP_CONFIG_PATH "cmake/config")
macro (Jinja2CppGetTargetIncludeDir infix target)
message (STATUS "infix: ${infix} target: ${target}")
if (TARGET ${target})
set (_J2CPP_VAR_NAME JINJA2CPP_${infix}_INCLUDE_DIRECTORIES)
get_target_property(${_J2CPP_VAR_NAME} ${target} INTERFACE_INCLUDE_DIRECTORIES)
else ()
message(WARNING "No target: ${target}")
endif()
endmacro ()
Jinja2CppGetTargetIncludeDir(EXPECTED-LITE nonstd::expected-lite)
Jinja2CppGetTargetIncludeDir(VARIANT-LITE nonstd::variant-lite)
Jinja2CppGetTargetIncludeDir(OPTIONAL-LITE nonstd::optional-lite)
Jinja2CppGetTargetIncludeDir(STRING-VIEW-LITE nonstd::string-view-lite)
# Workaround for #14444 bug of CMake (https://gitlab.kitware.com/cmake/cmake/issues/14444)
# We can't use EXPORT feature of 'install' as is due to limitation of subproject's targets installation
# So jinja2cpp-config.cmake should be written manually
if(JINJA2CPP_INSTALL)
install(
TARGETS
${LIB_TARGET_NAME}
EXPORT
InstallTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/static
FILE_SET HEADERS
)
install(
FILES
${CMAKE_BINARY_DIR}/jinja2cpp.pc
DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
)
install(
EXPORT
InstallTargets
FILE
jinja2cpp-cfg.cmake
DESTINATION
${JINJA2CPP_INSTALL_CONFIG_DIR}
)
configure_package_config_file(
cmake/public/jinja2cpp-config.cmake.in
${JINJA2CPP_TMP_CONFIG_PATH}/jinja2cpp-config.cmake
INSTALL_DESTINATION ${JINJA2CPP_TMP_CONFIG_PATH}
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
configure_package_config_file(
cmake/public/jinja2cpp-config-deps-${JINJA2CPP_DEPS_MODE}.cmake.in
${JINJA2CPP_TMP_CONFIG_PATH}/jinja2cpp-config-deps.cmake
INSTALL_DESTINATION ${JINJA2CPP_TMP_CONFIG_PATH}
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${JINJA2CPP_TMP_CONFIG_PATH}/${LIB_TARGET_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${JINJA2CPP_TMP_CONFIG_PATH}/${LIB_TARGET_NAME}-config-deps.cmake
DESTINATION
${JINJA2CPP_INSTALL_CONFIG_DIR}
)
endif()