Skip to content

Commit

Permalink
cmake: Redefine configuration flags
Browse files Browse the repository at this point in the history
  • Loading branch information
hebasto committed Sep 2, 2023
1 parent 1a1dda5 commit a65da0d
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 24 deletions.
71 changes: 47 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ set(configure_warnings)
# It is intended to be a usage requirement for all other targets.
add_library(core INTERFACE)

include(TryAppendCXXFlags)
include(TryAppendLinkerFlag)

if(WIN32)
Expand Down Expand Up @@ -180,6 +181,47 @@ include(cmake/leveldb.cmake)
include(cmake/minisketch.cmake)
include(cmake/secp256k1.cmake)

include(ProcessConfigurations)
set_default_config(RelWithDebInfo)

# Redefine configuration flags.
target_compile_definitions(core INTERFACE
$<$<CONFIG:Debug>:DEBUG>
$<$<CONFIG:Debug>:DEBUG_LOCKORDER>
$<$<CONFIG:Debug>:DEBUG_LOCKCONTENTION>
$<$<CONFIG:Debug>:RPC_DOC_CHECK>
$<$<CONFIG:Debug>: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)
Expand All @@ -203,6 +245,9 @@ add_subdirectory(test)

include(cmake/tests.cmake)

get_target_property(definitions core INTERFACE_COMPILE_DEFINITIONS)
separate_by_configs(definitions)

message("\n")
message("Configure summary")
message("=================")
Expand Down Expand Up @@ -230,9 +275,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)
Expand All @@ -258,27 +301,7 @@ endif()
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")
Expand Down
136 changes: 136 additions & 0 deletions cmake/module/ProcessConfigurations.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# 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/.

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})
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 "\\$<\\$<CONFIG:${config}>[^\n]*>" match "${${options}}")
list(JOIN match " " match)
string(REPLACE "\$<\$<CONFIG:${config}>:" "" 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()

0 comments on commit a65da0d

Please sign in to comment.