Skip to content

Commit f4162d0

Browse files
committed
cmake: Redefine configuration flags
1 parent 2e7355b commit f4162d0

File tree

2 files changed

+179
-24
lines changed

2 files changed

+179
-24
lines changed

CMakeLists.txt

+47-24
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ unset(check_pie_output)
9191
# It is intended to be a usage requirement for all other targets.
9292
add_library(core INTERFACE)
9393

94+
include(TryAppendCXXFlags)
9495
include(TryAppendLinkerFlag)
9596

9697
if(WIN32)
@@ -188,6 +189,47 @@ include(cmake/leveldb.cmake)
188189
include(cmake/minisketch.cmake)
189190
include(cmake/secp256k1.cmake)
190191

192+
include(ProcessConfigurations)
193+
set_default_config(RelWithDebInfo)
194+
195+
# Redefine configuration flags.
196+
target_compile_definitions(core INTERFACE
197+
$<$<CONFIG:Debug>:DEBUG>
198+
$<$<CONFIG:Debug>:DEBUG_LOCKORDER>
199+
$<$<CONFIG:Debug>:DEBUG_LOCKCONTENTION>
200+
$<$<CONFIG:Debug>:RPC_DOC_CHECK>
201+
$<$<CONFIG:Debug>:ABORT_ON_FAILED_ASSUME>
202+
)
203+
# We leave assertions on.
204+
if(MSVC)
205+
remove_c_flag_from_all_configs(/DNDEBUG)
206+
remove_cxx_flag_from_all_configs(/DNDEBUG)
207+
else()
208+
remove_c_flag_from_all_configs(-DNDEBUG)
209+
remove_cxx_flag_from_all_configs(-DNDEBUG)
210+
211+
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
212+
replace_c_flag_in_config(Release -O3 -O2)
213+
replace_cxx_flag_in_config(Release -O3 -O2)
214+
215+
set(debug_c_flags "")
216+
set(debug_cxx_flags "")
217+
try_append_cxx_flags(debug_cxx_flags "-O0" RESULT_VAR compiler_supports_O0)
218+
if(compiler_supports_O0)
219+
string(STRIP "${debug_c_flags} -O0" debug_c_flags)
220+
endif()
221+
try_append_cxx_flags(debug_cxx_flags "-g3" RESULT_VAR compiler_supports_g3)
222+
if(compiler_supports_g3)
223+
string(STRIP "${debug_c_flags} -g3" debug_c_flags)
224+
else()
225+
try_append_cxx_flags(debug_cxx_flags "-g")
226+
string(STRIP "${debug_c_flags} -g" debug_c_flags)
227+
endif()
228+
try_append_cxx_flags(debug_cxx_flags "-ftrapv")
229+
set(CMAKE_C_FLAGS_DEBUG "${debug_c_flags}")
230+
set(CMAKE_CXX_FLAGS_DEBUG "${debug_cxx_flags}")
231+
endif()
232+
191233
include(cmake/optional.cmake)
192234

193235
find_package(Python3 3.9 COMPONENTS Interpreter)
@@ -198,6 +240,9 @@ add_subdirectory(test)
198240

199241
include(cmake/tests.cmake)
200242

