ProcessConfigurations.cmake
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()