From 48841c34d2e86a741ec9992b9704c0fa5973503c Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Fri, 2 Jun 2023 16:22:39 +0200 Subject: [PATCH] CMake: Unify CMAKE_BUILD_TYPE behavior on all platforms Before this change, we had the following behaviors. On platforms other than Windows-MSVC: - when no build type was specified, we defaulted to Release - when -developer-build was specified, we defaulted to Debug - regardless of platform, unless the option was explicitly specified, we never defaulted to -debug-and-release. On Windows-MSVC, we always defaulted to Debug. Which is inconsistent with the rules above. The difference happens because CMake always sets CMAKE_BUILD_TYPE to Debug during the first project() call when targeting the Windows-MSVC platform. We interpreted that as the user setting the build type, and thus we didn't want to override what the user specified. After this change, if we detect that it's cmake setting the build type, we assign a build type that follows the non-Windows-MSVC rules. This change unifies the behavior across all platforms. Adjusted the configure help with the new reality. Augments 33af62db3747bb6fcb7490ef2d2abc5bb53925b6 [ChangeLog][configure] When no explicit build type is specified, Windows will now default to building Release like the other platforms. Pick-to: 6.5 6.6 Change-Id: Id2bf269c51cf300ec09751ece2ad721869e0f90c Reviewed-by: Amir Masoud Abdol Reviewed-by: Joerg Bornemann --- cmake/QtAutoDetect.cmake | 7 +++++++ cmake/QtSetup.cmake | 14 +++++++++++++- config_help.txt | 14 +++++++++----- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake index a994fc5e55..cab40b5e64 100644 --- a/cmake/QtAutoDetect.cmake +++ b/cmake/QtAutoDetect.cmake @@ -478,6 +478,12 @@ function(qt_auto_detect_integrity) endif() endfunction() +# Save the build type before project() might set one. +# This allows us to determine if the user has set an explicit build type that we should use. +function(qt_auto_detect_cmake_build_type) + set(__qt_auto_detect_cmake_build_type_before_project_call "${CMAKE_BUILD_TYPE}" PARENT_SCOPE) +endfunction() + # Let CMake load our custom platform modules. # CMake-provided platform modules take precedence. if(NOT QT_AVOID_CUSTOM_PLATFORM_MODULES) @@ -497,3 +503,4 @@ qt_auto_detect_wasm() qt_auto_detect_win32_arm() qt_auto_detect_linux_x86() qt_auto_detect_integrity() +qt_auto_detect_cmake_build_type() diff --git a/cmake/QtSetup.cmake b/cmake/QtSetup.cmake index caf342214e..d8c4be7466 100644 --- a/cmake/QtSetup.cmake +++ b/cmake/QtSetup.cmake @@ -49,7 +49,19 @@ unset(QT_EXTRA_BUILD_INTERNALS_VARS) # Save the global property in a variable to make it available to feature conditions. get_property(QT_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) +# Try to detect if an explicit CMAKE_BUILD_TYPE was set by the user. +# CMake sets CMAKE_BUILD_TYPE_INIT to Debug on most Windows platforms and doesn't set +# anything for UNIXes. CMake assigns CMAKE_BUILD_TYPE_INIT to CMAKE_BUILD_TYPE during +# first project() if CMAKE_BUILD_TYPE has no previous value. +# We use extra information about the state of CMAKE_BUILD_TYPE before the first +# project() call that's set in QtAutodetect. +# STREQUAL check needs to have expanded variables because an undefined var is not equal +# to an empty defined var. +# See also qt_internal_force_set_cmake_build_type_conditionally which is used +# to set the build type when building other repos or tests. +if("${CMAKE_BUILD_TYPE}" STREQUAL "${CMAKE_BUILD_TYPE_INIT}" + AND NOT __qt_auto_detect_cmake_build_type_before_project_call + AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to '${_default_build_type}' as none was specified.") set(CMAKE_BUILD_TYPE "${_default_build_type}" CACHE STRING "Choose the type of build." FORCE) set_property(CACHE CMAKE_BUILD_TYPE diff --git a/config_help.txt b/config_help.txt index f35ec4cc24..7be06c7f9f 100644 --- a/config_help.txt +++ b/config_help.txt @@ -64,10 +64,13 @@ Build options: -cmake-file-api ...... Let CMake store build metadata for loading the build into an IDE. [no; yes if -developer-build] -no-guess-compiler ... Do not guess the compiler from the target mkspec. - -release ............. Build Qt with debugging turned off [yes] - -debug ............... Build Qt with debugging turned on [no] - -debug-and-release ... Build two versions of Qt, with and without - debugging turned on [yes] (Apple and Windows only) + -release ............. Build Qt with optimizations and without debug + symbols [yes] + Note that -developer-build implies -debug unless + -release is also explicitly specified + -debug ............... Build Qt without optimizations and with debug symbols + [no] + -debug-and-release ... Build two versions of Qt in one build tree [no] -optimize-debug ...... Enable debug-friendly optimizations in debug builds [auto] (Not supported with MSVC or Clang toolchains) -optimize-size ....... Optimize release builds for size instead of speed [no] @@ -80,7 +83,8 @@ Build options: sections. [auto for static builds, otherwise no] -force-asserts ....... Enable Q_ASSERT even in release builds [no] -developer-build ..... Compile and link Qt for developing Qt itself - (exports for auto-tests, extra checks, etc.) [no] + (exports for auto-tests, extra checks, implies + -no-prefix, etc.) [no] -shared .............. Build shared Qt libraries [yes] (no for UIKit) -static .............. Build static Qt libraries [no] (yes for UIKit)