-
Notifications
You must be signed in to change notification settings - Fork 21
/
QuickCppLibMakeStandardTests.cmake
219 lines (213 loc) · 9.49 KB
/
QuickCppLibMakeStandardTests.cmake
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
# Adds standard ctest tests for each *.c;*.cpp;*.cxx in
# ${PROJECT_NAME}_TESTS for all ${PROJECT_NAME}_targets
#
# Sets ${PROJECT_NAME}_TEST_TARGETS to the test targets generated
if(NOT ${PROJECT_NAME}_IS_DEPENDENCY AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING))
if(DEFINED ${PROJECT_NAME}_TESTS)
enable_testing()
function(generate_tests)
# Firstly get all non-source files
foreach(testsource ${${PROJECT_NAME}_TESTS})
if(NOT testsource MATCHES ".+/(.+)[.](c|cpp|cxx)$")
list(APPEND testnonsources ${testsource})
endif()
endforeach()
function(do_add_test outtargets testsource special nogroup)
unset(${outtargets} PARENT_SCOPE)
set(target_names)
if(testsource MATCHES ".+/(.+)[.](c|cpp|cxx)$")
# We'll assume the test name is the source file name
set(testname ${CMAKE_MATCH_1})
# Path could however be test/tests/<name>/*.cpp
if(testsource MATCHES ".+/tests/([^/]+)/(.+)[.](c|cpp|cxx)$")
set(testname ${CMAKE_MATCH_1})
endif()
set(thistestsources ${testsource})
foreach(testnonsource ${testnonsources})
if(testnonsource MATCHES ${testname})
list(APPEND thistestsources ${testnonsource})
endif()
endforeach()
foreach(_target ${${PROJECT_NAME}_TARGETS})
set(target ${_target})
if(nogroup)
unset(group)
elseif(target MATCHES "_hl$")
set(group _hl)
elseif(target MATCHES "_sl$")
set(group _sl)
elseif(target MATCHES "_dl$")
set(group _dl)
else()
unset(group)
endif()
if(special STREQUAL "")
set(target_name "${target}--${testname}")
else()
set(group ${group}-${special})
set(target_name "${target}-${special}-${testname}")
if(NOT target MATCHES "_hl$")
set(target "${target}-${special}")
endif()
endif()
add_executable(${target_name} ${thistestsources})
set(target_in_disable_list ${PROJECT_NAME}_INTERFACE_DISABLED)
foreach(item ${${PROJECT_NAME}_TESTS_DISABLE_PRECOMPILE_HEADERS})
if(target_name MATCHES ${item})
set(target_in_disable_list 1)
break()
endif()
endforeach()
if(target_in_disable_list)
set_target_properties(${target_name} PROPERTIES DISABLE_PRECOMPILE_HEADERS On)
else()
if(NOT first_test_target${group})
set(first_test_target${group} ${target_name} PARENT_SCOPE)
elseif(COMMAND target_precompile_headers)
#message("*** target_precompile_headers(${target_name} REUSE_FROM ${first_test_target${group}})")
target_precompile_headers(${target_name} REUSE_FROM ${first_test_target${group}})
endif()
endif()
set_target_properties(${target_name} PROPERTIES
EXCLUDE_FROM_ALL ON
)
if(DEFINED group)
add_dependencies(${group} ${target_name})
endif()
target_link_libraries(${target_name} PRIVATE ${target})
set_target_properties(${target_name} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
POSITION_INDEPENDENT_CODE ON
)
if(WIN32)
target_compile_definitions(${target_name} PRIVATE _CRT_NONSTDC_NO_WARNINGS) # Shut up about using POSIX functions
endif()
if(MSVC)
target_compile_options(${target_name} PRIVATE /W4) # Stronger warnings
else()
target_compile_options(${target_name} PRIVATE -Wall -Wextra) # Stronger warnings
endif()
list(APPEND target_names "${target_name}")
endforeach()
if(target_names)
set(${outtargets} "${target_names}" PARENT_SCOPE)
endif()
endif()
endfunction()
# Deal with normal tests + special builds of them first
set(testtargets)
foreach(special ${SPECIAL_BUILDS} "")
set(first_test_target_hl)
set(first_test_target_sl)
set(first_test_target_dl)
foreach(testsource ${${PROJECT_NAME}_TESTS})
do_add_test(target_names "${testsource}" "${special}" OFF)
foreach(target_name ${target_names})
# This is a normal test target run for success
list(APPEND testtargets "${target_name}")
if(special STREQUAL "")
# Output test detail to JUnit XML
add_test(NAME ${target_name} CONFIGURATIONS Debug Release RelWithDebInfo MinSizeRel
COMMAND $<TARGET_FILE:${target_name}> --reporter junit --out $<TARGET_FILE:${target_name}>.junit.xml
)
else()
add_test(NAME ${target_name} COMMAND $<TARGET_FILE:${target_name}> CONFIGURATIONS ${special})
if(DEFINED ${special}_LINK_FLAGS)
_target_link_options(${target_name} PRIVATE ${${special}_LINK_FLAGS})
endif()
target_compile_options(${target_name} PRIVATE ${${special}_COMPILE_FLAGS})
string(REGEX MATCH "_(hl|sl|dl)-" out ${target_name})
list(APPEND ${PROJECT_NAME}_${CMAKE_MATCH_1}_${special}_TARGETS ${target_name})
endif()
endforeach()
endforeach()
endforeach()
set(${PROJECT_NAME}_TEST_TARGETS ${testtargets} PARENT_SCOPE)
foreach(special ${SPECIAL_BUILDS})
if(DEFINED ${PROJECT_NAME}_hl_${special}_TARGETS)
set(${PROJECT_NAME}_hl_${special}_TARGETS ${${PROJECT_NAME}_hl_${special}_TARGETS} PARENT_SCOPE)
endif()
if(DEFINED ${PROJECT_NAME}_sl_${special}_TARGETS)
set(${PROJECT_NAME}_sl_${special}_TARGETS ${${PROJECT_NAME}_sl_${special}_TARGETS} PARENT_SCOPE)
endif()
if(DEFINED ${PROJECT_NAME}_dl_${special}_TARGETS)
set(${PROJECT_NAME}_dl_${special}_TARGETS ${${PROJECT_NAME}_dl_${special}_TARGETS} PARENT_SCOPE)
endif()
endforeach()
# Deal with tests which require the compilation to succeed
set(testtargets)
set(first_test_target_hl)
set(first_test_target_sl)
set(first_test_target_dl)
foreach(testsource ${${PROJECT_NAME}_COMPILE_TESTS})
do_add_test(target_names "${testsource}" "" OFF)
list(APPEND testtargets ${target_names})
endforeach()
set(${PROJECT_NAME}_COMPILE_TEST_TARGETS ${testtargets} PARENT_SCOPE)
# Deal with tests which require the compilation to fail in an exact way
set(testtargets)
set(first_test_target_hl)
set(first_test_target_sl)
set(first_test_target_dl)
foreach(testsource ${${PROJECT_NAME}_COMPILE_FAIL_TESTS})
do_add_test(target_names "${testsource}" "" ON)
foreach(target_name ${target_names})
list(APPEND testtargets "${target_name}")
# Do not build these normally, only on request
set_target_properties(${target_name} PROPERTIES
EXCLUDE_FROM_ALL ON
EXCLUDE_FROM_DEFAULT_BUILD ON
CXX_CLANG_TIDY ""
)
# This test tries to build this test expecting failure
add_test(NAME ${target_name}
COMMAND ${CMAKE_COMMAND} --build . --target ${target_name} --config $<CONFIGURATION>
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
)
# Fetch the regex to detect correct failure
file(STRINGS "${testsource}" firstline LIMIT_COUNT 2)
list(GET firstline 1 firstline)
set_tests_properties(${target_name} PROPERTIES PASS_REGULAR_EXPRESSION "${firstline}")
endforeach()
endforeach()
set(${PROJECT_NAME}_COMPILE_FAIL_TARGETS ${testtargets} PARENT_SCOPE)
endfunction()
generate_tests()
endif()
# # For all special builds, create custom "all" target for each of those so one can build "everything with asan" etc
# foreach(special ${SPECIAL_BUILDS})
# if(DEFINED ${PROJECT_NAME}_hl_${special}_TARGETS)
# indented_message(STATUS "Creating non-default all target for special build ${PROJECT_NAME}_hl-${special}")
# indented_message(STATUS "*** ${${PROJECT_NAME}_hl_${special}_TARGETS}")
# add_custom_target(${PROJECT_NAME}_hl-${special} DEPENDS ${${PROJECT_NAME}_hl_${special}_TARGETS})
# endif()
# endforeach()
# We need to now decide on some default build target group. Prefer static libraries
# unless this is a header only library
set(dont_run_tests)
if(TARGET ${PROJECT_NAME}_sl)
set_target_properties(_sl PROPERTIES EXCLUDE_FROM_ALL OFF)
set(dont_run_tests "_(hl|dl)-")
else()
set_target_properties(_hl PROPERTIES EXCLUDE_FROM_ALL OFF)
set(dont_run_tests "_(sl|dl)-")
endif()
if(UNIT_TESTS_BUILD_ALL)
if(TARGET ${PROJECT_NAME}_hl)
set_target_properties(_hl PROPERTIES EXCLUDE_FROM_ALL OFF)
endif()
if(TARGET ${PROJECT_NAME}_sl)
set_target_properties(_sl PROPERTIES EXCLUDE_FROM_ALL OFF)
endif()
if(TARGET ${PROJECT_NAME}_dl)
set_target_properties(_dl PROPERTIES EXCLUDE_FROM_ALL OFF)
endif()
else()
# Don't run the tests which are not built by all
foreach(target ${${PROJECT_NAME}_TEST_TARGETS})
if(target MATCHES "${dont_run_tests}")
set_tests_properties(${target} PROPERTIES DISABLED ON)
endif()
endforeach()
endif()
endif()