Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIXUP] cmake: Rework compile/link flags summary #93

Merged
merged 3 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 12 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
$<$<CONFIG:RelWithDebInfo>:core_depends_release_interface>
$<$<CONFIG:Debug>:core_depends_debug_interface>
$<$<CONFIG:RelWithDebInfo>:core_interface_relwithdebinfo>
$<$<CONFIG:Debug>:core_interface_debug>
)
target_link_libraries(core_interface INTERFACE core_base_interface)

Expand Down Expand Up @@ -321,13 +321,11 @@ endif()
include(AddThreadsIfNeeded)
add_threads_if_needed()

add_library(sanitizing_interface INTERFACE)
target_link_libraries(core_base_interface INTERFACE sanitizing_interface)
if(SANITIZERS)
# First check if the compiler accepts flags. If an incompatible pair like
# -fsanitize=address,thread is used here, this check will fail. This will also
# fail if a bad argument is passed, e.g. -fsanitize=undfeined
try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET sanitizing_interface
try_append_cxx_flags("-fsanitize=${SANITIZERS}" TARGET core_base_interface
RESULT_VAR cxx_supports_sanitizers
SKIP_LINK
)
Expand All @@ -354,7 +352,7 @@ if(SANITIZERS)
message(FATAL_ERROR "Linker did not accept requested flags, you are missing required libraries.")
endif()
endif()
target_link_options(sanitizing_interface INTERFACE ${SANITIZER_LDFLAGS})
target_link_options(core_base_interface INTERFACE ${SANITIZER_LDFLAGS})

include(AddBoostIfNeeded)
add_boost_if_needed()
Expand Down Expand Up @@ -421,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
Expand Down Expand Up @@ -513,7 +511,7 @@ try_append_cxx_flags("-fstack-reuse=none" TARGET core_base_interface)

if(ENABLE_HARDENING)
add_library(hardening_interface INTERFACE)
target_link_libraries(core_base_interface INTERFACE hardening_interface)
target_link_libraries(core_interface INTERFACE hardening_interface)
if(MSVC)
try_append_linker_flag("/DYNAMICBASE" TARGET hardening_interface)
try_append_linker_flag("/HIGHENTROPYVA" TARGET hardening_interface)
Expand Down Expand Up @@ -582,8 +580,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.
Expand All @@ -609,12 +607,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("=================")
Expand Down Expand Up @@ -660,18 +652,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}")
Expand Down
5 changes: 4 additions & 1 deletion cmake/crc32c.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ target_compile_definitions(crc32c_common INTERFACE
HAVE_STRONG_GETAUXVAL=$<BOOL:${HAVE_STRONG_GETAUXVAL}>
BYTE_ORDER_BIG_ENDIAN=$<STREQUAL:${CMAKE_CXX_BYTE_ORDER},BIG_ENDIAN>
)
target_link_libraries(crc32c_common INTERFACE core_base_interface)
target_link_libraries(crc32c_common INTERFACE
core_base_interface
hardening_interface
)

add_library(crc32c STATIC EXCLUDE_FROM_ALL
${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c.cc
Expand Down
1 change: 1 addition & 0 deletions cmake/leveldb.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ endif()

target_link_libraries(leveldb PRIVATE
core_base_interface
hardening_interface
nowarn_leveldb_interface
crc32c
)
Expand Down
2 changes: 2 additions & 0 deletions cmake/minisketch.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ if(HAVE_CLMUL)
target_link_libraries(minisketch_clmul
PRIVATE
core_base_interface
hardening_interface
minisketch_common
)
set_target_properties(minisketch_clmul PROPERTIES
Expand Down Expand Up @@ -82,6 +83,7 @@ target_include_directories(minisketch
target_link_libraries(minisketch
PRIVATE
core_base_interface
hardening_interface
minisketch_common
$<TARGET_NAME_IF_EXISTS:minisketch_clmul>
)
Expand Down
84 changes: 84 additions & 0 deletions cmake/module/FlagsSummary.cmake
Original file line number Diff line number Diff line change
@@ -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} tail)
string(REGEX REPLACE "${tail}$" "" header "${header}")
endif()
message("${indentation}${header} ${content}")
endfunction()

# Print tools' flags on best-effort. Include the abstracted
# CMake flags that we touch ourselves.
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)
string(STRIP "${combined_c_flags} ${CMAKE_C${CMAKE_C_STANDARD}_STANDARD_COMPILE_OPTION}" combined_c_flags)
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 compiler flags ......................" "${combined_c_flags}" ${indent_num})

string(STRIP "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_cxx_flags)
string(STRIP "${combined_cxx_flags} ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION}" combined_cxx_flags)
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++ compiler flags ...................." "${combined_cxx_flags}" ${indent_num})

string(STRIP "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${config_uppercase}}" combined_linker_flags)
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()
else()
message("CMAKE_BUILD_TYPE ...................... ${CMAKE_BUILD_TYPE}")
print_flags_per_config(${CMAKE_BUILD_TYPE} 0)
endif()
message("")
message([=[
NOTE: The summary above may not exactly match the final applied build flags
if any additional CMAKE_* or environment variables have been modified.
To see the exact flags applied, build with the --verbose option.
]=])
endfunction()
33 changes: 29 additions & 4 deletions cmake/module/GetTargetInterface.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,46 @@

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:
# - $<$<CONFIG:[config]>:[value]>
# - $<$<NOT:$<CONFIG:[config]>>:[value]>
function(evaluate_generator_expressions list config)
set(input ${${list}})
set(result)
foreach(token IN LISTS input)
if(token MATCHES "\\$<\\$<CONFIG:([^>]+)>:([^>]+)>")
if(CMAKE_MATCH_1 STREQUAL config)
list(APPEND result ${CMAKE_MATCH_2})
endif()
elseif(token MATCHES "\\$<\\$<NOT:\\$<CONFIG:([^>]+)>>:([^>]+)>")
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)
endif()

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()
Expand Down
25 changes: 0 additions & 25 deletions cmake/module/ProcessConfigurations.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Loading