243+
get_target_property(definitions core INTERFACE_COMPILE_DEFINITIONS)
244+
separate_by_configs(definitions)
245+
201246
message("\n")
202247
message("Configure summary")
203248
message("=================")
@@ -225,9 +270,7 @@ else()
225270
set(cross_status "FALSE")
226271
endif()
227272
message("Cross compiling ....................... ${cross_status}")
228-
get_directory_property(definitions COMPILE_DEFINITIONS)
229-
string(REPLACE ";" " " definitions "${definitions}")
230-
message("Preprocessor defined macros ........... ${definitions}")
273+
message("Preprocessor defined macros ........... ${definitions_ALL}")
231274
message("C compiler ............................ ${CMAKE_C_COMPILER}")
232275
list(JOIN DEPENDS_C_COMPILER_FLAGS " " depends_c_flags)
233276
string(STRIP "${CMAKE_C_FLAGS} ${depends_c_flags}" combined_c_flags)
@@ -253,27 +296,7 @@ endif()
253296
message("Common link options ................... ${common_link_options}")
254297
message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}")
255298
message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}")
256-
if(DEFINED CMAKE_BUILD_TYPE)
257-
message("Build type:")
258-
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
259-
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
260-
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
261-
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${build_type}}")
262-
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
263-
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
264-
else()
265-
message("Available configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
266-
message("Debug configuration:")
267-
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
268-
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_DEBUG}")
269-
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
270-
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
271-
message("Release configuration:")
272-
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELEASE}")
273-
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_RELEASE}")
274-
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
275-
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
276-
endif()
299+
print_config_flags()
277300
message("Use assembly routines ................. ${ASM}")
278301
message("Use ccache for compiling .............. ${CCACHE}")
279302
message("\n")
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Copyright (c) 2023-present The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit/.
4+
5+
function(get_all_configs output)
6+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
7+
if(is_multi_config)
8+
set(all_configs ${CMAKE_CONFIGURATION_TYPES})
9+
else()
10+
get_property(all_configs CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS)
11+
if(NOT all_configs)
12+
# See https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#default-and-custom-configurations
13+
set(all_configs Debug Release RelWithDebInfo MinSizeRel)
14+
endif()
15+
endif()
16+
set(${output} "${all_configs}" PARENT_SCOPE)
17+
endfunction()
18+
19+
20+
#[=[
21+
Set the default build configuration.
22+
23+
See: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations.
24+
25+
On single-configuration generators, this function sets the CMAKE_BUILD_TYPE variable to
26+
the default build configuration, which can be overridden by the user at configure time if needed.
27+
28+
On multi-configuration generators, this function rearranges the CMAKE_CONFIGURATION_TYPES list,
29+
ensuring that the default build configuration appears first while maintaining the order of the
30+
remaining configurations. The user can choose a build configuration at build time.
31+
]=]
32+
function(set_default_config config)
33+
get_all_configs(all_configs)
34+
if(NOT ${config} IN_LIST all_configs)
35+
message(FATAL_ERROR "The default config is \"${config}\", but must be one of ${all_configs}.")
36+
endif()
37+
38+
list(REMOVE_ITEM all_configs ${config})
39+
list(PREPEND all_configs ${config})
40+
41+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
42+
if(is_multi_config)
43+
get_property(help_string CACHE CMAKE_CONFIGURATION_TYPES PROPERTY HELPSTRING)
44+
set(CMAKE_CONFIGURATION_TYPES "${all_configs}" CACHE STRING "${help_string}" FORCE)
45+
else()
46+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
47+
STRINGS "${all_configs}"
48+
)
49+
if(NOT CMAKE_BUILD_TYPE)
50+
message(STATUS "Setting build type to \"${config}\" as none was specified")
51+
get_property(help_string CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING)
52+
set(CMAKE_BUILD_TYPE "${config}" CACHE STRING "${help_string}" FORCE)
53+
endif()
54+
endif()
55+
endfunction()
56+
57+
function(remove_c_flag_from_all_configs flag)
58+
get_all_configs(all_configs)
59+
foreach(config IN LISTS all_configs)
60+
string(TOUPPER "${config}" config_uppercase)
61+
set(flags "${CMAKE_C_FLAGS_${config_uppercase}}")
62+
separate_arguments(flags)
63+
list(FILTER flags EXCLUDE REGEX "${flag}")
64+
list(JOIN flags " " new_flags)
65+
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
66+
endforeach()
67+
endfunction()
68+
69+
function(remove_cxx_flag_from_all_configs flag)
70+
get_all_configs(all_configs)
71+
foreach(config IN LISTS all_configs)
72+
string(TOUPPER "${config}" config_uppercase)
73+
set(flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
74+
separate_arguments(flags)
75+
list(FILTER flags EXCLUDE REGEX "${flag}")
76+
list(JOIN flags " " new_flags)
77+
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
78+
endforeach()
79+
endfunction()
80+
81+
function(replace_c_flag_in_config config old_flag new_flag)
82+
string(TOUPPER "${config}" config_uppercase)
83+
string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_C_FLAGS_${config_uppercase}}")
84+
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
85+
endfunction()
86+
87+
function(replace_cxx_flag_in_config config old_flag new_flag)
88+
string(TOUPPER "${config}" config_uppercase)
89+
string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
90+
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+
set(${options}_ALL "${${options}_ALL}" PARENT_SCOPE)
97+
98+
get_all_configs(all_configs)
99+
foreach(config IN LISTS all_configs)
100+
string(REGEX MATCHALL "\\$<\\$<CONFIG:${config}>[^\n]*>" match "${${options}}")
101+
list(JOIN match " " match)
102+
string(REPLACE "\$<\$<CONFIG:${config}>:" "" match "${match}")
103+
string(REPLACE ">" "" match "${match}")
104+
string(TOUPPER "${config}" conf_upper)
105+
set(${options}_${conf_upper} "${match}" PARENT_SCOPE)
106+
endforeach()
107+
endfunction()
108+
109+
function(print_config_flags)
110+
macro(print_flags config)
111+
string(TOUPPER "${config}" config_uppercase)
112+
message(" - Preprocessor defined macros ........ ${definitions_${config_uppercase}}")
113+
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${config_uppercase}}")
114+
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${config_uppercase}}")
115+
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${config_uppercase}}")
116+
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${config_uppercase}}")
117+
endmacro()
118+
119+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
120+
if(is_multi_config)
121+
list(JOIN CMAKE_CONFIGURATION_TYPES " " configs)
122+
message("Available build types (configurations) ${configs}")
123+
foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
124+
message("'${config}' build type (configuration):")
125+
print_flags(${config})
126+
endforeach()
127+
else()
128+
message("Build type (configuration):")
129+
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
130+
print_flags(${CMAKE_BUILD_TYPE})
131+
endif()
132+
endfunction()

0 commit comments

Comments
 (0)