ProcessConfigurations.cmake raw
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 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
35 function(get_all_configs output)
36 get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
37 if(is_multi_config)
38 set(all_configs ${CMAKE_CONFIGURATION_TYPES})
39 else()
40 get_property(all_configs CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS)
41 if(NOT all_configs)
42 # See https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#default-and-custom-configurations
43 set(all_configs Debug Release RelWithDebInfo MinSizeRel)
44 endif()
45 endif()
46 set(${output} "${all_configs}" PARENT_SCOPE)
47 endfunction()
48
49
50 #[=[
51 Set the default build configuration.
52
53 See: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations.
54
55 On single-configuration generators, this function sets the CMAKE_BUILD_TYPE variable to
56 the default build configuration, which can be overridden by the user at configure time if needed.
57
58 On multi-configuration generators, this function rearranges the CMAKE_CONFIGURATION_TYPES list,
59 ensuring that the default build configuration appears first while maintaining the order of the
60 remaining configurations. The user can choose a build configuration at build time.
61 ]=]
62 function(set_default_config config)
63 get_all_configs(all_configs)
64 if(NOT ${config} IN_LIST all_configs)
65 message(FATAL_ERROR "The default config is \"${config}\", but must be one of ${all_configs}.")
66 endif()
67
68 list(REMOVE_ITEM all_configs ${config})
69 list(PREPEND all_configs ${config})
70
71 get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
72 if(is_multi_config)
73 get_property(help_string CACHE CMAKE_CONFIGURATION_TYPES PROPERTY HELPSTRING)
74 set(CMAKE_CONFIGURATION_TYPES "${all_configs}" CACHE STRING "${help_string}" FORCE)
75 # Also see https://gitlab.kitware.com/cmake/cmake/-/issues/19512.
76 set(CMAKE_TRY_COMPILE_CONFIGURATION "${config}" PARENT_SCOPE)
77 else()
78 set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
79 STRINGS "${all_configs}"
80 )
81 if(NOT CMAKE_BUILD_TYPE)
82 message(STATUS "Setting build type to \"${config}\" as none was specified")
83 get_property(help_string CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING)
84 set(CMAKE_BUILD_TYPE "${config}" CACHE STRING "${help_string}" FORCE)
85 endif()
86 set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}" PARENT_SCOPE)
87 endif()
88 endfunction()
89
90 function(remove_cxx_flag_from_all_configs flag)
91 get_all_configs(all_configs)
92 foreach(config IN LISTS all_configs)
93 string(TOUPPER "${config}" config_uppercase)
94 set(flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
95 separate_arguments(flags)
96 list(FILTER flags EXCLUDE REGEX "${flag}")
97 list(JOIN flags " " new_flags)
98 set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
99 set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}"
100 CACHE STRING
101 "Flags used by the CXX compiler during ${config_uppercase} builds."
102 FORCE
103 )
104 endforeach()
105 endfunction()
106
107 function(replace_cxx_flag_in_config config old_flag new_flag)
108 string(TOUPPER "CMAKE_CXX_FLAGS_${config}" var_name)
109 if("${var_name}" IN_LIST precious_variables)
110 return()
111 endif()
112 string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" ${var_name} "${${var_name}}")
113 set(${var_name} "${${var_name}}" PARENT_SCOPE)
114 set_property(CACHE ${var_name} PROPERTY VALUE "${${var_name}}")
115 endfunction()
116
117 set_default_config(RelWithDebInfo)
118
119 include(TryAppendCXXFlags)
120
121 # We leave assertions on.
122 if(MSVC)
123 remove_cxx_flag_from_all_configs(/DNDEBUG)
124 else()
125 remove_cxx_flag_from_all_configs(-DNDEBUG)
126
127 # Adjust flags used by the CXX compiler during RELEASE builds.
128 # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
129 replace_cxx_flag_in_config(Release -O3 -O2)
130
131 are_flags_overridden(CMAKE_CXX_FLAGS_DEBUG cxx_flags_debug_overridden)
132 if(NOT cxx_flags_debug_overridden)
133 # Redefine flags used by the CXX compiler during DEBUG builds.
134 try_append_cxx_flags("-g3" RESULT_VAR compiler_supports_g3)
135 if(compiler_supports_g3)
136 replace_cxx_flag_in_config(Debug -g -g3)
137 endif()
138 unset(compiler_supports_g3)
139
140 try_append_cxx_flags("-ftrapv" RESULT_VAR compiler_supports_ftrapv)
141 if(compiler_supports_ftrapv)
142 string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-ftrapv ")
143 endif()
144 unset(compiler_supports_ftrapv)
145
146 string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-O0 ")
147
148 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}"
149 CACHE STRING
150 "Flags used by the CXX compiler during DEBUG builds."
151 FORCE
152 )
153 endif()
154 unset(cxx_flags_debug_overridden)
155 endif()
156
157 set(CMAKE_CXX_FLAGS_COVERAGE "-g -Og --coverage")
158 set(CMAKE_OBJCXX_FLAGS_COVERAGE "-g -Og --coverage")
159 set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage")
160 set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage")
161 get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
162 if(is_multi_config)
163 if(NOT "Coverage" IN_LIST CMAKE_CONFIGURATION_TYPES)
164 list(APPEND CMAKE_CONFIGURATION_TYPES Coverage)
165 endif()
166 endif()
167