From f365f4b369b7db2ae0da235fde8ab6f7479f6f71 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Wed, 19 Jul 2023 15:02:00 +0100 Subject: [PATCH] cmake: Redefine configuration flags --- CMakeLists.txt | 69 ++++++++----- cmake/module/ProcessConfigurations.cmake | 126 +++++++++++++++++++++++ 2 files changed, 171 insertions(+), 24 deletions(-) create mode 100644 cmake/module/ProcessConfigurations.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d789f8bc5cc18..2eb7fee021af4 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) @@ -163,6 +164,45 @@ 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") + 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) @@ -186,6 +226,9 @@ add_subdirectory(test) include(cmake/tests.cmake) +get_directory_property(definitions COMPILE_DEFINITIONS) +separate_by_configs(definitions) + message("\n") message("Configure summary") message("=================") @@ -213,9 +256,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}") list(JOIN DEPENDS_C_COMPILER_FLAGS " " depends_c_flags) string(STRIP "${CMAKE_C_FLAGS} ${depends_c_flags}" combined_c_flags) @@ -233,27 +274,7 @@ list(JOIN 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..613b4fee68301 --- /dev/null +++ b/cmake/module/ProcessConfigurations.cmake @@ -0,0 +1,126 @@ +# 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_by_configs options) + list(JOIN ${options} " " ${options}_ALL) + string(GENEX_STRIP "${${options}_ALL}" ${options}_ALL) + set(${options}_ALL "${${options}_ALL}" PARENT_SCOPE) + + get_all_configs(all_configs) + foreach(config IN LISTS all_configs) + string(REGEX MATCHALL "\\$<\\$[^\n]*>" match "${${options}}") + list(JOIN match " " match) + string(REPLACE "\$<\$:" "" match "${match}") + string(REPLACE ">" "" match "${match}") + string(TOUPPER "${config}" conf_upper) + set(${options}_${conf_upper} "${match}" 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()