diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bc124d9de805..60ad7fed8d42d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -198,11 +198,11 @@ add_library(core_interface INTERFACE) # include the warn_interface as subtree's warnings are not fixable # in our tree. add_library(core_base_interface INTERFACE) -add_library(core_depends_release_interface INTERFACE) -add_library(core_depends_debug_interface INTERFACE) +add_library(core_interface_relwithdebinfo INTERFACE) +add_library(core_interface_debug INTERFACE) target_link_libraries(core_base_interface INTERFACE - $<$:core_depends_release_interface> - $<$:core_depends_debug_interface> + $<$:core_interface_relwithdebinfo> + $<$:core_interface_debug> ) target_link_libraries(core_interface INTERFACE core_base_interface) @@ -419,7 +419,7 @@ include(ProcessConfigurations) set_default_config(RelWithDebInfo) # Redefine/adjust per-configuration flags. -target_compile_definitions(core_depends_debug_interface INTERFACE +target_compile_definitions(core_interface_debug INTERFACE DEBUG DEBUG_LOCKORDER DEBUG_LOCKCONTENTION @@ -564,8 +564,8 @@ else() endif() target_compile_definitions(core_base_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS}) -target_compile_definitions(core_depends_release_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO}) -target_compile_definitions(core_depends_debug_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_DEBUG}) +target_compile_definitions(core_interface_relwithdebinfo INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO}) +target_compile_definitions(core_interface_debug INTERFACE ${DEPENDS_COMPILE_DEFINITIONS_DEBUG}) # If {C,CXX,LD}FLAGS variables are defined during building depends and # configuring this build system, their content might be duplicated. @@ -591,12 +591,6 @@ add_maintenance_targets() add_windows_deploy_target() add_macos_deploy_target() - -include(GetTargetInterface) -get_target_interface(definitions core_interface COMPILE_DEFINITIONS) -get_target_interface(definitions_RELWITHDEBINFO core_depends_release_interface COMPILE_DEFINITIONS) -get_target_interface(definitions_DEBUG core_depends_debug_interface COMPILE_DEFINITIONS) - message("\n") message("Configure summary") message("=================") @@ -642,18 +636,10 @@ else() set(cross_status "FALSE") endif() message("Cross compiling ....................... ${cross_status}") -message("Preprocessor defined macros ........... ${definitions}") message("C compiler ............................ ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}, ${CMAKE_C_COMPILER}") -message("CFLAGS ................................ ${CMAKE_C_FLAGS} ${APPEND_CPPFLAGS} ${APPEND_CFLAGS}") message("C++ compiler .......................... ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}, ${CMAKE_CXX_COMPILER}") -message("CXXFLAGS .............................. ${CMAKE_CXX_FLAGS} ${APPEND_CPPFLAGS} ${APPEND_CXXFLAGS}") -get_target_interface(common_compile_options core_interface COMPILE_OPTIONS) -message("Common compile options ................ ${common_compile_options}") -get_target_interface(common_link_options core_interface LINK_OPTIONS) -message("Common link options ................... ${common_link_options}") -message("Linker flags for executables .......... ${CMAKE_EXE_LINKER_FLAGS} ${APPEND_LDFLAGS}") -message("Linker flags for shared libraries ..... ${CMAKE_SHARED_LINKER_FLAGS} ${APPEND_LDFLAGS}") -print_config_flags() +include(FlagsSummary) +flags_summary() message("Attempt to harden executables ......... ${ENABLE_HARDENING}") message("Treat compiler warnings as errors ..... ${WERROR}") message("Use ccache for compiling .............. ${WITH_CCACHE}") diff --git a/cmake/module/FlagsSummary.cmake b/cmake/module/FlagsSummary.cmake new file mode 100644 index 0000000000000..bd65b4ed4e7fd --- /dev/null +++ b/cmake/module/FlagsSummary.cmake @@ -0,0 +1,84 @@ +# Copyright (c) 2024-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) + +function(indent_message header content indent_num) + if(indent_num GREATER 0) + string(REPEAT " " ${indent_num} indentation) + string(REPEAT "\\." ${indent_num} dots) + string(REGEX REPLACE "${dots}$" "" header "${header}") + endif() + message("${indentation}${header} ${content}") +endfunction() + +function(print_flags_per_config config indent_num) + string(TOUPPER "${config}" config_uppercase) + + include(GetTargetInterface) + get_target_interface(definitions ${config} core_interface COMPILE_DEFINITIONS) + indent_message("Preprocessor defined macros ..........." "${definitions}" ${indent_num}) + + string(STRIP "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${config_uppercase}}" combined_c_flags) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + string(JOIN " " combined_c_flags ${combined_c_flags} ${CMAKE_C_COMPILE_OPTIONS_IPO}) + endif() + if(CMAKE_POSITION_INDEPENDENT_CODE) + string(JOIN " " combined_c_flags ${combined_c_flags} ${CMAKE_C_COMPILE_OPTIONS_PIC}) + endif() + get_target_interface(core_c_flags ${config} core_base_interface COMPILE_OPTIONS) + string(STRIP "${combined_c_flags} ${core_c_flags}" combined_c_flags) + string(STRIP "${combined_c_flags} ${APPEND_CPPFLAGS}" combined_c_flags) + string(STRIP "${combined_c_flags} ${APPEND_CFLAGS}" combined_c_flags) + indent_message("C flags ..............................." "${combined_c_flags}" ${indent_num}) + + string(STRIP "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_cxx_flags) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + string(JOIN " " combined_cxx_flags ${combined_cxx_flags} ${CMAKE_CXX_COMPILE_OPTIONS_IPO}) + endif() + if(CMAKE_POSITION_INDEPENDENT_CODE) + string(JOIN " " combined_cxx_flags ${combined_cxx_flags} ${CMAKE_CXX_COMPILE_OPTIONS_PIC}) + endif() + get_target_interface(core_cxx_flags ${config} core_interface COMPILE_OPTIONS) + string(STRIP "${combined_cxx_flags} ${core_cxx_flags}" combined_cxx_flags) + string(STRIP "${combined_cxx_flags} ${APPEND_CPPFLAGS}" combined_cxx_flags) + string(STRIP "${combined_cxx_flags} ${APPEND_CXXFLAGS}" combined_cxx_flags) + indent_message("C++ flags ............................." "${combined_cxx_flags}" ${indent_num}) + + string(STRIP "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_linker_flags) + if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) + string(JOIN " " combined_linker_flags ${combined_linker_flags} ${CMAKE_CXX_COMPILE_OPTIONS_IPO}) + endif() + string(STRIP "${combined_linker_flags} ${CMAKE_EXE_LINKER_FLAGS}" combined_linker_flags) + get_target_interface(common_link_options ${config} core_interface LINK_OPTIONS) + string(STRIP "${combined_linker_flags} ${common_link_options}" combined_linker_flags) + if(CMAKE_CXX_LINK_PIE_SUPPORTED) + string(JOIN " " combined_linker_flags ${combined_linker_flags} ${CMAKE_CXX_LINK_OPTIONS_PIE}) + endif() + string(STRIP "${combined_linker_flags} ${APPEND_LDFLAGS}" combined_linker_flags) + indent_message("Linker flags .........................." "${combined_linker_flags}" ${indent_num}) +endfunction() + +function(flags_summary) + get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi_config) + list(JOIN CMAKE_CONFIGURATION_TYPES ", " configs) + message("Available build configurations ........ ${configs}") + if(CMAKE_GENERATOR MATCHES "Visual Studio") + set(default_config "Debug") + else() + list(GET CMAKE_CONFIGURATION_TYPES 0 default_config) + endif() + message("Default build configuration ........... ${default_config}") + foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES) + message("") + message("'${config}' build configuration:") + print_flags_per_config(${config} 2) + endforeach() + message("") + else() + message("CMAKE_BUILD_TYPE ...................... ${CMAKE_BUILD_TYPE}") + print_flags_per_config(${CMAKE_BUILD_TYPE} 0) + endif() +endfunction() diff --git a/cmake/module/GetTargetInterface.cmake b/cmake/module/GetTargetInterface.cmake index f55354fd61b2a..1e455d456b419 100644 --- a/cmake/module/GetTargetInterface.cmake +++ b/cmake/module/GetTargetInterface.cmake @@ -4,11 +4,35 @@ include_guard(GLOBAL) -# Get target's interface properties recursively. -function(get_target_interface var target property) +# Evaluates config-specific generator expressions in a list. +# Recognizable patterns are: +# - $<$:[value]> +# - $<$>:[value]> +function(evaluate_generator_expressions list config) + set(input ${${list}}) + set(result) + foreach(token IN LISTS input) + if(token MATCHES "\\$<\\$]+)>:([^>]+)>") + if(CMAKE_MATCH_1 STREQUAL config) + list(APPEND result ${CMAKE_MATCH_2}) + endif() + elseif(token MATCHES "\\$<\\$]+)>>:([^>]+)>") + if(NOT CMAKE_MATCH_1 STREQUAL config) + list(APPEND result ${CMAKE_MATCH_2}) + endif() + else() + list(APPEND result ${token}) + endif() + endforeach() + set(${list} ${result} PARENT_SCOPE) +endfunction() + + +# Gets target's interface properties recursively. +function(get_target_interface var config target property) get_target_property(result ${target} INTERFACE_${property}) if(result) - string(GENEX_STRIP "${result}" result) + evaluate_generator_expressions(result "${config}") list(JOIN result " " result) else() set(result) @@ -16,9 +40,10 @@ function(get_target_interface var target property) get_target_property(dependencies ${target} INTERFACE_LINK_LIBRARIES) if(dependencies) + evaluate_generator_expressions(dependencies "${config}") foreach(dependency IN LISTS dependencies) if(TARGET ${dependency}) - get_target_interface(dep_result ${dependency} ${property}) + get_target_interface(dep_result "${config}" ${dependency} ${property}) string(STRIP "${result} ${dep_result}" result) endif() endforeach() diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake index d460e65fa3783..d5895497deb26 100644 --- a/cmake/module/ProcessConfigurations.cmake +++ b/cmake/module/ProcessConfigurations.cmake @@ -139,28 +139,3 @@ function(replace_cxx_flag_in_config config old_flag new_flag) FORCE ) 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()