Skip to content

Commit 5681ff0

Browse files
committed
[FIXUP] cmake: Fix flags handling
1. Use standard CMake's way to pass flags from depends to the main build system using CMAKE_<LANGUAGE>_FLAGS_INIT variables instead of custom DEPENDS_<LANGUAGE>_COMPILER_FLAGS ones. This guaranties using those flags during various checks at the configuration stage. 2. Setting flags is decoupled from setting compilers in the toolchain file. 3. Per-configuration flags are cached properly. 4. No longer needed to set -DCMAKE_BUILD_TYPE=None when building with depends. Fixes cross compilation for macOS. Allows the user to use {C,CXX}FLAGS environment variables for depends and the main build system without drawbacks/workarounds.
1 parent efd3267 commit 5681ff0

File tree

5 files changed

+166
-65
lines changed

5 files changed

+166
-65
lines changed

CMakeLists.txt

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ add_library(core_interface INTERFACE)
114114
# include the warn_interface as subtree's warnings are not fixable
115115
# in our tree.
116116
add_library(core_base_interface INTERFACE)
117+
add_library(core_depends_release_interface INTERFACE)
118+
add_library(core_depends_debug_interface INTERFACE)
119+
target_link_libraries(core_base_interface INTERFACE
120+
$<$<CONFIG:RelWithDebInfo>:${core_depends_release_interface}>
121+
$<$<CONFIG:Debug>:${core_depends_debug_interface}>
122+
)
117123
target_link_libraries(core_interface INTERFACE core_base_interface)
118124

119125
if(FUZZ)
@@ -223,12 +229,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
223229
try_append_linker_flag("-Wl,-headerpad_max_install_names" TARGET core_base_interface)
224230
endif()
225231

226-
if(CMAKE_CROSSCOMPILING)
227-
target_compile_definitions(core_base_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS})
228-
target_compile_options(core_base_interface INTERFACE "$<$<COMPILE_LANGUAGE:C>:${DEPENDS_C_COMPILER_FLAGS}>")
229-
target_compile_options(core_base_interface INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:${DEPENDS_CXX_COMPILER_FLAGS}>")
230-
endif()
231-
232232
include(AddThreadsIfNeeded)
233233
add_threads_if_needed()
234234

@@ -280,10 +280,10 @@ include(cmake/leveldb.cmake)
280280
include(cmake/minisketch.cmake)
281281
include(cmake/secp256k1.cmake)
282282

283-
string(STRIP "${CMAKE_CXX_FLAGS}" cxx_flags)
284-
string(STRIP "${CMAKE_CXX_FLAGS_INIT}" cxx_flags_init)
285-
if(cxx_flags STREQUAL cxx_flags_init)
286-
# CMAKE_CXX_FLAGS are not overridden.
283+
include(ProcessConfigurations)
284+
are_flags_overridden(CMAKE_CXX_FLAGS cxx_flags_overridden)
285+
# TODO: Rework after https://github.com/bitcoin/bitcoin/pull/25972.
286+
if(NOT cxx_flags_overridden AND NOT CMAKE_CROSSCOMPILING)
287287
add_library(warn_interface INTERFACE)
288288
target_link_libraries(core_interface INTERFACE warn_interface)
289289
if(MSVC)
@@ -331,19 +331,17 @@ if(cxx_flags STREQUAL cxx_flags_init)
331331
)
332332
endif()
333333
endif()
334-
unset(cxx_flags)
335-
unset(cxx_flags_init)
334+
unset(cxx_flags_overridden)
336335

337-
include(ProcessConfigurations)
338336
set_default_config(RelWithDebInfo)
339337

