From d7648a68e09e63938f1231689bd18ed81d685858 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Sun, 28 Jan 2024 14:25:48 +0000 Subject: [PATCH] [FIXUP] cmake: Fix flags handling 1. Use standard CMake's way to pass flags from depends to the main build system using CMAKE__FLAGS_INIT variables instead of custom DEPENDS__COMPILER_FLAGS ones. This guaranties using those flags during various checks at the configuration stage. 2. Setting flags is decoupled from setting compilers in the toolchain file. 3. Per-configuration flags are cached properly. 4. No longer needed to set -DCMAKE_BUILD_TYPE=None when building with depends. Fixes cross compilation for macOS. Allows the user to use {C,CXX}FLAGS environment variables for depends and the main build system without drawbacks/workarounds. --- CMakeLists.txt | 69 +++++++++++++++++------- cmake/module/ProcessConfigurations.cmake | 44 +++++++++++++++ depends/Makefile | 12 +++-- depends/toolchain.cmake.in | 31 ++++++++--- 4 files changed, 128 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7059147e40be..e35000fa4ff96 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -211,9 +211,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") endif() if(CMAKE_CROSSCOMPILING) - target_compile_definitions(core_interface INTERFACE ${DEPENDS_COMPILE_DEFINITIONS}) - target_compile_options(core_interface INTERFACE "$<$:${DEPENDS_C_COMPILER_FLAGS}>") - target_compile_options(core_interface INTERFACE "$<$:${DEPENDS_CXX_COMPILER_FLAGS}>") + target_compile_definitions(core_interface INTERFACE + "${DEPENDS_COMPILE_DEFINITIONS}" + "$<$:${DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO}>" + "$<$:${DEPENDS_COMPILE_DEFINITIONS_DEBUG}>" + ) endif() include(AddThreadsIfNeeded) @@ -270,7 +272,7 @@ include(cmake/secp256k1.cmake) include(ProcessConfigurations) set_default_config(RelWithDebInfo) -# Redefine configuration flags. +# Redefine/adjust per-configuration flags. target_compile_definitions(core_interface INTERFACE $<$:DEBUG> $<$:DEBUG_LOCKORDER> @@ -286,20 +288,53 @@ else() remove_c_flag_from_all_configs(-DNDEBUG) remove_cxx_flag_from_all_configs(-DNDEBUG) + # Adjust flags used by the C/CXX compiler during RELEASE builds. # 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_flags) - try_append_cxx_flags("-O0" VAR debug_flags) - try_append_cxx_flags("-g3" VAR debug_flags RESULT_VAR compiler_supports_g3) - if(NOT compiler_supports_g3) - try_append_cxx_flags("-g" VAR debug_flags) + include(ProcessConfigurations) + are_flags_overridden(CMAKE_CXX_FLAGS_DEBUG RESULT_VAR cxx_flags_debug_overridden) + if(NOT cxx_flags_debug_overridden) + # Redefine flags used by the CXX compiler during DEBUG builds. + try_append_cxx_flags("-g3" RESULT_VAR compiler_supports_g3) + if(compiler_supports_g3) + replace_cxx_flag_in_config(Debug -g -g3) + endif() + + try_append_cxx_flags("-ftrapv" RESULT_VAR compiler_supports_ftrapv) + if(compiler_supports_ftrapv) + string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-ftrapv ") + endif() + unset(compiler_supports_ftrapv) + + string(PREPEND CMAKE_CXX_FLAGS_DEBUG "-O0 ") + + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" + CACHE STRING + "Flags used by the CXX compiler during DEBUG builds." + FORCE + ) + endif() + unset(cxx_flags_debug_overridden) + + are_flags_overridden(CMAKE_C_FLAGS_DEBUG RESULT_VAR c_flags_debug_overridden) + if(NOT c_flags_debug_overridden) + # Redefine flags used by the C compiler during DEBUG builds. + if(compiler_supports_g3) + replace_c_flag_in_config(Debug -g -g3) + endif() + + string(PREPEND CMAKE_C_FLAGS_DEBUG "-O0 ") + + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" + CACHE STRING + "Flags used by the C compiler during DEBUG builds." + FORCE + ) endif() - set(CMAKE_C_FLAGS_DEBUG "${debug_flags}") - try_append_cxx_flags("-ftrapv" VAR debug_flags) - set(CMAKE_CXX_FLAGS_DEBUG "${debug_flags}") - unset(debug_flags) + unset(compiler_supports_g3) + unset(c_flags_debug_overridden) endif() include(cmake/optional_qt.cmake) @@ -429,13 +464,9 @@ endif() message("Cross compiling ....................... ${cross_status}") 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) -message("CFLAGS ................................ ${combined_c_flags}") +message("CFLAGS ................................ ${CMAKE_C_FLAGS}") message("C++ compiler .......................... ${CMAKE_CXX_COMPILER}") -list(JOIN DEPENDS_CXX_COMPILER_FLAGS " " depends_cxx_flags) -string(STRIP "${CMAKE_CXX_FLAGS} ${depends_cxx_flags}" combined_cxx_flags) -message("CXXFLAGS .............................. ${combined_cxx_flags}") +message("CXXFLAGS .............................. ${CMAKE_CXX_FLAGS}") include(GetTargetInterface) get_target_interface(common_compile_options core_interface COMPILE_OPTIONS) message("Common compile options ................ ${common_compile_options}") diff --git a/cmake/module/ProcessConfigurations.cmake b/cmake/module/ProcessConfigurations.cmake index c8cd0635220d9..84544a8e95462 100644 --- a/cmake/module/ProcessConfigurations.cmake +++ b/cmake/module/ProcessConfigurations.cmake @@ -2,6 +2,30 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/license/mit/. +include_guard(GLOBAL) + +macro(normalize_string string) + string(REGEX REPLACE " +" " " ${string} "${${string}}") + string(STRIP "${${string}}" ${string}) +endmacro() + +function(are_flags_overridden flags) + cmake_parse_arguments(PARSE_ARGV 1 + AFO # prefix + "" # options + "RESULT_VAR" # one_value_keywords + "" # multi_value_keywords + ) + normalize_string(${flags}) + normalize_string(${flags}_INIT) + if(${flags} STREQUAL ${flags}_INIT) + set(${AFO_RESULT_VAR} FALSE PARENT_SCOPE) + else() + set(${AFO_RESULT_VAR} TRUE PARENT_SCOPE) + endif() +endfunction() + + function(get_all_configs output) get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(is_multi_config) @@ -63,6 +87,11 @@ function(remove_c_flag_from_all_configs flag) list(FILTER flags EXCLUDE REGEX "${flag}") list(JOIN flags " " new_flags) set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) + set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" + CACHE STRING + "Flags used by the C compiler during ${config_uppercase} builds." + FORCE + ) endforeach() endfunction() @@ -75,6 +104,11 @@ function(remove_cxx_flag_from_all_configs flag) list(FILTER flags EXCLUDE REGEX "${flag}") list(JOIN flags " " new_flags) set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" PARENT_SCOPE) + set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" + CACHE STRING + "Flags used by the CXX compiler during ${config_uppercase} builds." + FORCE + ) endforeach() endfunction() @@ -82,12 +116,22 @@ 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) + set(CMAKE_C_FLAGS_${config_uppercase} "${new_flags}" + CACHE STRING + "Flags used by the C compiler during ${config_uppercase} builds." + FORCE + ) 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) + set(CMAKE_CXX_FLAGS_${config_uppercase} "${new_flags}" + CACHE STRING + "Flags used by the CXX compiler during ${config_uppercase} builds." + FORCE + ) endfunction() function(separate_by_configs options) diff --git a/depends/Makefile b/depends/Makefile index ab91b5b72a317..f75a1822c045a 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -273,9 +273,15 @@ $(host_prefix)/share/toolchain.cmake : toolchain.cmake.in $(host_prefix)/.stamp_ -e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \ -e 's|@OTOOL@|$(host_OTOOL)|' \ -e 's|@depends_prefix@|$(host_prefix)|' \ - -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ - -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \ - -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \ + -e 's|@CFLAGS@|$(strip $(host_CFLAGS))|' \ + -e 's|@CFLAGS_RELEASE@|$(strip $(host_release_CFLAGS))|' \ + -e 's|@CFLAGS_DEBUG@|$(strip $(host_debug_CFLAGS))|' \ + -e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS))|' \ + -e 's|@CXXFLAGS_RELEASE@|$(strip $(host_release_CXXFLAGS))|' \ + -e 's|@CXXFLAGS_DEBUG@|$(strip $(host_debug_CXXFLAGS))|' \ + -e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS))|' \ + -e 's|@CPPFLAGS_RELEASE@|$(strip $(host_release_CPPFLAGS))|' \ + -e 's|@CPPFLAGS_DEBUG@|$(strip $(host_debug_CPPFLAGS))|' \ -e 's|@no_qt@|$(NO_QT)|' \ -e 's|@no_qr@|$(NO_QR)|' \ -e 's|@no_zmq@|$(NO_ZMQ)|' \ diff --git a/depends/toolchain.cmake.in b/depends/toolchain.cmake.in index 81532f8bcc8a7..59940b984f6e5 100644 --- a/depends/toolchain.cmake.in +++ b/depends/toolchain.cmake.in @@ -32,7 +32,17 @@ function(split_compiler_launcher env_compiler launcher compiler) set(${compiler} ${${compiler}} PARENT_SCOPE) endfunction() -if(NOT CMAKE_C_COMPILER) +if(NOT DEFINED CMAKE_C_FLAGS_INIT) + set(CMAKE_C_FLAGS_INIT "@CFLAGS@") +endif() +if(NOT DEFINED CMAKE_C_FLAGS_RELWITHDEBINFO_INIT) + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "@CFLAGS_RELEASE@") +endif() +if(NOT DEFINED CMAKE_C_FLAGS_DEBUG_INIT) + set(CMAKE_C_FLAGS_DEBUG_INIT "@CFLAGS_DEBUG@") +endif() + +if(NOT DEFINED CMAKE_C_COMPILER) set(DEPENDS_C_COMPILER_WITH_LAUNCHER @CC@) split_compiler_launcher(DEPENDS_C_COMPILER_WITH_LAUNCHER CMAKE_C_COMPILER_LAUNCHER CMAKE_C_COMPILER) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) @@ -48,10 +58,19 @@ if(NOT CMAKE_C_COMPILER) string(PREPEND CMAKE_C_FLAGS_INIT "${mandatory_c_compiler_flags} ") unset(mandatory_c_compiler_flags) endif() - set(DEPENDS_C_COMPILER_FLAGS @CFLAGS@) endif() -if(NOT CMAKE_CXX_COMPILER) +if(NOT DEFINED CMAKE_CXX_FLAGS_INIT) + set(CMAKE_CXX_FLAGS_INIT "@CXXFLAGS@") +endif() +if(NOT DEFINED CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "@CXXFLAGS_RELEASE@") +endif() +if(NOT DEFINED CMAKE_CXX_FLAGS_DEBUG_INIT) + set(CMAKE_CXX_FLAGS_DEBUG_INIT "@CXXFLAGS_DEBUG@") +endif() + +if(NOT DEFINED CMAKE_CXX_COMPILER) set(DEPENDS_CXX_COMPILER_WITH_LAUNCHER @CXX@) split_compiler_launcher(DEPENDS_CXX_COMPILER_WITH_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER CMAKE_CXX_COMPILER) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) @@ -70,14 +89,14 @@ if(NOT CMAKE_CXX_COMPILER) string(PREPEND CMAKE_SHARED_LINKER_FLAGS_INIT "${mandatory_cxx_compiler_flags} ") unset(mandatory_cxx_compiler_flags) endif() - set(DEPENDS_CXX_COMPILER_FLAGS @CXXFLAGS@) - set(CMAKE_OBJCXX_COMPILER ${CMAKE_CXX_COMPILER}) set(CMAKE_OBJCXX_COMPILER_LAUNCHER ${CMAKE_CXX_COMPILER_LAUNCHER}) set(CMAKE_OBJCXX_LINKER_LAUNCHER ${CMAKE_CXX_LINKER_LAUNCHER}) endif() -set(DEPENDS_COMPILE_DEFINITIONS @CPPFLAGS@) +set(DEPENDS_COMPILE_DEFINITIONS "@CPPFLAGS@") +set(DEPENDS_COMPILE_DEFINITIONS_RELWITHDEBINFO "@CPPFLAGS_RELEASE@") +set(DEPENDS_COMPILE_DEFINITIONS_DEBUG "@CPPFLAGS_DEBUG@") set(CMAKE_AR "@AR@") set(CMAKE_RANLIB "@RANLIB@")