aboutsummaryrefslogtreecommitdiff
path: root/cmake/module
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/module')
-rw-r--r--cmake/module/ProcessConfigurations.cmake164
1 files changed, 164 insertions, 0 deletions
diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake
new file mode 100644
index 0000000000..80e842f59c
--- /dev/null
+++ b/cmake/module/ProcessConfigurations.cmake
@@ -0,0 +1,164 @@
+# Copyright (c) 2023-present The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or https://opensource.org/license/mit/.
+
+include_guard(GLOBAL)
+
+include(TryAppendCXXFlags)
+
+macro(normalize_string string)
+ string(REGEX REPLACE " +" " " ${string} "${${string}}")
+ string(STRIP "${${string}}" ${string})
+endmacro()
+
+function(are_flags_overridden flags_var result_var)
+ normalize_string(${flags_var})
+ normalize_string(${flags_var}_INIT)
+ if(${flags_var} STREQUAL ${flags_var}_INIT)
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ set(${result_var} TRUE PARENT_SCOPE)
+ endif()
+endfunction()
+
+
+# Removes duplicated flags. The relative order of flags is preserved.
+# If duplicates are encountered, only the last instance is preserved.
+function(deduplicate_flags flags)
+ separate_arguments(${flags})
+ list(REVERSE ${flags})
+ list(REMOVE_DUPLICATES ${flags})
+ list(REVERSE ${flags})
+ list(JOIN ${flags} " " result)
+ set(${flags} "${result}" PARENT_SCOPE)
+endfunction()
+
+
+function(get_all_configs output)
+ get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ set(all_configs ${CMAKE_CONFIGURATION_TYPES})
+ else()
+ get_property(all_configs CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS)
+ if(NOT all_configs)
+ # See https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#default-and-custom-configurations
+ set(all_configs Debug Release RelWithDebInfo MinSizeRel)
+ endif()
+ endif()
+ set(${output} "${all_configs}" PARENT_SCOPE)
+endfunction()
+
+
+#[=[
+Set the default build configuration.
+
+See: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations.
+
+On single-configuration generators, this function sets the CMAKE_BUILD_TYPE variable to
+the default build configuration, which can be overridden by the user at configure time if needed.
+
+On multi-configuration generators, this function rearranges the CMAKE_CONFIGURATION_TYPES list,
+ensuring that the default build configuration appears first while maintaining the order of the
+remaining configurations. The user can choose a build configuration at build time.
+]=]
+function(set_default_config config)
+ get_all_configs(all_configs)
+ if(NOT ${config} IN_LIST all_configs)
+ message(FATAL_ERROR "The default config is \"${config}\", but must be one of ${all_configs}.")
+ endif()
+
+ list(REMOVE_ITEM all_configs ${config})
+ list(PREPEND all_configs ${config})
+
+ get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ get_property(help_string CACHE CMAKE_CONFIGURATION_TYPES PROPERTY HELPSTRING)
+ set(CMAKE_CONFIGURATION_TYPES "${all_configs}" CACHE STRING "${help_string}" FORCE)
+ # Also see https://gitlab.kitware.com/cmake/cmake/-/issues/19512.
+ set(CMAKE_TRY_COMPILE_CONFIGURATION "${config}" PARENT_SCOPE)
+ else()
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
+ STRINGS "${all_configs}"
+ )
+ if(NOT CMAKE_BUILD_TYPE)
+ message(STATUS "Setting build type to \"${config}\" as none was specified")
+ get_property(help_string CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING)
+ set(CMAKE_BUILD_TYPE "${config}" CACHE STRING "${help_string}" FORCE)
+ endif()
+ set(CMAKE_TRY_COMPILE_CONFIGURATION "${CMAKE_BUILD_TYPE}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(remove_cxx_flag_from_all_configs flag)
+ get_all_configs(all_configs)
+ foreach(config IN LISTS all_configs)
+ string(TOUPPER "${config}" config_uppercase)
+ set(flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
+ separate_arguments(flags)
+ list(FILTER flags EXCLUDE REGEX "${flag}")
+ list(JOIN flags " " new_flags)
+ set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
+ set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}"
+ CACHE STRING
+ "Flags used by the CXX compiler during ${config_uppercase} builds."
+ FORCE
+ )
+ endforeach()
+endfunction()
+
+function(replace_cxx_flag_in_config config old_flag new_flag)
+ string(TOUPPER "${config}" config_uppercase)
+ string(REGEX REPLACE "(^| )${old_flag}( |$)" "\\1${new_flag}\\2" new_flags "${CMAKE_CXX_FLAGS_${config_uppercase}}")
+ set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE)
+ set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}"
+ CACHE STRING
+ "Flags used by the CXX compiler during ${config_uppercase} builds."
+ FORCE
+ )
+endfunction()
+
+set_default_config(RelWithDebInfo)
+
+# Redefine/adjust per-configuration flags.
+target_compile_definitions(core_interface_debug INTERFACE
+ DEBUG
+ DEBUG_LOCKORDER
+ DEBUG_LOCKCONTENTION
+ RPC_DOC_CHECK
+ ABORT_ON_FAILED_ASSUME
+)
+# We leave assertions on.
+if(MSVC)
+ remove_cxx_flag_from_all_configs(/DNDEBUG)
+else()
+ remove_cxx_flag_from_all_configs(-DNDEBUG)
+
+ # Adjust flags used by the CXX compiler during RELEASE builds.
+ # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.)
+ replace_cxx_flag_in_config(Release -O3 -O2)
+
+ are_flags_overridden(CMAKE_CXX_FLAGS_DEBUG cxx_flags_debug_overridden)
+ if(NOT cxx_flags_debug_overridden)
+ # Redefine flags used by the CXX compiler during DEBUG builds.
+ try_append_cxx_flags("-g3" RESULT_VAR compiler_supports_g3)
+ if(compiler_supports_g3)
+ replace_cxx_flag_in_config(Debug -g -g3)
+ endif()
+ unset(compiler_supports_g3)
+
+ try_append_cxx_flags("-ftrapv" RESULT_VAR compiler_supports_ftrapv)
+ if(compiler_supports_ftrapv)
+ string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-ftrapv ")
+ endif()
+ unset(compiler_supports_ftrapv)
+
+ string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-O0 ")
+
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}"
+ CACHE STRING
+ "Flags used by the CXX compiler during DEBUG builds."
+ FORCE
+ )
+ endif()
+ unset(cxx_flags_debug_overridden)
+endif()