summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2022-01-19 13:13:12 +0100
committerAlexandru Croitor <alexandru.croitor@qt.io>2022-01-21 14:24:09 +0100
commit33af62db3747bb6fcb7490ef2d2abc5bb53925b6 (patch)
tree9c6711f7a7d0c18660601dd74e0d47f62d9f6f28
parent0d5dc56554988edb87cb1575220a107c8a1f9cc4 (diff)
CMake: Support overriding CMAKE_BUILD_TYPE per-repo or test
One might want to build qtbase in Release, but qtsvg or some test in Debug mode. Before if qtbase was configured as Release, there was no way to override that. Now we try to detect whether a custom build type was specified to qt-cmake / qt-configure-module / qt-cmake-standalone-test / qt-internal-configure-tests Note mixing won't work on Windows due to different C/C++ runtimes. Also, now we don't force set a single build type when a multi config generator is used as well as one opts out via the QT_NO_FORCE_SET_CMAKE_BUILD_TYPE variable. Pick-to: 6.2 6.3 Change-Id: I6dc4325087ff7f905ad677d87b0267e2f3e4693f Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r--cmake/QtBuildInternalsExtra.cmake.in37
-rw-r--r--cmake/QtPostProcessHelpers.cmake17
-rw-r--r--cmake/qt.toolchain.cmake.in6
3 files changed, 53 insertions, 7 deletions
diff --git a/cmake/QtBuildInternalsExtra.cmake.in b/cmake/QtBuildInternalsExtra.cmake.in
index 37e6be8fbf..864e5badcc 100644
--- a/cmake/QtBuildInternalsExtra.cmake.in
+++ b/cmake/QtBuildInternalsExtra.cmake.in
@@ -105,5 +105,42 @@ if(NOT DEFINED QT_MAX_NEW_POLICY_CMAKE_VERSION)
set(QT_MAX_NEW_POLICY_CMAKE_VERSION "@max_new_policy_version@")
endif()
+get_property(__qt_internal_extras_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+
+# We want the same build type to be used when configuring all Qt repos or standalone
+# tests or single tests.
+# To do that, we need to force-set the CMAKE_BUILD_TYPE cache var because CMake itself
+# initializes it with the value of CMAKE_BUILD_TYPE_INIT at the start of project
+# configuration, so we need to override it.
+# Note the value of CMAKE_BUILD_TYPE_INIT is different based on the platform, most
+# Linux and macOS platforms will have it empty, but Windows platforms will have a value.
+#
+# We can't reliably differentiate between a value set on the command line by the user
+# and one set by CMake, so we use a few heuristics:
+# 1) When using a qt.toolchain.cmake file, we rely on the toolchain file to tell us
+# if a value was set by the user at initial configure time. On a 2nd run there will
+# always be a value in the cache, but at that point we've already set it to whatever it needs
+# to be.
+# 2) If a toolchain file is not used, we rely on the value of the CMake internal
+# CMAKE_BUILD_TYPE_INIT variable.
+# This won't work reliably on Windows where CMAKE_BUILD_TYPE_INIT is non-empty.
+#
+# Both cases won't handle an empty "" config set by the user, but we claim that's an
+# unsupported config when building Qt.
+#
+# Allow an opt out when QT_NO_FORCE_SET_CMAKE_BUILD_TYPE is set.
+# Finally, don't set the variable if a multi-config generator is used. This can happen
+# when qtbase is built with a single config, but a test is built with a multi-config generator.
+function(qt_internal_force_set_cmake_build_type_conditionally value)
+ # STREQUAL check needs to be expanded variables because an undefined var is not equal to an
+ # empty defined var.
+ if("${CMAKE_BUILD_TYPE}" STREQUAL "${CMAKE_BUILD_TYPE_INIT}"
+ AND NOT __qt_toolchain_cmake_build_type_before_project_call
+ AND NOT QT_NO_FORCE_SET_CMAKE_BUILD_TYPE
+ AND NOT __qt_internal_extras_is_multi_config)
+ set(CMAKE_BUILD_TYPE "${value}" CACHE STRING "Choose the type of build." FORCE)
+ endif()
+endfunction()
+
# Extra set of exported variables
@QT_EXTRA_BUILD_INTERNALS_VARS@
diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake
index a9b295a9d6..60a745c0f5 100644
--- a/cmake/QtPostProcessHelpers.cmake
+++ b/cmake/QtPostProcessHelpers.cmake
@@ -519,12 +519,12 @@ function(qt_generate_build_internals_extra_cmake_code)
${INSTALL_CMAKE_NAMESPACE}BuildInternals/QtBuildInternalsExtra.cmake)
if(CMAKE_BUILD_TYPE)
- # Need to force set, because CMake itself initializes a value for CMAKE_BUILD_TYPE
- # at the start of project configuration (with an empty value),
- # so we need to force override it.
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
- "set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\" CACHE STRING \"Choose the type of build.\" FORCE)\n")
-
+ "
+set(__qt_internal_initial_qt_cmake_build_type \"${CMAKE_BUILD_TYPE}\")
+qt_internal_force_set_cmake_build_type_conditionally(
+ \"\${__qt_internal_initial_qt_cmake_build_type}\")
+")
endif()
if(CMAKE_CONFIGURATION_TYPES)
string(APPEND multi_config_specific
@@ -546,11 +546,14 @@ function(qt_generate_build_internals_extra_cmake_code)
"\nset(QT_MULTI_CONFIG_FIRST_CONFIG \"${QT_MULTI_CONFIG_FIRST_CONFIG}\")\n")
endif()
# When building standalone tests against a multi-config Qt, we want to choose the first
- # configuration, rather than default to Debug.
+ # configuration, rather than use CMake's default value.
+ # In the case of Windows, we definitely don't it to default to Debug, because that causes
+ # issues in the CI.
if(multi_config_specific)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "
if(QT_BUILD_STANDALONE_TESTS)
- set(CMAKE_BUILD_TYPE \"\${QT_MULTI_CONFIG_FIRST_CONFIG}\" CACHE STRING \"Choose the type of build.\" FORCE)
+ qt_internal_force_set_cmake_build_type_conditionally(
+ \"\${QT_MULTI_CONFIG_FIRST_CONFIG}\")
endif()\n")
endif()
diff --git a/cmake/qt.toolchain.cmake.in b/cmake/qt.toolchain.cmake.in
index b8c5852dff..23f322824d 100644
--- a/cmake/qt.toolchain.cmake.in
+++ b/cmake/qt.toolchain.cmake.in
@@ -202,6 +202,12 @@ if(__qt_toolchain_host_path_required AND
"the location of your host Qt installation lib/cmake directory.")
endif()
+# Store initial build type (if any is specified) to be read by QtBuildInternals.cmake when building
+# a Qt repo, standalone tests or a single test.
+if(DEFINED CACHE{CMAKE_BUILD_TYPE})
+ set(__qt_toolchain_cmake_build_type_before_project_call "${CMAKE_BUILD_TYPE}")
+endif()
+
# Compile tests only see a restricted set of variables.
# All cache variables, this toolchain file uses, must be made available to project-based
# try_compile tests because this toolchain file will be included there too.