340-
# Redefine configuration flags.
341-
target_compile_definitions(core_base_interface INTERFACE
342-
$<$<CONFIG:Debug>:DEBUG>
343-
$<$<CONFIG:Debug>:DEBUG_LOCKORDER>
344-
$<$<CONFIG:Debug>:DEBUG_LOCKCONTENTION>
345-
$<$<CONFIG:Debug>:RPC_DOC_CHECK>
346-
$<$<CONFIG:Debug>:ABORT_ON_FAILED_ASSUME>
338+
# Redefine/adjust per-configuration flags.
339+
target_compile_definitions(core_depends_debug_interface INTERFACE
340+
DEBUG
341+
DEBUG_LOCKORDER
342+
DEBUG_LOCKCONTENTION
343+
RPC_DOC_CHECK
344+
ABORT_ON_FAILED_ASSUME
347345
)
348346
# We leave assertions on.
349347
if(MSVC)
@@ -353,20 +351,52 @@ else()
353351
remove_c_flag_from_all_configs(-DNDEBUG)
354352
remove_cxx_flag_from_all_configs(-DNDEBUG)
355353

354+
# Adjust flags used by the C/CXX compiler during RELEASE builds.
356355
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
357356
replace_c_flag_in_config(Release -O3 -O2)
358357
replace_cxx_flag_in_config(Release -O3 -O2)
359358

360-
set(debug_flags)
361-
try_append_cxx_flags("-O0" VAR debug_flags)
362-
try_append_cxx_flags("-g3" VAR debug_flags RESULT_VAR compiler_supports_g3)
363-
if(NOT compiler_supports_g3)
364-
try_append_cxx_flags("-g" VAR debug_flags)
359+
are_flags_overridden(CMAKE_CXX_FLAGS_DEBUG cxx_flags_debug_overridden)
360+
if(NOT cxx_flags_debug_overridden)
361+
# Redefine flags used by the CXX compiler during DEBUG builds.
362+
try_append_cxx_flags("-g3" RESULT_VAR compiler_supports_g3)
363+
if(compiler_supports_g3)
364+
replace_cxx_flag_in_config(Debug -g -g3)
365+
endif()
366+
367+
try_append_cxx_flags("-ftrapv" RESULT_VAR compiler_supports_ftrapv)
368+
if(compiler_supports_ftrapv)
369+
string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-ftrapv ")
370+
endif()
371+
unset(compiler_supports_ftrapv)
372+
373+
string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-O0 ")
374+
375+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}"
376+
CACHE STRING
377+
"Flags used by the CXX compiler during DEBUG builds."
378+
FORCE
379+
)
380+
endif()
381+
unset(cxx_flags_debug_overridden)
382+
383+
are_flags_overridden(CMAKE_C_FLAGS_DEBUG c_flags_debug_overridden)
384+
if(NOT c_flags_debug_overridden)
385+
# Redefine flags used by the C compiler during DEBUG builds.
386+
if(compiler_supports_g3)
387+
replace_c_flag_in_config(Debug -g -g3)
388+
endif()
389+
390+
string(PREPEND CMAKE_C_FLAGS_DEBUG "-O0 ")
391+
392+
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}"
393+
CACHE STRING
394+
"Flags used by the C compiler during DEBUG builds."
395+
FORCE
396+
)
365397
endif()
366-
set(CMAKE_C_FLAGS_DEBUG "${debug_flags}")
367-
try_append_cxx_flags("-ftrapv" VAR debug_flags)
368-
set(CMAKE_CXX_FLAGS_DEBUG "${debug_flags}")
369-
unset(debug_flags)
398+
unset(compiler_supports_g3)
399+
unset(c_flags_debug_overridden)
370400
endif()
371401

372402
include(cmake/optional_qt.cmake)
@@ -462,9 +492,27 @@ setup_split_debug_script()
462492
add_maintenance_targets()
463493
add_windows_deploy_target()
464494

