Skip to content

Commit f365f4b

Browse files
committed
cmake: Redefine configuration flags
1 parent 93f8b26 commit f365f4b

File tree

2 files changed

+171
-24
lines changed

2 files changed

+171
-24
lines changed

CMakeLists.txt

+45-24
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
8080

8181
set(configure_warnings)
8282

83+
include(TryAppendCXXFlags)
8384
include(TryAppendLinkerFlag)
8485

8586
if(WIN32)
@@ -163,6 +164,45 @@ include(cmake/leveldb.cmake)
163164
include(cmake/minisketch.cmake)
164165
include(cmake/secp256k1.cmake)
165166

167+
include(ProcessConfigurations)
168+
set_default_config(RelWithDebInfo)
169+
170+
# Redefine configuration flags.
171+
add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
172+
add_compile_definitions($<$<CONFIG:Debug>:DEBUG_LOCKORDER>)
173+
add_compile_definitions($<$<CONFIG:Debug>:DEBUG_LOCKCONTENTION>)
174+
add_compile_definitions($<$<CONFIG:Debug>:RPC_DOC_CHECK>)
175+
add_compile_definitions($<$<CONFIG:Debug>:ABORT_ON_FAILED_ASSUME>)
176+
# We leave assertions on.
177+
if(MSVC)
178+
remove_c_flag_from_all_configs(/DNDEBUG)
179+
remove_cxx_flag_from_all_configs(/DNDEBUG)
180+
else()
181+
remove_c_flag_from_all_configs(-DNDEBUG)
182+
remove_cxx_flag_from_all_configs(-DNDEBUG)
183+
184+
# Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
185+
replace_c_flag_in_config(Release -O3 -O2)
186+
replace_cxx_flag_in_config(Release -O3 -O2)
187+
188+
set(debug_c_flags "")
189+
set(debug_cxx_flags "")
190+
try_append_cxx_flags(debug_cxx_flags "-O0" RESULT_VAR compiler_supports_O0)
191+
if(compiler_supports_O0)
192+
string(STRIP "${debug_c_flags} -O0" debug_c_flags)
193+
endif()
194+
try_append_cxx_flags(debug_cxx_flags "-g3" RESULT_VAR compiler_supports_g3)
195+
if(compiler_supports_g3)
196+
string(STRIP "${debug_c_flags} -g3" debug_c_flags)
197+
else()
198+
try_append_cxx_flags(debug_cxx_flags "-g")
199+
string(STRIP "${debug_c_flags} -g" debug_c_flags)
200+
endif()
201+
try_append_cxx_flags(debug_cxx_flags "-ftrapv")
202+
set(CMAKE_C_FLAGS_DEBUG "${debug_c_flags}")
203+
set(CMAKE_CXX_FLAGS_DEBUG "${debug_cxx_flags}")
204+
endif()
205+
166206
include(cmake/optional.cmake)
167207

168208
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14)
@@ -186,6 +226,9 @@ add_subdirectory(test)
186226

187227
include(cmake/tests.cmake)
188228

