From add16ca1ef55e10615fddfe1b14c343f81d1ebb5 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Fri, 20 Jan 2023 14:13:37 +0000 Subject: [PATCH] cmake: Redefine configuration flags --- CMakeLists.txt | 72 ++++++++----- cmake/module/ProcessConfigurations.cmake | 127 +++++++++++++++++++++++ 2 files changed, 175 insertions(+), 24 deletions(-) create mode 100644 cmake/module/ProcessConfigurations.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 209931d70d57e..697b8ee4b2ce0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,7 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(configure_warnings) +include(TryAppendCXXFlags) include(TryAppendLinkerFlag) if(WIN32) @@ -158,6 +159,48 @@ include(cmake/leveldb.cmake) include(cmake/minisketch.cmake) include(cmake/secp256k1.cmake) +include(ProcessConfigurations) +set_default_config(RelWithDebInfo) + +# Redefine configuration flags. +add_compile_definitions($<$:DEBUG>) +add_compile_definitions($<$:DEBUG_LOCKORDER>) +add_compile_definitions($<$:DEBUG_LOCKCONTENTION>) +add_compile_definitions($<$:RPC_DOC_CHECK>) +add_compile_definitions($<$:ABORT_ON_FAILED_ASSUME>) +# We leave assertions on. +if(MSVC) + remove_c_flag_from_all_configs(/DNDEBUG) + remove_cxx_flag_from_all_configs(/DNDEBUG) +else() + remove_c_flag_from_all_configs(-DNDEBUG) + remove_cxx_flag_from_all_configs(-DNDEBUG) + + # Prefer -O2 optimization level. (-O3 is CMake's default for Release for many compilers.) + replace_c_flag_in_config(Release -O3 -O2) + replace_cxx_flag_in_config(Release -O3 -O2) + + set(debug_c_flags "") + set(debug_cxx_flags "") + try_append_cxx_flags(debug_cxx_flags "-O0" RESULT_VAR compiler_supports_O0) + if(compiler_supports_O0) + string(STRIP "${debug_c_flags} -O0" debug_c_flags) + endif() + try_append_cxx_flags(debug_cxx_flags "-g3" RESULT_VAR compiler_supports_g3) + if(compiler_supports_g3) + string(STRIP "${debug_c_flags} -g3" debug_c_flags) + else() + try_append_cxx_flags(debug_cxx_flags "-g") + string(STRIP "${debug_c_flags} -g" debug_c_flags) + endif() + try_append_cxx_flags(debug_cxx_flags "-ftrapv") + if(MINGW) + try_append_cxx_flags(debug_cxx_flags "-Wa,-mbig-obj") + endif() + set(CMAKE_C_FLAGS_DEBUG "${debug_c_flags}") + set(CMAKE_CXX_FLAGS_DEBUG "${debug_cxx_flags}") +endif() + include(cmake/optional.cmake) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.14) @@ -181,6 +224,9 @@ add_subdirectory(test) include(cmake/tests.cmake) +get_directory_property(definitions COMPILE_DEFINITIONS) +separate_configs(definitions) + message("\n") message("Configure summary") message("=================") @@ -208,9 +254,7 @@ else() set(cross_status "FALSE") endif() message("Cross compiling ....................... ${cross_status}") -get_directory_property(definitions COMPILE_DEFINITIONS) -string(REPLACE ";" " " definitions "${definitions}") -message("Preprocessor defined macros ........... ${definitions}") +message("Preprocessor defined macros ........... ${definitions_ALL}") message("C compiler ............................ ${CMAKE_C_COMPILER}") message("CFLAGS ................................ ${CMAKE_C_FLAGS}") message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}") @@ -223,27 +267,7 @@ string(REPLACE ";" " " common_link_options "${common_link_options}") message("Common link options ................... ${common_link_options}") message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS}") message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS}") -if(DEFINED CMAKE_BUILD_TYPE) - message("Build type:") - message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") - string(TOUPPER "${CMAKE_BUILD_TYPE}" build_type) - message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${build_type}}") - message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${build_type}}") - message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${build_type}}") - message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${build_type}}") -else() - message("Available configurations .............. ${CMAKE_CONFIGURATION_TYPES}") - message("Debug configuration:") - message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_DEBUG}") - message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_DEBUG}") - message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_DEBUG}") - message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") - message("Release configuration:") - message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_RELEASE}") - message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_RELEASE}") - message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_RELEASE}") - message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") -endif() +print_config_flags() message("Use assembly routines ................. ${ASM}") message("Use ccache for compiling .............. ${CCACHE}") message("\n") diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake new file mode 100644 index 0000000000000..c64e4df026a0e --- /dev/null +++ b/cmake/module/ProcessConfigurations.cmake @@ -0,0 +1,127 @@ +# Copyright (c) 2023 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +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() + +# When used with multi-configuration generators, this function rearranges +# the CMAKE_CONFIGURATION_TYPES list, ensuring that the default configuration type +# appears first while maintaining the order of the remaining configuration types. +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}) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) + list(PREPEND all_configs ${config}) + else() + set(all_configs ${config} ${all_configs}) + endif() + + 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) + 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() + endif() +endfunction() + +function(remove_c_flag_from_all_configs flag) + get_all_configs(all_configs) + foreach(config IN LISTS all_configs) + string(TOUPPER "${config}" config_uppercase) + set(flags "${CMAKE_C_FLAGS_${config_uppercase}}") + separate_arguments(flags) + list(FILTER flags EXCLUDE REGEX "${flag}") + list(JOIN flags " " new_flags) + set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) + endforeach() +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) + endforeach() +endfunction() + +function(replace_c_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_C_FLAGS_${config_uppercase}}") + set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) +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) +endfunction() + +function(separate_configs options) + string(GENEX_STRIP "${${options}}" ${options}_ALL) + string(REPLACE ";" " " ${options}_ALL "${${options}_ALL}") + set(${options}_ALL "${${options}_ALL}" PARENT_SCOPE) + + get_all_configs(all_configs) + foreach(config IN LISTS all_configs) + string(TOUPPER "${config}" conf_upper) + set(var ${options}_${conf_upper}) + string(REGEX MATCHALL "\\$<\\$[^\n]*>" ${var} "${${options}}") + string(REPLACE "\$<\$:" "" ${var} "${${var}}") + string(REPLACE ">" "" ${var} "${${var}}") + string(REPLACE ";" " " ${var} "${${var}}") + set(${var} "${${var}}" PARENT_SCOPE) + endforeach() +endfunction() + +function(print_config_flags) + macro(print_flags config) + string(TOUPPER "${config}" config_uppercase) + message(" - Preprocessor defined macros ........ ${definitions_${config_uppercase}}") + message(" - CFLAGS ............................. ${CMAKE_C_FLAGS_${config_uppercase}}") + message(" - CXXFLAGS ........................... ${CMAKE_CXX_FLAGS_${config_uppercase}}") + message(" - LDFLAGS for executables ............ ${CMAKE_EXE_LINKER_FLAGS_${config_uppercase}}") + message(" - LDFLAGS for shared libraries ....... ${CMAKE_SHARED_LINKER_FLAGS_${config_uppercase}}") + endmacro() + + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + list(JOIN CMAKE_CONFIGURATION_TYPES " " configs) + message("Available build types (configurations) ${configs}") + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + message("'${config}' build type (configuration):") + print_flags(${config}) + endforeach() + else() + message("Build type (configuration):") + message(" - CMAKE_BUILD_TYPE ................... ${CMAKE_BUILD_TYPE}") + print_flags(${CMAKE_BUILD_TYPE}) + endif() +endfunction()