495+
496+
if(CMAKE_CROSSCOMPILING)
497+
target_compile_definitions(core_base_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS})
498+
target_compile_definitions(core_depends_release_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO})
499+
target_compile_definitions(core_depends_debug_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_DEBUG})
500+
501+
# If {C,CXX}FLAGS variables are defined during building depends and
502+
# configuring this build system, their content might be duplicated.
503+
if(DEFINED ENV{CFLAGS})
504+
deduplicate_flags(CMAKE_C_FLAGS)
505+
endif()
506+
if(DEFINED ENV{CXXFLAGS})
507+
deduplicate_flags(CMAKE_CXX_FLAGS)
508+
endif()
509+
endif()
510+
511+
465512
include(GetTargetInterface)
466513
get_target_interface(definitions core_interface COMPILE_DEFINITIONS)
467-
separate_by_configs(definitions)
514+
get_target_interface(definitions_RELWITHDEBINFO core_depends_release_interface COMPILE_DEFINITIONS)
515+
get_target_interface(definitions_DEBUG core_depends_debug_interface COMPILE_DEFINITIONS)
468516

469517
message("\n")
470518
message("Configure summary")
@@ -500,15 +548,11 @@ else()
500548
set(cross_status "FALSE")
501549
endif()
502550
message("Cross compiling ....................... ${cross_status}")
503-
message("Preprocessor defined macros ........... ${definitions_ALL}")
551+
message("Preprocessor defined macros ........... ${definitions}")
504552
message("C compiler ............................ ${CMAKE_C_COMPILER}")
505-
list(JOIN DEPENDS_C_COMPILER_FLAGS " " depends_c_flags)
506-
string(STRIP "${CMAKE_C_FLAGS} ${depends_c_flags}" combined_c_flags)
507-
message("CFLAGS ................................ ${combined_c_flags}")
553+
message("CFLAGS ................................ ${CMAKE_C_FLAGS}")
508554
message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}")
509-
list(JOIN DEPENDS_CXX_COMPILER_FLAGS " " depends_cxx_flags)
510-
string(STRIP "${CMAKE_CXX_FLAGS} ${depends_cxx_flags}" combined_cxx_flags)
511-
message("CXXFLAGS .............................. ${combined_cxx_flags}")
555+
message("CXXFLAGS .............................. ${CMAKE_CXX_FLAGS}")
512556
get_target_interface(common_compile_options core_interface COMPILE_OPTIONS)
513557
message("Common compile options ................ ${common_compile_options}")
514558
get_target_interface(common_link_options core_interface LINK_OPTIONS)

cmake/module/GetTargetInterface.cmake

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ include_guard(GLOBAL)
88
function(get_target_interface var target property)
99
get_target_property(result ${target} INTERFACE_${property})
1010
if(result)
11-
if(NOT ${property} STREQUAL "COMPILE_DEFINITIONS")
12-
string(GENEX_STRIP "${result}" result)
13-
endif()
11+
string(GENEX_STRIP "${result}" result)
1412
list(JOIN result " " result)
1513
else()
1614
set(result)

cmake/module/ProcessConfigurations.cmake

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,36 @@
22
# Distributed under the MIT software license, see the accompanying
33
# file COPYING or https://opensource.org/license/mit/.
44

5+
include_guard(GLOBAL)
6+
7+
macro(normalize_string string)
8+
string(REGEX REPLACE " +" " " ${string} "${${string}}")
9+
string(STRIP "${${string}}" ${string})
10+
endmacro()
11+
12+
function(are_flags_overridden flags_var result_var)
13+
normalize_string(${flags_var})
14+
normalize_string(${flags_var}_INIT)
15+
if(${flags_var} STREQUAL ${flags_var}_INIT)
16+
set(${result_var} FALSE PARENT_SCOPE)
17+
else()
18+
set(${result_var} TRUE PARENT_SCOPE)
19+
endif()
20+
endfunction()
21+
22+
23+
# Removes duplicated flags. The relative order of flags is preserved.
24+
# If duplicates are encountered, only the last instance is preserved.
25+
function(deduplicate_flags flags)
26+
separate_arguments(${flags})
27+
list(REVERSE ${flags})
28+
list(REMOVE_DUPLICATES ${flags})
29+
list(REVERSE ${flags})
30+
list(JOIN ${flags} " " result)
31+
set(${flags} "${result}" PARENT_SCOPE)
32+
endfunction()
33+
34+
535
function(get_all_configs output)
636
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
737
if(is_multi_config)
@@ -63,6 +93,11 @@ function(remove_c_flag_from_all_configs flag)
6393
list(FILTER flags EXCLUDE REGEX "${flag}")
6494
list(JOIN flags " " new_flags)
6595
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
96+
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}"
97+
CACHE STRING
98+
"Flags used by the C compiler during ${config_uppercase} builds."
99+
FORCE
100+
)
66101
endforeach()
67102
endfunction()
68103

