Skip to content

Commit 8104bf7

Browse files
authored
Make common CMake targets more modular (#53)
2 parents 7f3a1c8 + edf1f75 commit 8104bf7

4 files changed

Lines changed: 126 additions & 91 deletions

File tree

CMakeLists.txt

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ set_property(GLOBAL PROPERTY IRIS_ROOT "${IRIS_ROOT}")
2020
set(CMAKE_COLOR_DIAGNOSTICS ON)
2121
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
2222

23+
if(NOT DEFINED CMAKE_CXX_EXTENSIONS)
24+
set(CMAKE_CXX_EXTENSIONS OFF)
25+
endif()
26+
2327
option(IRIS_REMOVE_MINSIZEREL_CONFIG "Remove rarely used MinSizeRel config" ON)
2428

2529
if(MSVC)
@@ -36,9 +40,52 @@ endif()
3640
# -----------------------------------------------------------------
3741
# Create common base targets
3842

39-
# Iris-specific common target
40-
add_library(_iris_cxx_common INTERFACE)
41-
set_target_properties(_iris_cxx_common PROPERTIES CXX_EXTENSIONS OFF)
43+
# ABI compatibility target
44+
add_library(iris_cxx_abi INTERFACE)
45+
set_target_properties(iris_cxx_abi PROPERTIES CXX_EXTENSIONS OFF)
46+
47+
# In contrast to the flags defined in `iris_cxx_abi`, certain
48+
# miscellaneous flags aren't strictly required for ABI compatibility.
49+
#
50+
# However, we're going to merge them into `Iris::Iris` anyway, because
51+
# the whole point of using Iris is to simplify C++ build system and use
52+
# common flags everywhere; enforcing best-practices is our goal.
53+
add_library(_iris_cxx_best_practices INTERFACE)
54+
set_target_properties(_iris_cxx_best_practices PROPERTIES CXX_EXTENSIONS OFF)
55+
56+
# ASan/UBSan
57+
add_library(iris_cxx_sanitizer INTERFACE)
58+
set_target_properties(iris_cxx_sanitizer PROPERTIES CXX_EXTENSIONS OFF)
59+
target_link_libraries(iris_cxx_sanitizer INTERFACE iris_cxx_abi)
60+
61+
if(MSVC)
62+
# TODO: use $<$<CONFIG:Debug,RelWithDebInfo>:......>
63+
64+
target_compile_options(
65+
iris_cxx_sanitizer
66+
INTERFACE
67+
/wd5072 # ASan intentionally enabled on Release build
68+
/fsanitize=address
69+
)
70+
target_link_options(
71+
iris_cxx_sanitizer
72+
INTERFACE
73+
/ignore:4302 # ASan intentionally enabled on Release build
74+
/INCREMENTAL:NO # required for ASan
75+
)
76+
77+
else() # non-MSVC
78+
target_compile_options(
79+
iris_cxx_sanitizer
80+
INTERFACE
81+
-fsanitize=undefined,address
82+
)
83+
target_link_options(
84+
iris_cxx_sanitizer
85+
INTERFACE
86+
-fsanitize=undefined,address
87+
)
88+
endif()
4289

4390

4491
# -----------------------------------------------------------------
@@ -56,11 +103,11 @@ if(MSVC)
56103
"${CMAKE_CURRENT_LIST_DIR}/iris.natvis"
57104
)
58105

59-
target_link_libraries(iris PUBLIC _iris_cxx_common)
106+
target_link_libraries(iris PUBLIC iris_cxx_abi _iris_cxx_best_practices)
60107

61108
else()
62109
add_library(iris INTERFACE)
63-
target_link_libraries(iris INTERFACE _iris_cxx_common)
110+
target_link_libraries(iris INTERFACE iris_cxx_abi _iris_cxx_best_practices)
64111
endif()
65112

66113
add_library(Iris::Iris ALIAS iris)
@@ -88,21 +135,21 @@ if(MSVC)
88135
set(CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_STANDARD_COMPILE_OPTION ${CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_STANDARD_COMPILE_OPTION} PARENT_SCOPE)
89136
set(CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_EXTENSION_COMPILE_OPTION ${CMAKE_CXX${IRIS_CXX_VERSION_BEFORE_LATEST}_EXTENSION_COMPILE_OPTION} PARENT_SCOPE)
90137

91-
target_compile_options(_iris_cxx_common INTERFACE /std:c++${IRIS_CXX_VERSION_BEFORE_LATEST}preview)
138+
target_compile_options(iris_cxx_abi INTERFACE /std:c++${IRIS_CXX_VERSION_BEFORE_LATEST}preview)
92139

