diff options
-rw-r--r-- | .cmake.conf | 10 | ||||
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | cmake/QtBaseGlobalTargets.cmake | 18 | ||||
-rw-r--r-- | cmake/QtBuildInternalsExtra.cmake.in | 15 | ||||
-rw-r--r-- | cmake/QtCMakeVersionHelpers.cmake | 115 | ||||
-rw-r--r-- | cmake/QtConfig.cmake.in | 4 | ||||
-rw-r--r-- | cmake/QtConfigExtras.cmake.in | 2 | ||||
-rw-r--r-- | cmake/QtPostProcessHelpers.cmake | 22 | ||||
-rw-r--r-- | cmake/QtPublicCMakeVersionHelpers.cmake | 69 |
9 files changed, 205 insertions, 53 deletions
diff --git a/.cmake.conf b/.cmake.conf index ff95a9c186..12991eebd5 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -2,8 +2,14 @@ set(QT_REPO_MODULE_VERSION "6.2.0") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") # Minimum requirement for building Qt -set(QT_MIN_SUPPORTED_CMAKE_VERSION "3.16") -set(QT_MIN_SUPPORTED_CMAKE_VERSION_FOR_STATIC_QT "3.20") +set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_SHARED "3.16") +set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_STATIC "3.20") + +# Minimum requirement for consuming Qt in a user project. +# This might be different in the future, e.g. be lower than the requirement for +# building Qt. +set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_SHARED "3.16") +set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC "3.20") # 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index c3dcc2f731..f453505ee8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,7 +57,8 @@ set(QT6_IS_SHARED_LIBS_BUILD ${BUILD_SHARED_LIBS}) # or specified via a toolchain file that is loaded by the project() call # or set by the option() call above include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtCMakeVersionHelpers.cmake") -qt_internal_check_for_suitable_cmake_version() +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtPublicCMakeVersionHelpers.cmake") +qt_internal_check_and_warn_about_unsuitable_cmake_version() if(NOT QT_BUILD_STANDALONE_TESTS) ## Add some paths to check for cmake modules: diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index aab7646b25..0ed881aac5 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -142,16 +142,28 @@ qt_internal_export_modern_cmake_config_targets_file(TARGETS ${__export_targets} CONFIG_INSTALL_DIR ${__GlobalConfig_install_dir}) -# Generate and install Qt6 config file. Make sure it happens after the global feature evaluation so -# they can be accessed in the Config file if needed. +# Save minimum required CMake version to use Qt. +qt_internal_get_supported_min_cmake_version_for_using_qt(supported_min_version_for_using_qt) +qt_internal_get_computed_min_cmake_version_for_using_qt(computed_min_version_for_using_qt) + +# Get the lower and upper policy range to embed into the 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) + +# Generate and install Qt6 config file. Make sure it happens after the global feature evaluation so +# they can be accessed in the Config file if needed. configure_package_config_file( "${PROJECT_SOURCE_DIR}/cmake/QtConfig.cmake.in" "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}Config.cmake" INSTALL_DESTINATION "${__GlobalConfig_install_dir}" ) +configure_file( + "${PROJECT_SOURCE_DIR}/cmake/QtConfigExtras.cmake.in" + "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigExtras.cmake" + @ONLY +) + write_basic_package_version_file( "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersion.cmake" VERSION ${PROJECT_VERSION} @@ -160,6 +172,7 @@ write_basic_package_version_file( qt_install(FILES "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}Config.cmake" + "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigExtras.cmake" "${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersion.cmake" DESTINATION "${__GlobalConfig_install_dir}" COMPONENT Devel @@ -257,6 +270,7 @@ qt_copy_or_install(DIRECTORY set(__public_cmake_helpers cmake/QtFeature.cmake cmake/QtFeatureCommon.cmake + cmake/QtPublicCMakeVersionHelpers.cmake cmake/QtPublicFinalizerHelpers.cmake cmake/QtPublicPluginHelpers.cmake cmake/QtPublicTargetHelpers.cmake diff --git a/cmake/QtBuildInternalsExtra.cmake.in b/cmake/QtBuildInternalsExtra.cmake.in index b089f00fd6..640fbdca9d 100644 --- a/cmake/QtBuildInternalsExtra.cmake.in +++ b/cmake/QtBuildInternalsExtra.cmake.in @@ -69,5 +69,20 @@ set(QT_USE_CCACHE @QT_USE_CCACHE@ CACHE BOOL "Enable the use of ccache") set(QT_CREATE_VERSIONED_HARD_LINK "@QT_CREATE_VERSIONED_HARD_LINK@" CACHE BOOL "Enable the use of versioned hard link") +# The minimum version required to build Qt. +set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT "@supported_min_version_for_building_qt@") +set(QT_COMPUTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT "@computed_min_version_for_building_qt@") + +# The lower and upper CMake version policy range as computed by qtbase. +# These values are inherited when building other Qt repositories, unless overridden +# in the respective repository .cmake.conf file. +# These are not cache variables, so that they can be overridden in each repo directory scope. +if(NOT DEFINED QT_MIN_NEW_POLICY_CMAKE_VERSION) + set(QT_MIN_NEW_POLICY_CMAKE_VERSION "@min_new_policy_version@") +endif() +if(NOT DEFINED QT_MAX_NEW_POLICY_CMAKE_VERSION) + set(QT_MAX_NEW_POLICY_CMAKE_VERSION "@max_new_policy_version@") +endif() + # Extra set of exported variables @QT_EXTRA_BUILD_INTERNALS_VARS@ diff --git a/cmake/QtCMakeVersionHelpers.cmake b/cmake/QtCMakeVersionHelpers.cmake index 31eb78b667..9013c2321a 100644 --- a/cmake/QtCMakeVersionHelpers.cmake +++ b/cmake/QtCMakeVersionHelpers.cmake @@ -1,38 +1,74 @@ -# Returns the minimum supported CMake version required to build Qt as originally advertised by Qt. -function(qt_internal_get_qt_supported_minimum_cmake_version out_var) +# Returns the minimum supported CMake version required to /build/ Qt as originally advertised by Qt. +function(qt_internal_get_supported_min_cmake_version_for_building_qt out_var) if(NOT DEFINED BUILD_SHARED_LIBS) message(FATAL_ERROR "BUILD_SHARED_LIBS is needed to decide the minimum CMake version. " "It should have been set by this point.") endif() - # QT_MIN_SUPPORTED_CMAKE_VERSION is set either in .cmake.conf or in QtBuildInternalsExtras.cmake - # when building a repo. - set(supported_version "${QT_MIN_SUPPORTED_CMAKE_VERSION}") + # First check if a value is already set in QtBuildInternalsExtras.cmake, which means we're + # building a repo other than qtbase and the minimum version was already recorded. + if(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT) + set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT}") - if(NOT BUILD_SHARED_LIBS) - set(supported_version "${QT_MIN_SUPPORTED_CMAKE_VERSION_FOR_STATIC_QT}") + # We're building qtbase so the values come from .cmake.conf. + elseif(BUILD_SHARED_LIBS) + set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_SHARED}") + else() + set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_STATIC}") endif() + set(${out_var} "${supported_version}" PARENT_SCOPE) endfunction() -# Returns the computed minimum supported CMake version required to build Qt. -function(qt_internal_get_computed_minimum_cmake_version out_var) +# Returns the minimum supported CMake version required to /use/ Qt as originally advertised by Qt. +function(qt_internal_get_supported_min_cmake_version_for_using_qt out_var) + if(NOT DEFINED BUILD_SHARED_LIBS) + message(FATAL_ERROR "BUILD_SHARED_LIBS is needed to decide the minimum CMake version. " + "It should have been set by this point.") + endif() + + if(BUILD_SHARED_LIBS) + set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_SHARED}") + else() + set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC}") + endif() + + set(${out_var} "${supported_version}" PARENT_SCOPE) +endfunction() + +# Returns the computed minimum supported CMake version required to /build/ Qt. +function(qt_internal_get_computed_min_cmake_version_for_building_qt out_var) # An explicit override for those that take it upon themselves to fix the build system # when using a CMake version lower than the one officially supported. # Also useful for build testing locally with different minimum versions to observe different # policy behaviors. - if(QT_FORCE_MIN_CMAKE_VERSION) - set(computed_min_version "${QT_FORCE_MIN_CMAKE_VERSION}") + if(QT_FORCE_MIN_CMAKE_VERSION_FOR_BUILDING_QT) + set(computed_min_version "${QT_FORCE_MIN_CMAKE_VERSION_FOR_BUILDING_QT}") # Set in QtBuildInternalsExtras.cmake, which means it was already computed as part of qtbase # configuration. - elseif(QT_COMPUTED_MIN_CMAKE_VERSION) - set(computed_min_version "${QT_COMPUTED_MIN_CMAKE_VERSION}") + elseif(QT_COMPUTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT) + set(computed_min_version "${QT_COMPUTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT}") # No override was given and the version was not computed before, thus initialize with the # default minimum. else() - qt_internal_get_qt_supported_minimum_cmake_version(min_supported_version) + qt_internal_get_supported_min_cmake_version_for_building_qt(min_supported_version) + set(computed_min_version "${min_supported_version}") + endif() + set(${out_var} "${computed_min_version}" PARENT_SCOPE) +endfunction() + +# Returns the computed minimum supported CMake version required to /use/ Qt. +function(qt_internal_get_computed_min_cmake_version_for_using_qt out_var) + # Allow overriding the required minimum CMake version for user projects, without forcing + # each project developer to have to override it manually. + if(QT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT) + set(computed_min_version "${QT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT}") + + # No override was given, thus initialize with the default minimum. + else() + qt_internal_get_supported_min_cmake_version_for_using_qt(min_supported_version) set(computed_min_version "${min_supported_version}") endif() set(${out_var} "${computed_min_version}" PARENT_SCOPE) @@ -63,49 +99,54 @@ function(qt_internal_get_max_new_policy_cmake_version out_var) set(${out_var} "${upper_version}" PARENT_SCOPE) endfunction() -function(qt_internal_check_for_suitable_cmake_version) - # Implementation note. - # 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_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. - qt_internal_check_minimum_cmake_version() - qt_internal_warn_about_unsuitable_cmake_versions() +function(qt_internal_check_and_warn_about_unsuitable_cmake_version) + # Don't show the warnings multiple times in a top-level build. + get_cmake_property(check_done _qt_unsuitable_cmake_version_check_done) + if(check_done) + return() + endif() + set_property(GLOBAL PROPERTY _qt_unsuitable_cmake_version_check_done TRUE) + + qt_internal_warn_if_min_cmake_version_not_met() + qt_internal_warn_about_buggy_cmake_versions() endfunction() -# Function to be used in downstream repos like qtsvg to require a minimum CMake version. +# Function to be used in downstream repos (like qtsvg) to require a minimum CMake version and warn +# about unsuitable cmake versions. # # 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() - qt_internal_get_computed_minimum_cmake_version(computed_min_version) + qt_internal_check_and_warn_about_unsuitable_cmake_version() + qt_internal_get_computed_min_cmake_version_for_building_qt(computed_min_version) if(CMAKE_VERSION VERSION_LESS computed_min_version) + set(major_minor "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}") message(FATAL_ERROR "CMake ${computed_min_version} or higher is required. " "You are running version ${CMAKE_VERSION} " "\nQt requires newer CMake features to build correctly. You can lower the minimum " - "required version by passing a QT_FORCE_MIN_CMAKE_VERSION cache variable when configuring Qt.") + "required version by passing " + "-DQT_FORCE_MIN_CMAKE_VERSION_FOR_BUILDING_QT=${major_minor} when configuring Qt. " + "Building Qt with this CMake version is not officially supported. Use at your own risk." + ) endif() endfunction() -function(qt_internal_check_minimum_cmake_version) - qt_internal_get_qt_supported_minimum_cmake_version(min_supported_version) - qt_internal_get_computed_minimum_cmake_version(computed_min_version) +function(qt_internal_warn_if_min_cmake_version_not_met) + qt_internal_get_supported_min_cmake_version_for_building_qt(min_supported_version) + qt_internal_get_computed_min_cmake_version_for_building_qt(computed_min_version) if(NOT min_supported_version STREQUAL computed_min_version AND computed_min_version VERSION_LESS min_supported_version) message(WARNING - "The minimum required CMake version to build Qt is '${min_supported_version}'. " - "You have explicitly chosen to require a lower minimum CMake version, namely '${computed_min_version}'. " - "Building Qt with such a CMake version is not officially supported. Use at your own risk.") + "The minimum required CMake version to build Qt is: '${min_supported_version}'. " + "You have explicitly chosen to require a lower minimum CMake version: '${computed_min_version}'. " + "Building Qt with this CMake version is not officially supported. Use at your own risk.") endif() endfunction() -function(qt_internal_warn_about_unsuitable_cmake_versions) +function(qt_internal_warn_about_buggy_cmake_versions) set(unsuitable_versions "") # Touching a library's source file causes unnecessary rebuilding of unrelated targets. @@ -161,13 +202,15 @@ function(qt_internal_warn_about_unsuitable_cmake_versions) endif() endfunction() +# Used to upgrade policies only when building Qt repositories. +# # 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_computed_min_cmake_version_for_building_qt(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 92e47a04a0..7f5698a34c 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION @min_new_policy_version@...@max_new_policy_version@) +include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@ConfigExtras.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/QtPublicCMakeVersionHelpers.cmake") +__qt_internal_require_suitable_cmake_version_for_using_qt() + 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/QtConfigExtras.cmake.in b/cmake/QtConfigExtras.cmake.in new file mode 100644 index 0000000000..bde3460cdc --- /dev/null +++ b/cmake/QtConfigExtras.cmake.in @@ -0,0 +1,2 @@ +set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT "@supported_min_version_for_using_qt@") +set(QT_COMPUTED_MIN_CMAKE_VERSION_FOR_USING_QT "@computed_min_version_for_using_qt@") diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index 248989c81c..f8f42d273e 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -556,18 +556,16 @@ endif()\n") endif() # 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" - "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" - ) + # checked for when building other downstream repos (qtsvg, etc) and the policy settings + # will be consistent unless the downstream repos explicitly override them. + # Policy settings can be overridden per-repo, but the minimum CMake version is global for all of + # Qt. + qt_internal_get_supported_min_cmake_version_for_building_qt( + supported_min_version_for_building_qt) + qt_internal_get_computed_min_cmake_version_for_building_qt( + computed_min_version_for_building_qt) + qt_internal_get_min_new_policy_cmake_version(min_new_policy_version) + qt_internal_get_max_new_policy_cmake_version(max_new_policy_version) # Rpath related things that need to be re-used when building other repos. string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS diff --git a/cmake/QtPublicCMakeVersionHelpers.cmake b/cmake/QtPublicCMakeVersionHelpers.cmake new file mode 100644 index 0000000000..2b3c697f4c --- /dev/null +++ b/cmake/QtPublicCMakeVersionHelpers.cmake @@ -0,0 +1,69 @@ +function(__qt_internal_get_supported_min_cmake_version_for_using_qt out_var) + # This is recorded in Qt6ConfigExtras.cmake + set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT}") + set(${out_var} "${supported_version}" PARENT_SCOPE) +endfunction() + +function(__qt_internal_get_computed_min_cmake_version_for_using_qt out_var) + # Allow override when configuring user project. + if(QT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT) + set(computed_min_version "${QT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT}") + + # Set in QtConfigExtras.cmake. + elseif(QT_COMPUTED_MIN_CMAKE_VERSION_FOR_USING_QT) + set(computed_min_version "${QT_COMPUTED_MIN_CMAKE_VERSION_FOR_USING_QT}") + else() + message(FATAL_ERROR + "Qt Developer error: Can't compute the minimum CMake version required to use this Qt.") + endif() + + set(${out_var} "${computed_min_version}" PARENT_SCOPE) +endfunction() + +function(__qt_internal_warn_if_min_cmake_version_not_met) + __qt_internal_get_supported_min_cmake_version_for_using_qt(min_supported_version) + __qt_internal_get_computed_min_cmake_version_for_using_qt(computed_min_version) + + if(NOT min_supported_version STREQUAL computed_min_version + AND computed_min_version VERSION_LESS min_supported_version) + message(WARNING + "The minimum required CMake version to use Qt is: '${min_supported_version}'. " + "You have explicitly chosen to require a lower minimum CMake version: '${computed_min_version}'. " + "Using Qt with this CMake version is not officially supported. Use at your own risk." + ) + endif() +endfunction() + +function(__qt_internal_require_suitable_cmake_version_for_using_qt) + # Skip the public project check if we're building a Qt repo because it's too early to do + # it at find_package(Qt6) time. + # Instead, a separate check is done in qt_build_repo_begin. + # We detect a Qt repo by the presence of the QT_REPO_MODULE_VERSION variable set in .cmake.conf + # of each repo. + if(QT_REPO_MODULE_VERSION) + return() + endif() + + # Only do the setup once per directory scope, because Qt6 is a dependency for many packages, + # and a recursive call will show the warning multiple times. + if(__qt_internal_set_up_cmake_minimum_required_version_already_done) + return() + endif() + set(__qt_internal_set_up_cmake_minimum_required_version_already_done TRUE PARENT_SCOPE) + + # Check the overall minimum required CMake version when consuming any Qt CMake package. + __qt_internal_warn_if_min_cmake_version_not_met() + __qt_internal_get_computed_min_cmake_version_for_using_qt(computed_min_version) + + if(CMAKE_VERSION VERSION_LESS computed_min_version) + set(major_minor "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}") + message(FATAL_ERROR + "CMake ${computed_min_version} or higher is required to use Qt. " + "You are running version ${CMAKE_VERSION} " + "Qt requires newer CMake features to work correctly. You can lower the minimum " + "required version by passing " + "-DQT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT=${major_minor} when configuring the " + "project. Using Qt with this CMake version is not officially supported. " + "Use at your own risk.") + endif() +endfunction() |