@@ -75,36 +110,34 @@ function(remove_cxx_flag_from_all_configs flag)
75110
list(FILTER flags EXCLUDE REGEX "${flag}")
76111
list(JOIN flags " " new_flags)
77112
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
113+
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}"
114+
CACHE STRING
115+
"Flags used by the CXX compiler during ${config_uppercase} builds."
116+
FORCE
117+
)
78118
endforeach()
79119
endfunction()
80120

81121
function(replace_c_flag_in_config config old_flag new_flag)
82122
string(TOUPPER "${config}" config_uppercase)
83123
string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_C_FLAGS_${config_uppercase}}")
84124
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
125+
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}"
126+
CACHE STRING
127+
"Flags used by the C compiler during ${config_uppercase} builds."
128+
FORCE
129+
)
85130
endfunction()
86131

87132
function(replace_cxx_flag_in_config config old_flag new_flag)
88133
string(TOUPPER "${config}" config_uppercase)
89134
string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
90135
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
91-
endfunction()
92-
93-
function(separate_by_configs options)
94-
list(JOIN ${options} " " ${options}_ALL)
95-
string(GENEX_STRIP "${${options}_ALL}" ${options}_ALL)
96-
string(STRIP "${${options}_ALL}" ${options}_ALL)
97-
set(${options}_ALL "${${options}_ALL}" PARENT_SCOPE)
98-
99-
get_all_configs(all_configs)
100-
foreach(config IN LISTS all_configs)
101-
string(REGEX MATCHALL "\\$<\\$<CONFIG:${config}>:[^<>\n]*>" match "${${options}}")
102-
list(JOIN match " " match)
103-
string(REPLACE "\$<\$<CONFIG:${config}>:" "" match "${match}")
104-
string(REPLACE ">" "" match "${match}")
105-
string(TOUPPER "${config}" conf_upper)
106-
set(${options}_${conf_upper} "${match}" PARENT_SCOPE)
107-
endforeach()
136+
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}"
137+
CACHE STRING
138+
"Flags used by the CXX compiler during ${config_uppercase} builds."
139+
FORCE
140+
)
108141
endfunction()
109142

110143
function(print_config_flags)

depends/Makefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,15 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_
273273
-e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \
274274
-e 's|@OTOOL@|$(host_OTOOL)|' \
275275
-e 's|@depends_prefix@|$(host_prefix)|' \
276-
-e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \
277-
-e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \
278-
-e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \
276+
-e 's|@CFLAGS@|$(strip $(host_CFLAGS))|' \
277+
-e 's|@CFLAGS_RELEASE@|$(strip $(host_release_CFLAGS))|' \
278+
-e 's|@CFLAGS_DEBUG@|$(strip $(host_debug_CFLAGS))|' \
279+
-e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS))|' \
280+
-e 's|@CXXFLAGS_RELEASE@|$(strip $(host_release_CXXFLAGS))|' \
281+
-e 's|@CXXFLAGS_DEBUG@|$(strip $(host_debug_CXXFLAGS))|' \
282+
-e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS))|' \
283+
-e 's|@CPPFLAGS_RELEASE@|$(strip $(host_release_CPPFLAGS))|' \
284+
-e 's|@CPPFLAGS_DEBUG@|$(strip $(host_debug_CPPFLAGS))|' \
279285
-e 's|@no_qt@|$(NO_QT)|' \
280286
-e 's|@no_qr@|$(NO_QR)|' \
281287
-e 's|@no_zmq@|$(NO_ZMQ)|' \