93140
else()
94141
# MSVC's CMake support does not provide the latest `cxx_std_XX`
95142
# feature until the very last stage of the implementation. Instead,
96143
# the feature number that is one version behind the latest usually
97144
# resolves to `/std:c++latest`.
98-
target_compile_features(_iris_cxx_common INTERFACE cxx_std_${IRIS_CXX_VERSION_BEFORE_LATEST})
145+
target_compile_features(iris_cxx_abi INTERFACE cxx_std_${IRIS_CXX_VERSION_BEFORE_LATEST})
99146
endif()
100147

101148
else() # Non-MSVC
102149
if(DEFINED CMAKE_CXX_STANDARD)
103-
target_compile_features(_iris_cxx_common INTERFACE cxx_std_${CMAKE_CXX_STANDARD})
150+
target_compile_features(iris_cxx_abi INTERFACE cxx_std_${CMAKE_CXX_STANDARD})
104151
else()
105-
target_compile_features(_iris_cxx_common INTERFACE cxx_std_${IRIS_CXX_VERSION_LATEST})
152+
target_compile_features(iris_cxx_abi INTERFACE cxx_std_${IRIS_CXX_VERSION_LATEST})
106153
endif()
107154
endif()
108155

@@ -115,47 +162,45 @@ unset(IRIS_CXX_FEATURE_BEFORE_LATEST)
115162

116163
if(WIN32)
117164
target_compile_definitions(
118-
_iris_cxx_common
165+
iris_cxx_abi
119166
INTERFACE NOMINMAX WIN32_LEAN_AND_MEAN
120167
)
121168
endif()
122169