229+
get_directory_property(definitions COMPILE_DEFINITIONS)
230+
separate_by_configs(definitions)
231+
189232
message("\n")
190233
message("Configure summary")
191234
message("=================")
@@ -213,9 +256,7 @@ else()
213256
set(cross_status "FALSE")
214257
endif()
215258
message("Cross compiling ....................... ${cross_status}")
216-
get_directory_property(definitions COMPILE_DEFINITIONS)
217-
string(REPLACE ";" " " definitions "${definitions}")
218-
message("Preprocessor defined macros ........... ${definitions}")
259+
message("Preprocessor defined macros ........... ${definitions_ALL}")
219260
message("C compiler ............................ ${CMAKE_C_COMPILER}")
220261
list(JOIN DEPENDS_C_COMPILER_FLAGS " " depends_c_flags)
221262
string(STRIP "${CMAKE_C_FLAGS} ${depends_c_flags}" combined_c_flags)
@@ -233,27 +274,7 @@ list(JOIN common_link_options " " common_link_options)
233274
message("Common link options ................... ${common_link_options}")
234275
message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}")
235276
message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}")
236-
if(DEFINED CMAKE_BUILD_TYPE)
237-
message("Build type:")
238-
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
239-
string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type)
240-
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}")
241-
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${build_type}}")
242-
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}")
243-
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}")
244-
else()
245-
message("Available configurations .............. ${CMAKE_CONFIGURATION_TYPES}")
246-
message("Debug configuration:")
247-
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}")
248-
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_DEBUG}")
249-
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
250-
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
251-
message("Release configuration:")
252-
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELEASE}")
253-
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_RELEASE}")
254-
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
255-
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
256-
endif()
277+
print_config_flags()
257278
message("Use assembly routines ................. ${ASM}")
258279
message("Use ccache for compiling .............. ${CCACHE}")
259280
message("\n")
+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Copyright (c) 2023 The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
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+
# When used with multi-configuration generators, this function rearranges
20+
# the CMAKE_CONFIGURATION_TYPES list, ensuring that the default configuration type
21+
# appears first while maintaining the order of the remaining configuration types.
22+
function(set_default_config config)
23+
get_all_configs(all_configs)
24+
if(NOT ${config} IN_LIST all_configs)
25+
message(FATAL_ERROR "The default config is \"${config}\", but must be one of ${all_configs}.")
26+
endif()
27+
28+
list(REMOVE_ITEM all_configs ${config})
29+
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15)
30+
list(PREPEND all_configs ${config})
31+
else()
32+
set(all_configs ${config} ${all_configs})
33+
endif()
34+
35+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
36+
if(is_multi_config)
37+
get_property(help_string CACHE CMAKE_CONFIGURATION_TYPES PROPERTY HELPSTRING)
38+
set(CMAKE_CONFIGURATION_TYPES "${all_configs}" CACHE STRING "${help_string}" FORCE)
39+
else()
40+
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
41+
STRINGS "${all_configs}"
42+
)
43+
if(NOT CMAKE_BUILD_TYPE)
44+
message(STATUS "Setting build type to \"${config}\" as none was specified")
45+
get_property(help_string CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING)
46+
set(CMAKE_BUILD_TYPE "${config}" CACHE STRING "${help_string}" FORCE)
47+
endif()
48+
endif()
49+
endfunction()
50+
51+
function(remove_c_flag_from_all_configs flag)
52+
get_all_configs(all_configs)
53+
foreach(config IN LISTS all_configs)
54+
string(TOUPPER "${config}" config_uppercase)
55+
set(flags "${CMAKE_C_FLAGS_${config_uppercase}}")
56+
separate_arguments(flags)
57+
list(FILTER flags EXCLUDE REGEX "${flag}")
58+
list(JOIN flags " " new_flags)
59+
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
60+
endforeach()
61+
endfunction()
62+
63+
function(remove_cxx_flag_from_all_configs flag)
64+
get_all_configs(all_configs)
65+
foreach(config IN LISTS all_configs)
66+
string(TOUPPER "${config}" config_uppercase)
67+
set(flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
68+
separate_arguments(flags)
69+
list(FILTER flags EXCLUDE REGEX "${flag}")
70+
list(JOIN flags " " new_flags)
71+
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
72+
endforeach()
73+
endfunction()
74+
75+
function(replace_c_flag_in_config config old_flag new_flag)
76+
string(TOUPPER "${config}" config_uppercase)
77+
string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_C_FLAGS_${config_uppercase}}")
78+
set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
79+
endfunction()
80+
81+
function(replace_cxx_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_CXX_FLAGS_${config_uppercase}}")
84+
set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
85+
endfunction()
86+
87+
function(separate_by_configs options)
88+
list(JOIN ${options} " " ${options}_ALL)
89+
string(GENEX_STRIP "${${options}_ALL}" ${options}_ALL)
90+
set(${options}_ALL "${${options}_ALL}" PARENT_SCOPE)
91+
92+
get_all_configs(all_configs)
93+
foreach(config IN LISTS all_configs)
94+
string(REGEX MATCHALL "\\$<\\$<CONFIG:${config}>[^\n]*>" match "${${options}}")
95+
list(JOIN match " " match)
96+
string(REPLACE "\$<\$<CONFIG:${config}>:" "" match "${match}")
97+
string(REPLACE ">" "" match "${match}")
98+
string(TOUPPER "${config}" conf_upper)
99+
set(${options}_${conf_upper} "${match}" PARENT_SCOPE)
100+
endforeach()
101+
endfunction()
102+
103+
function(print_config_flags)
104+
macro(print_flags config)
105+
string(TOUPPER "${config}" config_uppercase)
106+
message(" - Preprocessor defined macros ........ ${definitions_${config_uppercase}}")
107+
message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${config_uppercase}}")
108+
message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${config_uppercase}}")
109+
message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${config_uppercase}}")
110+
message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${config_uppercase}}")
111+
endmacro()
112+
113+
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
114+
if(is_multi_config)
115+
list(JOIN CMAKE_CONFIGURATION_TYPES " " configs)
116+
message("Available build types (configurations) ${configs}")
117+
foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
118+
message("'${config}' build type (configuration):")
119+
print_flags(${config})
120+
endforeach()
121+
else()
122+
message("Build type (configuration):")
123+
message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}")
124+
print_flags(${CMAKE_BUILD_TYPE})
125+
endif()
126+
endfunction()

0 commit comments

Comments
 (0)