depends/toolchain.cmake.in

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,17 @@ function(split_compiler_launcher env_compiler launcher compiler)
3232
set(${compiler} ${${compiler}} PARENT_SCOPE)
3333
endfunction()
3434

35-
if(NOT CMAKE_C_COMPILER)
35+
if(NOT DEFINED CMAKE_C_FLAGS_INIT)
36+
set(CMAKE_C_FLAGS_INIT "@CFLAGS@")
37+
endif()
38+
if(NOT DEFINED CMAKE_C_FLAGS_RELWITHDEBINFO_INIT)
39+
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "@CFLAGS_RELEASE@")
40+
endif()
41+
if(NOT DEFINED CMAKE_C_FLAGS_DEBUG_INIT)
42+
set(CMAKE_C_FLAGS_DEBUG_INIT "@CFLAGS_DEBUG@")
43+
endif()
44+
45+
if(NOT DEFINED CMAKE_C_COMPILER)
3646
set(DEPENDS_C_COMPILER_WITH_LAUNCHER @CC@)
3747
split_compiler_launcher(DEPENDS_C_COMPILER_WITH_LAUNCHER CMAKE_C_COMPILER_LAUNCHER CMAKE_C_COMPILER)
3848
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21)
@@ -48,10 +58,19 @@ if(NOT CMAKE_C_COMPILER)
4858
string(PREPEND CMAKE_C_FLAGS_INIT "${mandatory_c_compiler_flags} ")
4959
unset(mandatory_c_compiler_flags)
5060
endif()
51-
set(DEPENDS_C_COMPILER_FLAGS @CFLAGS@)
5261
endif()
5362

54-
if(NOT CMAKE_CXX_COMPILER)
63+
if(NOT DEFINED CMAKE_CXX_FLAGS_INIT)
64+
set(CMAKE_CXX_FLAGS_INIT "@CXXFLAGS@")
65+
endif()
66+
if(NOT DEFINED CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT)
67+
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "@CXXFLAGS_RELEASE@")
68+
endif()
69+
if(NOT DEFINED CMAKE_CXX_FLAGS_DEBUG_INIT)
70+
set(CMAKE_CXX_FLAGS_DEBUG_INIT "@CXXFLAGS_DEBUG@")
71+
endif()
72+
73+
if(NOT DEFINED CMAKE_CXX_COMPILER)
5574
set(DEPENDS_CXX_COMPILER_WITH_LAUNCHER @CXX@)
5675
split_compiler_launcher(DEPENDS_CXX_COMPILER_WITH_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER CMAKE_CXX_COMPILER)
5776
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21)
@@ -70,14 +89,15 @@ if(NOT CMAKE_CXX_COMPILER)
7089
string(PREPEND CMAKE_SHARED_LINKER_FLAGS_INIT "${mandatory_cxx_compiler_flags} ")
7190
unset(mandatory_cxx_compiler_flags)
7291
endif()
73-
set(DEPENDS_CXX_COMPILER_FLAGS @CXXFLAGS@)
74-
7592
set(CMAKE_OBJCXX_COMPILER ${CMAKE_CXX_COMPILER})
7693
set(CMAKE_OBJCXX_COMPILER_LAUNCHER ${CMAKE_CXX_COMPILER_LAUNCHER})
7794
set(CMAKE_OBJCXX_LINKER_LAUNCHER ${CMAKE_CXX_LINKER_LAUNCHER})
7895
endif()
7996

97+
# The DEPENDS_COMPILE_DEFINITIONS* variables are to be treated as lists.
8098
set(DEPENDS_COMPILE_DEFINITIONS @CPPFLAGS@)
99+
set(DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO @CPPFLAGS_RELEASE@)
100+
set(DEPENDS_COMPILE_DEFINITIONS_DEBUG @CPPFLAGS_DEBUG@)
81101

82102
set(CMAKE_AR "@AR@")
83103
set(CMAKE_RANLIB "@RANLIB@")

0 commit comments

Comments
 (0)