123170
if(MSVC)
124-
# Don't set too strict flags for testing! They must go to `iris_cxx_test`.
125-
# ABI-dependent configurations MUST be set here.
171+
# Some flags affect ABI-compatibility, which means they are mandatory
172+
# for any kind of downstream applications.
173+
126174
target_compile_definitions(
127-
_iris_cxx_common
175+
iris_cxx_abi
128176
INTERFACE UNICODE _UNICODE
129177
)
130178
target_compile_options(
131-
_iris_cxx_common
179+
iris_cxx_abi
132180
INTERFACE
133181
/EHsc /MP /utf-8 /Zc:__cplusplus /Zc:preprocessor /permissive-
134-
# $<$<CONFIG:Debug,RelWithDebInfo>:/fsanitize=address> # TODO
135182
)
136-
target_link_options(
137-
_iris_cxx_common
183+
184+
target_compile_options(
185+
_iris_cxx_best_practices
138186
INTERFACE
139-
# $<$<CONFIG:Debug,RelWithDebInfo>:/INCREMENTAL:NO> # TODO
187+
/W4 /analyze /analyze:external-
140188
)
189+
141190
else()
142191
if(CMAKE_CXX_COMPILER_ID MATCHES Clang)
143192
target_compile_options(
144-
_iris_cxx_common
193+
iris_cxx_abi
145194
INTERFACE
146195
-fno-builtin-std-forward_like
147196
-Wno-c++26-extensions # workaround for warnings emitted when using pack indexing
148197
)
149198
endif()
199+
150200
target_compile_options(
151-
_iris_cxx_common
152-
INTERFACE
153-
# $<$<CONFIG:Debug>:-fsanitize=undefined,address> # TODO
154-
)
155-
target_link_options(
156-
_iris_cxx_common
201+
_iris_cxx_best_practices
157202
INTERFACE
158-
# $<$<CONFIG:Debug>:-fsanitize=undefined,address> # TODO
203+
-Wall -Wextra -pedantic
159204
)
160205
endif()
161206

test/CMakeLists.txt

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,63 +3,33 @@
33
# -----------------------------------------------------------------
44
# Setup the basic targets
55

6-
# For internal common settings
7-
add_library(_iris_cxx_test_common INTERFACE)
8-
set_target_properties(_iris_cxx_test_common PROPERTIES CXX_EXTENSIONS OFF)
9-
target_link_libraries(_iris_cxx_test_common INTERFACE _iris_cxx_common)
106

7+
# For internal common settings
118

129
# For Iris-specific tests
1310
add_library(iris_cxx_test INTERFACE)
1411
set_target_properties(iris_cxx_test PROPERTIES CXX_EXTENSIONS OFF)
15-
target_link_libraries(iris_cxx_test INTERFACE _iris_cxx_test_common)
12+
target_link_libraries(iris_cxx_test INTERFACE iris_cxx_abi)
1613

1714
# For external libraries. Excludes strict warning, etc.
1815
add_library(iris_cxx_test_external INTERFACE)
1916
set_target_properties(iris_cxx_test_external PROPERTIES CXX_EXTENSIONS OFF)
20-
target_link_libraries(iris_cxx_test_external INTERFACE _iris_cxx_test_common)
17+
target_link_libraries(iris_cxx_test_external INTERFACE iris_cxx_abi)
2118

2219
if(MSVC)
23-
target_compile_options(
24-
_iris_cxx_test_common
25-
INTERFACE
26-
/wd5072 # ASan intentionally enabled on Release build
27-
/fsanitize=address
28-
)
29-
target_link_options(
30-
_iris_cxx_test_common
31-
INTERFACE
32-
/ignore:4302 # ASan intentionally enabled on Release build
33-
/INCREMENTAL:NO # required for ASan
34-
)
35-
36-
target_compile_options(
37-
iris_cxx_test
38-
INTERFACE /W4 /analyze /analyze:external-
39-
)
40-
4120
target_compile_options(
4221
iris_cxx_test_external
4322
INTERFACE /analyze-
4423
)
24+
endif()
4525

46-
else() # non-MSVC
47-
target_compile_options(
48-
_iris_cxx_test_common
49-
INTERFACE
50-
-fsanitize=undefined,address
51-
)
52-
target_link_options(
53-
_iris_cxx_test_common
54-
INTERFACE
55-
-fsanitize=undefined,address
56-
)
57-
58-
target_compile_options(
59-
iris_cxx_test
60-
INTERFACE
61-
-Wall -Wextra -pedantic
62-
)
26+
#
27+
# TODO: separate sanitizer and non-sanitizer versions
28+
#
29+
option(IRIS_TEST_USE_SANITIZER "Enable ASan/UBSan" ON)
30+
if(${IRIS_TEST_USE_SANITIZER})
31+
target_link_libraries(iris_cxx_test INTERFACE iris_cxx_sanitizer)
32+
target_link_libraries(iris_cxx_test_external INTERFACE iris_cxx_sanitizer)
6333
endif()
6434

6535

@@ -84,11 +54,33 @@ set_target_properties(Catch2 PROPERTIES CXX_EXTENSIONS OFF)
8454
set_target_properties(Catch2 Catch2WithMain PROPERTIES FOLDER "_deps")
8555

8656
target_compile_definitions(Catch2 PUBLIC DO_NOT_USE_WMAIN)
57+
58+
if(MSVC)
59+
target_compile_options(Catch2 PRIVATE /wd6054)
60+
endif()
61+
8762
target_link_libraries(Catch2 PRIVATE iris_cxx_test_external)
8863
target_link_libraries(Catch2WithMain PRIVATE iris_cxx_test_external)
8964

9065
target_link_libraries(iris_cxx_test INTERFACE Catch2::Catch2)
9166

67+
68+
# -----------------------------------------------------------------
69+
# Iris internal test targets
70+
71+
add_library(_iris_internal_test INTERFACE)
72+
target_include_directories(_iris_internal_test INTERFACE ${CMAKE_CURRENT_LIST_DIR})
73+
74+
if(MSVC)
75+
target_sources(_iris_internal_test INTERFACE "${CMAKE_CURRENT_LIST_DIR}/cpp.hint")
76+
endif()
77+
78+
function(iris_define_internal_test test_name)
79+
iris_define_test(${test_name} ${ARGN})
80+
target_link_libraries(${test_name}_test PRIVATE _iris_internal_test)
81+
endfunction()
82+
83+
9284
# -----------------------------------------------------------------
9385
# Common CMake utilities for testing
9486

@@ -102,9 +94,8 @@ function(_iris_define_test_impl test_name libs)
10294
message(FATAL_ERROR "IRIS_ROOT is not defined")
10395
endif()
10496

105-
add_executable(${test_name}_test ${ARGN})
106-
target_include_directories(${test_name}_test PRIVATE ${CMAKE_CURRENT_FUNCTION_LIST_DIR})
10797
target_include_directories(${test_name}_test PRIVATE ${CMAKE_CURRENT_LIST_DIR})
98+
target_link_libraries(${test_name}_test PRIVATE Iris::Iris iris_cxx_test ${libs})
10899
set_target_properties(${test_name}_test PROPERTIES CXX_EXTENSIONS OFF)
109100

110101
if(MSVC)
@@ -114,12 +105,8 @@ function(_iris_define_test_impl test_name libs)
114105
TARGET_DIRECTORY ${test_name}_test
115106
PROPERTIES VS_SETTINGS "ExcludedFromBuild=true"
116107
)
117-
118-
target_sources(${test_name}_test PRIVATE "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/cpp.hint")
119108
endif()
120109

