qt5base-lts/cmake/QtPublicCMakeVersionHelpers.cmake
Alexandru Croitor 6518bcc167 CMake: Enforce minimum CMake version in user projects
This change introduces new behavior to error out when configuring user
projects if the CMake version used is too old for Qt to work with.

The main motivator is the requirement of new CMake features to ensure
object libraries are placed in the proper place on the link line in
static builds.

The minimum CMake version is computed based on whether Qt was
configured as shared or static libraries.

At the moment the required versions for building and using Qt are the
same.

The minimum versions are defined in qtbase/.cmake.conf in the
following variables

QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_SHARED
QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_STATIC
QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_SHARED
QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC

Qt Packagers can disable the version check when configuring Qt
by setting
QT_FORCE_MIN_CMAKE_VERSION_FOR_BUILDING_QT and
QT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT.

In this case it is the packagers responsibility to ensure such a Qt
works correctly with the specified CMake version.

User projects can also set QT_FORCE_MIN_CMAKE_VERSION_FOR_USING_QT
to disable the version check. Then it's the project's developer
responsibility to ensure such a Qt works correctly.

No official support is provided for these cases.

Implementation notes.

The versions required to build Qt are stored in
QtBuildInternalsExtra.cmake
whereas the versions required to use Qt are stored in a new
QtConfigExtras.cmake.

Also the policy range variables stored in
QtBuildInternalsExtra.cmake are now regular variables instead of cache
variables, to properly allow overrides per-repository.

Some renaming of functions and variables was done for a bit more
clarity and easier grep-ability.

Pick-to: 6.2
Task-number: QTBUG-95018
Change-Id: I4279f2e10b6d3977319237ba21e2f4ed676aa48b
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2021-08-04 16:03:08 +02:00

70 lines
3.3 KiB
CMake

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()