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 Jul 12, 2023
1 parent d2b5b0b commit a2740c4
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 24 deletions.
72 changes: 48 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)

set(configure_warnings)

include(TryAppendCXXFlags)
include(TryAppendLinkerFlag)

if(WIN32)
Expand Down Expand Up @@ -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($<$<CONFIG:Debug>:DEBUG>)
add_compile_definitions($<$<CONFIG:Debug>:DEBUG_LOCKORDER>)
add_compile_definitions($<$<CONFIG:Debug>:DEBUG_LOCKCONTENTION>)
add_compile_definitions($<$<CONFIG:Debug>:RPC_DOC_CHECK>)
add_compile_definitions($<$<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")
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)
Expand All @@ -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("=================")
Expand Down Expand Up @@ -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}")
Expand All @@ -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")
Expand Down
127 changes: 127 additions & 0 deletions cmake/module/ProcessConfigurations.cmake
Original file line number Diff line number Diff line change
@@ -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 "\\$<\\$<CONFIG:${config}>[^\n]*>" ${var} "${${options}}")
string(REPLACE "\$<\$<CONFIG:${config}>:" "" ${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()

0 comments on commit a2740c4

Please sign in to comment.