-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathCompileFlags.cmake
More file actions
388 lines (340 loc) · 16.1 KB
/
CompileFlags.cmake
File metadata and controls
388 lines (340 loc) · 16.1 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
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
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
#
# Copyright 2021 Huawei Technologies Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Generic compilation flags
#
# Compilation flags are ALWAYS passed to consuming targets (backends, tests)
# VIA THE TARGETS HERE DEFINED and never via strings, to minimize the amount of
# information and dependencies between CMake files; strings defined here follow
# certain patterns and are to be used ONLY HERE
#
# Flags for specific dependencies (e.g., NUMA or OpenMP) are not handled here,
# but in the corresponding include and library targets where they are actually
# used (usually in include/CMakeLists.txt, since ALP/GraphBLAS is template-based)
#
assert_valid_variables( TEST_CATEGORIES )
assert_defined_variables(
COMMON_COMPILE_DEFINITIONS COMMON_COMPILE_OPTIONS
WITH_NUMA ADDITIONAL_BACKEND_DEFINITIONS ADDITIONAL_BACKEND_OPTIONS
ADDITIONAL_TEST_DEFINITIONS ADDITIONAL_TEST_OPTIONS
TEST_PERFORMANCE_DEFINITIONS TEST_PERFORMANCE_OPTIONS
)
# allow only Relase, Debug and Coverage
set( CMAKE_CONFIGURATION_TYPES "Release;Debug;Coverage" CACHE STRING
"Add the configurations that we need" FORCE
)
### COMMMON COMPILATION FLAGS
if( NOT CMAKE_BUILD_TYPE )
# if no build type, set Release
set( CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE )
else()
if( CMAKE_BUILD_TYPE AND( NOT CMAKE_BUILD_TYPE IN_LIST CMAKE_CONFIGURATION_TYPES ) )
message( SEND_ERROR "Built type \"${CMAKE_BUILD_TYPE}\" unrecognized" )
message( FATAL_ERROR "CMAKE_BUILD_TYPE must be one of: \"${CMAKE_CONFIGURATION_TYPES}\"" )
endif()
# clear CMake defaults
foreach( bt ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${bt} btu )
set( CMAKE_CXX_FLAGS_${btu} "" CACHE STRING "${CMAKE_BUILD_TYPE} CXX compilation flags" FORCE )
set( CMAKE_C_FLAGS_${btu} "" CACHE STRING "${CMAKE_BUILD_TYPE} C compilation flags" FORCE )
endforeach()
endif()
set( COMMON_OPTS "-g" "-Wall" "-Wextra" )
# cache variable to allow manual tweaks from CMake cache
set_valid_string( COMMON_DEFS_Release "${COMMON_COMPILE_DEFINITIONS}" "" )
set_valid_string( COMMON_DEFS_Debug "${COMMON_COMPILE_DEFINITIONS}" "" )
set_valid_string( COMMON_DEFS_Coverage "${COMMON_COMPILE_DEFINITIONS}" "" )
set_valid_string( COMMON_OPTS_Release "${COMMON_COMPILE_OPTIONS}"
"${COMMON_OPTS}"
)
set_valid_string( COMMON_OPTS_Debug "${COMMON_COMPILE_OPTIONS}"
"${COMMON_OPTS};-fno-omit-frame-pointer"
)
set_valid_string( COMMON_OPTS_Coverage "${COMMON_COMPILE_OPTIONS}"
"${COMMON_OPTS};-fprofile-arcs;-ftest-coverage;-fprofile-update=atomic"
)
add_library( common_flags INTERFACE )
target_compile_definitions( common_flags INTERFACE
"$<$<CONFIG:Release>:${COMMON_DEFS_Release}>"
"$<$<CONFIG:Debug>:${COMMON_DEFS_Debug}>"
"$<$<CONFIG:Coverage>:${COMMON_DEFS_Coverage}>"
)
target_compile_options( common_flags INTERFACE
"$<$<CONFIG:Release>:${COMMON_OPTS_Release}>"
"$<$<CONFIG:Debug>:${COMMON_OPTS_Debug}>"
"$<$<CONFIG:Coverage>:${COMMON_OPTS_Coverage}>"
)
target_link_libraries( common_flags INTERFACE
"$<$<CONFIG:Coverage>:GCov::GCov>"
)
## defaults performance options for all targets (backends and tests)
set( COMMON_PERF_DEFS_Release "NDEBUG" )
set( COMMON_PERF_OPTS_Release "-O3" "-march=native" "-mtune=native" "-funroll-loops" )
set( COMMON_PERF_DEFS_Debug "" )
set( COMMON_PERF_OPTS_Debug "-O0" )
set( COMMON_PERF_DEFS_Coverage "" )
set( COMMON_PERF_OPTS_Coverage "-O1" "-fno-inline" "-fno-inline-small-functions" "-fno-default-inline" )
### COMPILATION FLAGS FOR BACKENDS
append_if_valid( _BACKEND_DEFS_Release "${COMMON_PERF_DEFS_Release}" "${ADDITIONAL_BACKEND_DEFINITIONS}" )
append_if_valid( _BACKEND_DEFS_Debug "${COMMON_PERF_DEFS_Debug}" "${ADDITIONAL_BACKEND_DEFINITIONS}" )
append_if_valid( _BACKEND_DEFS_Coverage "${COMMON_PERF_DEFS_Coverage}" "${ADDITIONAL_BACKEND_DEFINITIONS}" )
append_if_valid( _BACKEND_OPTS_Release "${COMMON_PERF_OPTS_Release}" "${ADDITIONAL_BACKEND_OPTIONS}" )
append_if_valid( _BACKEND_OPTS_Debug "${COMMON_PERF_OPTS_Debug}" "${ADDITIONAL_BACKEND_OPTIONS}" )
append_if_valid( _BACKEND_OPTS_Coverage "${COMMON_PERF_OPTS_Coverage}" "${ADDITIONAL_BACKEND_OPTIONS}" )
# cache variable to allow manual tweaks from CMake cache
set( BACKEND_DEFS_Release "${_BACKEND_DEFS_Release}" CACHE STRING "backend Release definitions" )
set( BACKEND_DEFS_Debug "${_BACKEND_DEFS_Debug}" CACHE STRING "backend Debug definitions" )
set( BACKEND_DEFS_Coverage "${_BACKEND_DEFS_Coverage}" CACHE STRING "backend Coverage definitions" )
set( BACKEND_OPTS_Release "${_BACKEND_OPTS_Release}" CACHE STRING "backend Release options" )
set( BACKEND_OPTS_Debug "${_BACKEND_OPTS_Debug}" CACHE STRING "backend Debug options" )
set( BACKEND_OPTS_Coverage "${_BACKEND_OPTS_Coverage}" CACHE STRING "backend Coverage options" )
add_library( backend_flags INTERFACE )
target_compile_definitions( backend_flags INTERFACE
"$<$<CONFIG:Release>:${BACKEND_DEFS_Release}>"
"$<$<CONFIG:Debug>:${BACKEND_DEFS_Debug}>"
"$<$<CONFIG:Coverage>:${BACKEND_DEFS_Coverage}>"
)
target_compile_options( backend_flags INTERFACE
"$<$<CONFIG:Release>:${BACKEND_OPTS_Release}>"
"$<$<CONFIG:Debug>:${BACKEND_OPTS_Debug}>"
"$<$<CONFIG:Coverage>:${BACKEND_OPTS_Coverage}>"
)
target_link_libraries( backend_flags INTERFACE common_flags )
if( CMAKE_BUILD_TYPE STREQUAL Coverage )
get_target_property( COMMON_OPTS_EXTRA GCov::GCov INTERFACE_COMPILE_OPTIONS )
get_target_property( COMMON_DEFS_EXTRA GCov::GCov INTERFACE_COMPILE_DEFINITIONS )
endif()
install( TARGETS common_flags backend_flags
EXPORT GraphBLASTargets
)
### COMPILATION FLAGS FOR TESTS
# pattern for variables ({} for mandatory choice, [] for optional parts):
# TEST_{DEFAULT,category[_mode]}[_PERF]_{DEFS,OPTS}_{<build type>}
# corresponding pattern for targets:
# test_{default,category[_mode]}[_perf]_flags
set_valid_string( TEST_DEFAULT_DEFS_Release "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_DEFAULT_DEFS_Debug "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_DEFAULT_DEFS_Coverage "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_DEFAULT_OPTS_Release "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_DEFAULT_OPTS_Debug "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_DEFAULT_OPTS_Coverage "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_DEFAULT_PERF_DEFS_Release "${TEST_PERFORMANCE_DEFINITIONS}"
"${COMMON_PERF_DEFS_Release}"
)
set_valid_string( TEST_DEFAULT_PERF_DEFS_Debug "${TEST_PERFORMANCE_DEFINITIONS}"
"${COMMON_PERF_DEFS_Debug}"
)
set_valid_string( TEST_DEFAULT_PERF_DEFS_Coverage "${TEST_PERFORMANCE_DEFINITIONS}"
"${COMMON_PERF_DEFS_Coverage}"
)
set_valid_string( TEST_DEFAULT_PERF_OPTS_Release "${TEST_PERFORMANCE_OPTIONS}"
"${COMMON_PERF_OPTS_Release}"
)
set_valid_string( TEST_DEFAULT_PERF_OPTS_Debug "${TEST_PERFORMANCE_OPTIONS}"
"${COMMON_PERF_OPTS_Debug}"
)
set_valid_string( TEST_DEFAULT_PERF_OPTS_Coverage "${TEST_PERFORMANCE_OPTIONS}"
"${COMMON_PERF_OPTS_Coverage}"
)
add_library( test_default_flags INTERFACE )
target_link_libraries( test_default_flags INTERFACE common_flags )
target_compile_definitions( test_default_flags INTERFACE
"$<$<CONFIG:Release>:${TEST_DEFAULT_DEFS_Release}>"
"$<$<CONFIG:Debug>:${TEST_DEFAULT_DEFS_Debug}>"
"$<$<CONFIG:Coverage>:${TEST_DEFAULT_DEFS_Coverage}>"
"$<$<CONFIG:Release>:${TEST_DEFAULT_PERF_DEFS_Release}>"
"$<$<CONFIG:Debug>:${TEST_DEFAULT_PERF_DEFS_Debug}>"
"$<$<CONFIG:Coverage>:${TEST_DEFAULT_PERF_DEFS_Coverage}>"
)
target_compile_options( test_default_flags INTERFACE
"$<$<CONFIG:Release>:${TEST_DEFAULT_OPTS_Release}>"
"$<$<CONFIG:Debug>:${TEST_DEFAULT_OPTS_Debug}>"
"$<$<CONFIG:Coverage>:${TEST_DEFAULT_OPTS_Coverage}>"
"$<$<CONFIG:Release>:${TEST_DEFAULT_PERF_OPTS_Release}>"
"$<$<CONFIG:Debug>:${TEST_DEFAULT_PERF_OPTS_Debug}>"
"$<$<CONFIG:Coverage>:${TEST_DEFAULT_PERF_OPTS_Coverage}>"
)
# list of categories with default test settings: at the beginning, all of them
set( default_categories "${TEST_CATEGORIES}" )
# settings about modes are passed to tests via the MODES_* variables
#
# MODES_{category}
# MODES_{category}[_<mode name>]_suffix
#
# that MUST be defined for each category. The former stores the list of modes for
# the given test category, while the second the file suffix (with also _, or empty)
# to be appendedn to each test's target and file name
# macro to assemble custom projects for a given category and optional mode
# it is based on the above conditions to populate the flags, hence the corresponding
# strings (tests and performance) MUST BE DEFINED according to the conditions above
macro( add_category_flags category )
if( NOT "${category}" IN_LIST TEST_CATEGORIES )
message( FATAL_ERROR "category \"${category}\" not among: ${TEST_CATEGORIES}" )
endif()
set(oneValueArgs "MODE" )
cmake_parse_arguments( parsed "${options}"
"${oneValueArgs}" "${multiValueArgs}" "${ARGN}"
)
set( __prefix "${category}" )
if( parsed_MODE )
string( APPEND __prefix "_" "${parsed_MODE}" )
if( "${__prefix}" IN_LIST MODES_${category} )
message( FATAL_ERROR
"mode \"${__prefix}\" already specified in MODES_${category}: ${MODES_${category}}"
)
endif()
list( APPEND MODES_${category} "${__prefix}" )
set( MODES_${__prefix}_suffix "_${parsed_MODE}" )
else()
set( MODES_${__prefix}_suffix "" )
endif()
list( REMOVE_ITEM default_categories "${category}" )
# we're in a macro: reset the variables first!
# previous invocations may already have set them
set( __defs "" )
set( __opts "" )
foreach( bt ${CMAKE_CONFIGURATION_TYPES} )
set( __defs_name "TEST_${__prefix}_DEFS_${bt}")
assert_defined_variables( ${__defs_name} )
list( APPEND __defs "$<$<CONFIG:${bt}>:${${__defs_name}}>" )
set( __opts_name "TEST_${__prefix}_OPTS_${bt}")
assert_defined_variables( ${__opts_name} )
list( APPEND __opts "$<$<CONFIG:${bt}>:${${__opts_name}}>" )
set( __perf_defs_name "TEST_${__prefix}_PERF_DEFS_${bt}")
assert_defined_variables( ${__perf_defs_name} )
list( APPEND __defs "$<$<CONFIG:${bt}>:${${__perf_defs_name}}>" )
set( __perf_opts_name "TEST_${__prefix}_PERF_OPTS_${bt}")
assert_defined_variables( ${__perf_opts_name} )
list( APPEND __opts "$<$<CONFIG:${bt}>:${${__perf_opts_name}}>" )
endforeach()
set( __tgt_name "test_${__prefix}_flags" )
add_library( ${__tgt_name} INTERFACE )
target_compile_definitions( ${__tgt_name} INTERFACE "${__defs}" )
target_compile_options( ${__tgt_name} INTERFACE "${__opts}" )
target_link_libraries( ${__tgt_name} INTERFACE common_flags )
endmacro( add_category_flags )
set_valid_string( TEST_unit_ndebug_DEFS_Release "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_unit_ndebug_DEFS_Debug "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_unit_ndebug_DEFS_Coverage "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_unit_ndebug_OPTS_Release "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_unit_ndebug_OPTS_Debug "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_unit_ndebug_OPTS_Coverage "${ADDITIONAL_TEST_OPTIONS}" "" )
# custom modes test the same code, just with different compilation flags
# hence, they have dedicated performance flags
set( TEST_unit_ndebug_PERF_DEFS_Release "${COMMON_PERF_DEFS_Release}" CACHE STRING
"Release definitions for category unit, mode ndebug "
)
set( TEST_unit_ndebug_PERF_DEFS_Debug "${COMMON_PERF_DEFS_Debug}" CACHE STRING
"Debug definitions for category unit, mode ndebug "
)
set( TEST_unit_ndebug_PERF_DEFS_Coverage "${COMMON_PERF_DEFS_Coverage}" CACHE STRING
"Coverage definitions for category unit, mode ndebug "
)
set( TEST_unit_ndebug_PERF_OPTS_Release "${COMMON_PERF_OPTS_Release}" CACHE STRING
"Release options for category unit, mode ndebug "
)
set( TEST_unit_ndebug_PERF_OPTS_Debug "${COMMON_PERF_OPTS_Release}" CACHE STRING
"Debug options for category unit, mode ndebug "
)
# coverage options are special, in that they must allow tracing execution: hence use
# dedicated flags
set( TEST_unit_ndebug_PERF_OPTS_Coverage "${COMMON_PERF_OPTS_Coverage}" CACHE STRING
"Coverage options for category unit, mode ndebug "
)
add_category_flags( "unit" MODE ndebug )
if( NOT CMAKE_BUILD_TYPE STREQUAL Coverage )
set_valid_string( TEST_unit_debug_DEFS_Release "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_unit_debug_DEFS_Debug "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_unit_debug_DEFS_Coverage "${ADDITIONAL_TEST_DEFINITIONS}" "" )
set_valid_string( TEST_unit_debug_OPTS_Release "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_unit_debug_OPTS_Debug "${ADDITIONAL_TEST_OPTIONS}" "" )
set_valid_string( TEST_unit_debug_OPTS_Coverage "${ADDITIONAL_TEST_OPTIONS}" "" )
set( TEST_unit_debug_PERF_DEFS_Release "${COMMON_PERF_DEFS_Debug}" CACHE STRING
"Release performance definitions for category unit, mode debug"
)
set( TEST_unit_debug_PERF_DEFS_Debug "${COMMON_PERF_DEFS_Debug}" CACHE STRING
"Debug performance definitions for category unit, mode debug"
)
set( TEST_unit_debug_PERF_DEFS_Coverage "${COMMON_PERF_DEFS_Debug}" CACHE STRING
"Coverage performance definitions for category unit, mode debug"
)
set( TEST_unit_debug_PERF_OPTS_Release "${COMMON_PERF_OPTS_Debug}" CACHE STRING
"Release options definitions for category unit, mode debug"
)
set( TEST_unit_debug_PERF_OPTS_Debug "${COMMON_PERF_OPTS_Debug}" CACHE STRING
"Debug options definitions for category unit, mode debug"
)
set( TEST_unit_debug_PERF_OPTS_Coverage "${COMMON_PERF_OPTS_Coverage}" CACHE STRING
"Coverage options definitions for category unit, mode debug"
)
add_category_flags( "unit" MODE debug )
endif()
# for categories with no specific options, set default:
# - modes with same name as category
# - flags are as default, via an alias
foreach( cat ${default_categories} )
set( MODES_${cat} "${cat}" )
set( MODES_${cat}_suffix "" )
add_library( "test_${cat}_flags" ALIAS test_default_flags )
endforeach()
# generate a report with all subsets of compilation flags, for each target type
message( "" )
message( "######### COMPILATION OPTIONS AND DEFINITIONS #########" )
message( "Build type: ${CMAKE_BUILD_TYPE}")
message( "global flags (from CMake): ${CMAKE_CXX_FLAGS} \
${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}"
)
message( "common definitions: ${COMMON_DEFS_${CMAKE_BUILD_TYPE}}" )
message( "common options: ${COMMON_OPTS_${CMAKE_BUILD_TYPE}}" )
message( "flags for BACKENDS:")
message( " definitions: ${BACKEND_DEFS_${CMAKE_BUILD_TYPE}}")
message( " options: ${BACKEND_OPTS_${CMAKE_BUILD_TYPE}}")
message( "flags for TESTS:")
foreach( cat ${TEST_CATEGORIES} )
if( cat IN_LIST default_categories )
continue()
endif()
message( " category: ${cat}" )
foreach( mode ${MODES_${cat}} )
assert_defined_variables( TEST_${mode}_DEFS_${CMAKE_BUILD_TYPE}
TEST_${mode}_OPTS_${CMAKE_BUILD_TYPE}
TEST_${mode}_PERF_DEFS_${CMAKE_BUILD_TYPE}
TEST_${mode}_PERF_OPTS_${CMAKE_BUILD_TYPE}
)
assert_defined_targets( test_${mode}_flags )
message( " mode: ${mode}" )
message( " definitions: ${TEST_${mode}_DEFS_${CMAKE_BUILD_TYPE}}" )
message( " options: ${TEST_${mode}_OPTS_${CMAKE_BUILD_TYPE}}" )
message( " performance definitions: ${TEST_${mode}_PERF_DEFS_${CMAKE_BUILD_TYPE}}" )
message( " performance options: ${TEST_${mode}_PERF_OPTS_${CMAKE_BUILD_TYPE}}" )
endforeach()
endforeach()
list( JOIN default_categories ", " cats )
message( "default test flags (categories: ${cats})")
set( test_defs ${TEST_DEFAULT_DEFS_${CMAKE_BUILD_TYPE}} )
if( COMMON_DEFS_EXTRA )
list( APPEND test_defs ${COMMON_DEFS_EXTRA} )
endif()
message( " common definitions: ${test_defs}")
set( test_opts ${TEST_DEFAULT_OPTS_${CMAKE_BUILD_TYPE}} )
if( COMMON_OPTS_EXTRA )
list( APPEND test_opts ${COMMON_OPTS_EXTRA} )
endif()
message( " common options: ${test_opts}")
message( " performance definitions: ${TEST_DEFAULT_PERF_DEFS_${CMAKE_BUILD_TYPE}}")
message( " performance options: ${TEST_DEFAULT_PERF_OPTS_${CMAKE_BUILD_TYPE}}")
message( "######### END OF COMPILATION OPTIONS AND DEFINITIONS #########" )
message( "" )