summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Scott <[email protected]>2020-11-30 18:46:49 +1100
committerCraig Scott <[email protected]>2020-12-07 13:22:57 +1100
commit3859f15ec9fd333089e6eb1152a76592cd5f83c0 (patch)
treeab1a3efb43ae5fac1dff489ce8832fd8e20bf021
parentec02de374da3f796a2155b45779be222a90be2cd (diff)
CMake: Enable NEW policies by CMake version with a global default
When a CMake release introduces a new policy that affects most Qt modules, it may be appropriate to make each module aware of that newer CMake version and use the NEW policy without raising the minimum CMake version requirement. To reduce the churn associated with making that change across all Qt modules individually, this change allows it to be updated in a central place (qtbase), but in a way that allows a Qt module to override it in its own .cmake.conf file if required (e.g. to address the issues identified by policy warnings at a later time). The policies are modified at the start of the call to qt_build_repo_begin(). For commands defined by the qtbase module, qtbase needs to be in control of the policy settings at the point where those commands are defined. The above mechanism should not affect the policy settings for these commands, so the various *Config.cmake.in files must not specify policy ranges in a way that a Qt module's .cmake.conf file could influence. Starting with CMake 3.12, policies can be specified as a version range with the cmake_minimum_required() and cmake_policy() commands. All policies introduced in CMake versions up to the upper limit of that range will be set to NEW. The actual version of CMake being used only has to be at least the lower limit of the specified version range. This change uses cmake_minimum_required() rather than cmake_policy() due to the latter not halting further processing upon failure. See the following: https://gitlab.kitware.com/cmake/cmake/-/issues/21557 Task-number: QTBUG-88700 Pick-to: 6.0 Change-Id: I0a1f2611dd629f847a18186394f500d7f52753bc Reviewed-by: Alexandru Croitor <[email protected]>
-rw-r--r--.cmake.conf14
-rw-r--r--CMakeLists.txt20
-rw-r--r--cmake/Qt3rdPartyLibraryConfig.cmake.in2
-rw-r--r--cmake/Qt3rdPartyLibraryHelpers.cmake2
-rw-r--r--cmake/QtBaseGlobalTargets.cmake2
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsConfig.cmake6
-rw-r--r--cmake/QtCMakeVersionHelpers.cmake42
-rw-r--r--cmake/QtConfig.cmake.in5
-rw-r--r--cmake/QtModuleConfig.cmake.in4
-rw-r--r--cmake/QtModuleHelpers.cmake2
-rw-r--r--cmake/QtModuleToolsConfig.cmake.in2
-rw-r--r--cmake/QtPluginConfig.cmake.in2
-rw-r--r--cmake/QtPluginHelpers.cmake3
-rw-r--r--cmake/QtPostProcessHelpers.cmake15
-rw-r--r--cmake/QtToolHelpers.cmake2
15 files changed, 98 insertions, 25 deletions
diff --git a/.cmake.conf b/.cmake.conf
index b8e9ae67357..2680c4a33d7 100644
--- a/.cmake.conf
+++ b/.cmake.conf
@@ -1,2 +1,16 @@
set(QT_REPO_MODULE_VERSION "6.0.0")
+
+# Minimum requirement for building Qt
set(QT_MIN_SUPPORTED_CMAKE_VERSION "3.18")
+
+# Policy settings for commands defined by qtbase. These will also be injected
+# into the top level policy scope of each Qt module when building Qt so that
+# modules have the same policy settings as qtbase by default. They can be
+# overridden by individual Qt modules in their own .cmake.conf files if needed.
+#
+# NOTE: These two values are also hard-coded in QtBuildInternalsConfig.cmake
+# because that file is used in-place by a superbuild, so there is no
+# opportunity for substituting the values from here. Keep both locations
+# in sync.
+set(QT_MIN_NEW_POLICY_CMAKE_VERSION "3.14")
+set(QT_MAX_NEW_POLICY_CMAKE_VERSION "3.19")
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 53daa1721a6..3557cad293c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,14 +1,16 @@
# special case skip regeneration
-# Get the repo version and the minimum CMake version.
-include("${CMAKE_CURRENT_SOURCE_DIR}/.cmake.conf")
-
-if(NOT QT_SUPER_BUILD)
- include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtCMakeVersionHelpers.cmake")
- qt_internal_check_for_suitable_cmake_version()
- qt_internal_get_computed_minimum_cmake_version(__qt_minimum_cmake_version)
- cmake_minimum_required(VERSION ${__qt_minimum_cmake_version})
-endif()
+# Need an explicit call at the top level. This is the absolute minimum version
+# needed to configure the project with any combination of enabled features.
+# The call to qt_build_repo_begin() will upgrade policies further.
+cmake_minimum_required(VERSION 3.16)
+
+# Get the repo version and CMake policy details
+include(.cmake.conf)
+
+# Early check to reduce chance of warning being lost in the output
+include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtCMakeVersionHelpers.cmake")
+qt_internal_check_for_suitable_cmake_version()
# Run auto detection routines, but not when doing standalone tests. In that case, the detection
# results are taken from either QtBuildInternals or the qt.toolchain.cmake file. Also, inhibit
diff --git a/cmake/Qt3rdPartyLibraryConfig.cmake.in b/cmake/Qt3rdPartyLibraryConfig.cmake.in
index f0489b7fe15..3f59d212d8c 100644
--- a/cmake/Qt3rdPartyLibraryConfig.cmake.in
+++ b/cmake/Qt3rdPartyLibraryConfig.cmake.in
@@ -1,5 +1,7 @@
@PACKAGE_INIT@
+cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
+
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/cmake/Qt3rdPartyLibraryHelpers.cmake b/cmake/Qt3rdPartyLibraryHelpers.cmake
index 13e67f35245..f91a7628e7a 100644
--- a/cmake/Qt3rdPartyLibraryHelpers.cmake
+++ b/cmake/Qt3rdPartyLibraryHelpers.cmake
@@ -201,6 +201,8 @@ function(qt_internal_add_3rdparty_library target)
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
set(export_name "${INSTALL_CMAKE_NAMESPACE}${target}Targets")
+ qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
+ qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
configure_package_config_file(
"${QT_CMAKE_DIR}/Qt3rdPartyLibraryConfig.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 8c1c9d2bd06..03f4b4d76a2 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -19,6 +19,8 @@ file(RELATIVE_PATH
${__qt_bin_dir_absolute} ${__GlobalConfig_install_dir_absolute})
# Generate and install Qt6 config file.
+qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
+qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/QtConfig.cmake.in"
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}Config.cmake"
diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
index d930e2a9636..7aebfb04db9 100644
--- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
+++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
@@ -1,6 +1,5 @@
-if (CMAKE_VERSION VERSION_LESS 3.1.0)
- message(FATAL_ERROR "Qt requires at least CMake version 3.1.0")
-endif()
+# These values should be kept in sync with those in qtbase/.cmake.conf
+cmake_minimum_required(VERSION 3.14...3.19)
######################################
#
@@ -168,6 +167,7 @@ macro(qt_build_internals_set_up_private_api)
# Check for the minimum CMake version.
include(QtCMakeVersionHelpers)
qt_internal_require_suitable_cmake_version()
+ qt_internal_upgrade_cmake_policies()
# Qt specific setup common for all modules:
include(QtSetup)
diff --git a/cmake/QtCMakeVersionHelpers.cmake b/cmake/QtCMakeVersionHelpers.cmake
index 274af52cd1b..aca1c50206e 100644
--- a/cmake/QtCMakeVersionHelpers.cmake
+++ b/cmake/QtCMakeVersionHelpers.cmake
@@ -27,11 +27,36 @@ function(qt_internal_get_computed_minimum_cmake_version out_var)
set(${out_var} "${computed_min_version}" PARENT_SCOPE)
endfunction()
+# Returns the oldest CMake version for which NEW policies should be enabled.
+# It can be older than the minimum supported or computed CMake version, as it
+# is only used for policy settings. The currently running CMake must not be
+# older than this version though (doing so will result in an error).
+function(qt_internal_get_min_new_policy_cmake_version out_var)
+ # QT_MIN_NEW_POLICY_CMAKE_VERSION is set either in .cmake.conf or in
+ # QtBuildInternalsExtras.cmake when building a child repo.
+ set(lower_version "${QT_MIN_NEW_POLICY_CMAKE_VERSION}")
+ set(${out_var} "${lower_version}" PARENT_SCOPE)
+endfunction()
+
+# Returns the latest CMake version for which NEW policies should be enabled.
+# This cannot be less than the minimum CMake policy version or we will end up
+# specifying a version range with the max less than the min.
+function(qt_internal_get_max_new_policy_cmake_version out_var)
+ # QT_MAX_NEW_POLICY_CMAKE_VERSION is set either in .cmake.conf or in
+ # QtBuildInternalsExtras.cmake when building a child repo.
+ set(upper_version "${QT_MAX_NEW_POLICY_CMAKE_VERSION}")
+ qt_internal_get_min_new_policy_cmake_version(lower_version)
+ if(upper_version VERSION_LESS lower_version)
+ set(upper_version ${lower_version})
+ endif()
+ set(${out_var} "${upper_version}" PARENT_SCOPE)
+endfunction()
+
function(qt_internal_check_for_suitable_cmake_version)
# Implementation note.
- # The very first cmake_required_version() call can't be placed in an include()d file.
+ # The very first cmake_minimum_required() call can't be placed in an include()d file.
# It causes CMake to fail to configure with 'No cmake_minimum_required command is present.'
- # The first cmake_required_version() must be called directly in the top-level CMakeLists.txt
+ # The first cmake_minimum_required() must be called directly in the top-level CMakeLists.txt
# file.
# That's why this function only handles output of warnings, and doesn't try to set the required
# version.
@@ -41,7 +66,7 @@ endfunction()
# Function to be used in child repos like qtsvg to require a minimum CMake version.
#
-# Such repos don't have the required version information at cmake_required_version() time, that's
+# Such repos don't have the required version information at cmake_minimum_required() time, that's
# why we provide this function to be called at a time when the info is available.
function(qt_internal_require_suitable_cmake_version)
qt_internal_check_for_suitable_cmake_version()
@@ -100,3 +125,14 @@ function(qt_internal_warn_about_unsuitable_cmake_versions)
endif()
endforeach()
endfunction()
+
+# Functions don't have their own policy scope, so the policy settings modified
+# here will be those of the caller's policy scope. Note that these settings
+# will only apply to functions and macros defined after this function is called,
+# but not to any that are already defined. Ordinary CMake code not inside a
+# function or macro will be affected by these policy settings too.
+function(qt_internal_upgrade_cmake_policies)
+ qt_internal_get_computed_minimum_cmake_version(lower_version)
+ qt_internal_get_max_new_policy_cmake_version(upper_version)
+ cmake_minimum_required(VERSION ${lower_version}...${upper_version})
+endfunction()
diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in
index 8a8f73b1555..a43583e4cb6 100644
--- a/cmake/QtConfig.cmake.in
+++ b/cmake/QtConfig.cmake.in
@@ -1,9 +1,6 @@
@PACKAGE_INIT@
-# Slightly amended version of ./src/corelib/Qt6Config.cmake.in
-if (CMAKE_VERSION VERSION_LESS 3.14)
- message(FATAL_ERROR "Qt requires at least CMake version 3.14")
-endif()
+cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
get_filename_component(_qt_cmake_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
set(_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
diff --git a/cmake/QtModuleConfig.cmake.in b/cmake/QtModuleConfig.cmake.in
index 96e68e0cafb..ecd5e04e634 100644
--- a/cmake/QtModuleConfig.cmake.in
+++ b/cmake/QtModuleConfig.cmake.in
@@ -1,5 +1,7 @@
@PACKAGE_INIT@
+cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
+
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
@@ -108,7 +110,7 @@ if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
endif()
-# Load Module's BuildIntenals should any exist
+# Load Module's BuildInternals should any exist
if (@INSTALL_CMAKE_NAMESPACE@BuildInternals_DIR AND
EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@[email protected]")
diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake
index 2c03917f328..cc353289a40 100644
--- a/cmake/QtModuleHelpers.cmake
+++ b/cmake/QtModuleHelpers.cmake
@@ -492,6 +492,8 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
endif()
qt6_extract_metatypes(${target} ${args})
endif()
+ qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
+ qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
configure_package_config_file(
"${QT_CMAKE_DIR}/QtModuleConfig.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
diff --git a/cmake/QtModuleToolsConfig.cmake.in b/cmake/QtModuleToolsConfig.cmake.in
index a714a7b7f2e..fdbc8536464 100644
--- a/cmake/QtModuleToolsConfig.cmake.in
+++ b/cmake/QtModuleToolsConfig.cmake.in
@@ -1,5 +1,7 @@
@PACKAGE_INIT@
+cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
+
include(CMakeFindDependencyMacro)
if (NOT QT_NO_CREATE_TARGETS)
diff --git a/cmake/QtPluginConfig.cmake.in b/cmake/QtPluginConfig.cmake.in
index 03314d3d40f..25ad75ce718 100644
--- a/cmake/QtPluginConfig.cmake.in
+++ b/cmake/QtPluginConfig.cmake.in
@@ -2,6 +2,8 @@ include_guard(DIRECTORY)
@PACKAGE_INIT@
+cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@)
+
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake
index 4b8a9c1beb2..5cb2ece4a01 100644
--- a/cmake/QtPluginHelpers.cmake
+++ b/cmake/QtPluginHelpers.cmake
@@ -241,6 +241,9 @@ function(qt_internal_add_plugin target)
TARGETS ${target}
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
CONFIG_INSTALL_DIR "${config_install_dir}")
+
+ qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
+ qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
configure_package_config_file(
"${QT_CMAKE_DIR}/QtPluginConfig.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"
diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake
index 09a5b964792..37213f13a53 100644
--- a/cmake/QtPostProcessHelpers.cmake
+++ b/cmake/QtPostProcessHelpers.cmake
@@ -549,14 +549,19 @@ endif()\n")
"set(QT_QPA_DEFAULT_PLATFORM \"${QT_QPA_DEFAULT_PLATFORM}\" CACHE STRING \"\")\n")
endif()
- # Save the supported and computed minimum CMake versions to ensure the same minimum is
- # checked for when building other child repos (qtsvg, etc).
+ # Save minimum and policy-related CMake versions to ensure the same minimum is
+ # checked for when building other child repos (qtsvg, etc) and the policy settings
+ # will be consistent unless the child repos explicitly override them.
qt_internal_get_qt_supported_minimum_cmake_version(min_supported_version)
qt_internal_get_computed_minimum_cmake_version(computed_min_version)
+ qt_internal_get_min_new_policy_cmake_version(lower_policy_version)
+ qt_internal_get_max_new_policy_cmake_version(upper_policy_version)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
- "set(QT_MIN_SUPPORTED_CMAKE_VERSION \"${min_supported_version}\" CACHE STRING \"Minimum supported CMake version required to build Qt\")\n")
- string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
- "set(QT_COMPUTED_MIN_CMAKE_VERSION \"${computed_min_version}\" CACHE STRING \"Computed minimum CMake version required to build Qt\")\n")
+ "set(QT_MIN_SUPPORTED_CMAKE_VERSION \"${min_supported_version}\" CACHE STRING \"Minimum supported CMake version required to build Qt\")\n"
+ "set(QT_COMPUTED_MIN_CMAKE_VERSION \"${computed_min_version}\" CACHE STRING \"Computed minimum CMake version required to build Qt\")\n"
+ "set(QT_MIN_NEW_POLICY_CMAKE_VERSION \"${lower_policy_version}\" CACHE STRING \"Oldest CMake version for which NEW policies should be enabled\")\n"
+ "set(QT_MAX_NEW_POLICY_CMAKE_VERSION \"${upper_policy_version}\" CACHE STRING \"Latest CMake version for which NEW policies should be enabled\")\n"
+ )
# Rpath related things that need to be re-used when building other repos.
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
diff --git a/cmake/QtToolHelpers.cmake b/cmake/QtToolHelpers.cmake
index 4cca2990f33..6717465bba6 100644
--- a/cmake/QtToolHelpers.cmake
+++ b/cmake/QtToolHelpers.cmake
@@ -324,6 +324,8 @@ endif()
endif()
# Configure and install the ${module_name}Tools package Config file.
+ qt_internal_get_min_new_policy_cmake_version(min_new_policy_version)
+ qt_internal_get_max_new_policy_cmake_version(max_new_policy_version)
configure_package_config_file(
"${QT_CMAKE_DIR}/QtModuleToolsConfig.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Config.cmake"