b3e3b12489
Changing a C++ source file can trigger rebuilds of a lot of other source files that might include AUTOGEN'ed headers or sources. See https://gitlab.kitware.com/cmake/cmake/-/issues/22531 for some details. Fixed in CMake 3.21.2. There are still files that are rebuilt even in 3.21.2, but it's less, and it returns to the status quo of how it was in 3.21.0 or earlier versions. Pick-to: 6.2 6.3 6.4 Task-number: QTBUG-104352 Change-Id: Ie1c991d52df48442d4134e4ed22a8137a3c993c8 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
243 lines
12 KiB
CMake
243 lines
12 KiB
CMake
# 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()
|
|
|
|
# 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}")
|
|
|
|
# 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 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_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_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_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)
|
|
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_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 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_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 "
|
|
"-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_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: '${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_buggy_cmake_versions)
|
|
set(unsuitable_versions "")
|
|
|
|
# Touching a library's source file causes unnecessary rebuilding of unrelated targets.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/21020
|
|
list(APPEND unsuitable_versions "3.18.0")
|
|
|
|
# Ninja Multi-Config race condition overrides response files of different configurations
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/20961
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/21050 (follow up issue)
|
|
list(APPEND unsuitable_versions "3.18.1")
|
|
|
|
# AUTOMOC dependencies are not properly created when using Ninja Multi-Config.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/21118
|
|
#
|
|
# Also until 3.18.2 inclusive, AUTOMOC dependencies are out-of-date if a previously header
|
|
# disappears (for example when upgrading a compiler)
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/21136
|
|
#
|
|
# Also multi-arch PCH doesn't work on iOS. Can't quite find the original upstream CMake issue
|
|
# but the Qt one was detected at https://codereview.qt-project.org/c/qt/qt5/+/310947
|
|
# And a follow up issue regarding PCH and -fembed-bitcode failing.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/21163
|
|
list(APPEND unsuitable_versions "3.18.2")
|
|
|
|
# Cyclic dependencies are created when mixing AUTOMOC/AUTOUIC with sources
|
|
# that have their SKIP_MOC or SKIP_UIC source file properties set to true.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/21977
|
|
list(APPEND unsuitable_versions "3.20.0")
|
|
|
|
# AUTOMOC can crash or hang when using a Qt that supports moc depfiles.
|
|
# Issues reported on Windows with Ninja and Makefiles, but it could be happening
|
|
# on other platforms too.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/22014
|
|
list(APPEND unsuitable_versions "3.20.1")
|
|
|
|
# Cyclic dependencies can happen when the AUTOMOC / AUTOUIC include directory is added as a
|
|
# target include directory.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6380
|
|
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6359
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/16776
|
|
list(APPEND unsuitable_versions "3.21.0")
|
|
|
|
# Changing a C++ source file can trigger rebuilds of a lot of other source files that might
|
|
# include AUTOGEN'ed headers or sources.
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/22531
|
|
# Fixed in 3.21.2.
|
|
list(APPEND unsuitable_versions "3.21.1")
|
|
|
|
# qt_ensure_perl fails to find perl in host PATH via find_program
|
|
# due to Android Platform module setting CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH to OFF
|
|
# Fixed in 3.20.6, 3.21.3. not a problem in CMake versions earlier than 3.20.0
|
|
# https://gitlab.kitware.com/cmake/cmake/-/issues/22634
|
|
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/5357
|
|
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/6528
|
|
if(ANDROID AND CMAKE_HOST_WIN32)
|
|
list(APPEND unsuitable_versions
|
|
"3.20.0" "3.20.1" "3.20.2" "3.20.3" "3.20.4" "3.20.5"
|
|
"3.21.0" "3.21.1" "3.21.2"
|
|
)
|
|
endif()
|
|
|
|
foreach(unsuitable_version ${unsuitable_versions})
|
|
if(CMAKE_VERSION VERSION_EQUAL unsuitable_version)
|
|
message(WARNING
|
|
"The CMake version you are using is known to cause issues when building Qt. "
|
|
"Please upgrade to a newer version. "
|
|
"CMake version used: '${unsuitable_version}'")
|
|
endif()
|
|
endforeach()
|
|
|
|
# Ninja Multi-Config was introduced in 3.17, but we recommend 3.18.
|
|
set(min_nmc_cmake_version "3.18.3")
|
|
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config"
|
|
AND CMAKE_VERSION VERSION_LESS ${min_nmc_cmake_version})
|
|
message(WARNING
|
|
"You are using CMake ${CMAKE_VERSION} with the Ninja Multi-Config generator. "
|
|
"This combination is unsupported. "
|
|
"Please upgrade to at least CMake ${min_nmc_cmake_version}. ")
|
|
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_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()
|