121-
target_link_libraries(${test_name}_test PRIVATE Iris::Iris iris_cxx_test ${libs})
122-
add_test(NAME ${test_name}_test COMMAND ${test_name}_test --colour-mode=ansi)
123110

124111
set_tests_properties(
125112
${test_name}_test PROPERTIES
@@ -151,25 +138,28 @@ function(_iris_define_test_impl test_name libs)
151138
endif()
152139
endfunction()
153140

154-
function(iris_define_test test_name)
155-
_iris_define_test_impl(${test_name} Catch2::Catch2WithMain ${ARGN})
141+
function(_iris_define_executable_test test_name libs)
142+
add_executable(${test_name}_test ${ARGN})
143+
add_test(NAME ${test_name}_test COMMAND ${test_name}_test --colour-mode=ansi)
144+
_iris_define_test_impl(${test_name} ${libs})
156145
endfunction()
157146

158-
function(iris_define_test_no_main test_name)
159-
_iris_define_test_impl(${test_name} "" ${ARGN})
147+
148+
# -----------------------------------------------------------------
149+
# Public test adder functions
150+
151+
function(iris_define_test test_name)
152+
_iris_define_executable_test(${test_name} Catch2::Catch2WithMain ${ARGN})
160153
endfunction()
161154

162-
function(iris_define_tests)
163-
foreach(test_name IN LISTS ARGV)
164-
iris_define_test(${test_name} ${test_name}.cpp)
165-
endforeach()
155+
function(iris_define_test_no_main test_name)
156+
_iris_define_executable_test(${test_name} Catch2::Catch2 ${ARGN})
166157
endfunction()
167158

168-
function(iris_define_sub_tests prefix)
169-
foreach(test_name IN LISTS ARGN)
170-
iris_define_test(${prefix}_${test_name} ${test_name}.cpp)
171-
set_target_properties(${prefix}_${test_name}_test PROPERTIES FOLDER "test/${prefix}")
172-
endforeach()
159+
function(iris_define_library_test library_type test_name srcs)
160+
add_library(${test_name}_test ${library_type} ${srcs})
161+
add_test(NAME ${test_name}_test COMMAND ${ARGN})
162+
_iris_define_test_impl(${test_name} Catch2::Catch2)
173163
endfunction()
174164

175165

@@ -190,10 +180,10 @@ if(PROJECT_IS_TOP_LEVEL)
190180
preprocess
191181
)
192182

193-
iris_define_sub_tests(iris ${IRIS_TEST_IRIS_TESTS})
194-
195183
foreach(test_name IN LISTS IRIS_TEST_IRIS_TESTS)
184+
iris_define_internal_test(iris_${test_name} ${test_name}.cpp)
196185
iris_define_test_headers(iris_${test_name} iris_test.hpp)
186+
set_target_properties(iris_${test_name}_test PROPERTIES FOLDER "test/iris")
197187
endforeach()
198188

199189
add_subdirectory(unicode)

test/rvariant/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ if(IRIS_CI)
1414
list(APPEND IRIS_TEST_RVARIANT_TESTS many_alternatives_32)
1515
endif()
1616

17-
iris_define_sub_tests(rvariant ${IRIS_TEST_RVARIANT_TESTS})
18-
1917
foreach(test_name IN LISTS IRIS_TEST_RVARIANT_TESTS)
18+
iris_define_internal_test(rvariant_${test_name} ${test_name}.cpp)
2019
iris_define_test_headers(rvariant_${test_name} iris_rvariant_test.hpp)
20+
set_target_properties(rvariant_${test_name}_test PROPERTIES FOLDER "test/rvariant")
2121
endforeach()

test/unicode/string/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ set(
77
)
88

99
foreach(test_name IN LISTS IRIS_TEST_UNICODE_STRING_TESTS)
10-
iris_define_test(unicode_string_${test_name} ${test_name}.cpp)
10+
iris_define_internal_test(unicode_string_${test_name} ${test_name}.cpp)
1111
set_target_properties(unicode_string_${test_name}_test PROPERTIES FOLDER "test/unicode/string")
1212
endforeach()
1313

0 commit comments

Comments
 (0)