We set the CMP0156 policy to NEW for Apple platforms for each created Qt target, but the debug message is generic, so we should only show it once. Amends c20d7bcb86361d0c9f8af3807dcad9db1a3a5ca0 Pick-to: 6.8 Task-number: QTBUG-135978 Change-Id: I332bd357999647df1d5f715d154fb568911889b1 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit 674a6dc5f66fce1cbe77a593e1fc942290d3f9b1) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
192 lines
9.2 KiB
CMake
192 lines
9.2 KiB
CMake
# Copyright (C) 2022 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
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)
|
|
__qt_internal_force_allow_unsuitable_cmake_version_for_using_qt(allow_any_version)
|
|
|
|
# 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(allow_any_version)
|
|
# Just set some low version, the exact value is not really important.
|
|
set(computed_min_version "3.16")
|
|
|
|
# Allow override when configuring user project.
|
|
elseif(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()
|
|
|
|
# Sets out_var to either TRUE or FALSE if dependning on whether there was a forceful request to
|
|
# allow using the current cmake version to use Qt in projects.
|
|
function(__qt_internal_force_allow_unsuitable_cmake_version_for_using_qt out_var)
|
|
set(allow_any_version FALSE)
|
|
|
|
# Temporarily allow any version when using Qt in Qt's CI, so we can decouple the provisioning
|
|
# of the minimum CMake version from the bump of the minimum CMake version.
|
|
# The COIN_UNIQUE_JOB_ID env var is set in Qt's CI for both build and test work items.
|
|
# Current state is that this check is disabled.
|
|
set(allow_any_version_in_ci FALSE)
|
|
|
|
if(allow_any_version_in_ci AND DEFINED ENV{COIN_UNIQUE_JOB_ID})
|
|
set(allow_any_version TRUE)
|
|
endif()
|
|
|
|
# An explicit opt in, for using any CMake version.
|
|
if(QT_FORCE_ANY_CMAKE_VERSION_FOR_USING_QT)
|
|
set(allow_any_version TRUE)
|
|
endif()
|
|
|
|
set(${out_var} "${allow_any_version}" PARENT_SCOPE)
|
|
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()
|
|
|
|
# Handle force-assignment of CMP0156 policy when using CMake 3.29+.
|
|
#
|
|
# For Apple-platforms we set it to NEW, to avoid duplicate linker issues when using -ObjC flag.
|
|
#
|
|
# For non-Apple platforms we set it to OLD, because we haven't done the necessary testing to
|
|
# see which platforms / linkers can handle the new deduplication behavior, without breaking the
|
|
# various linking techniques that Qt uses for object library propagation.
|
|
function(__qt_internal_set_cmp0156)
|
|
# Exit early if not using CMake 3.29+
|
|
if(NOT POLICY CMP0156)
|
|
return()
|
|
endif()
|
|
|
|
# Honor this variable if it's set and TRUE. It was previously introduced to allow working around
|
|
# the forced OLD value.
|
|
if(QT_FORCE_CMP0156_TO_NEW)
|
|
get_cmake_property(debug_message_shown _qt_internal_cmp0156_debug_message_shown)
|
|
if(NOT debug_message_shown)
|
|
message(DEBUG "Force setting the CMP0156 policy to user provided value: NEW")
|
|
set_property(GLOBAL PROPERTY _qt_internal_cmp0156_debug_message_shown TRUE)
|
|
endif()
|
|
|
|
cmake_policy(SET CMP0156 "NEW")
|
|
return()
|
|
endif()
|
|
|
|
# Allow forcing to OLD / NEW or empty behavior due the default being NEW for Apple platforms.
|
|
if(QT_FORCE_CMP0156_TO_VALUE)
|
|
cmake_policy(SET CMP0156 "${QT_FORCE_CMP0156_TO_VALUE}")
|
|
message(DEBUG "Force setting the CMP0156 policy to user provided value: "
|
|
"${QT_FORCE_CMP0156_TO_VALUE}")
|
|
return()
|
|
endif()
|
|
|
|
# Get the current value of the policy, as saved by the Qt6 package as soon as it is found.
|
|
# We can't just do cmake_policy(GET CMP0156 policy_value) here, because our Qt6Config.cmake and
|
|
# Qt6FooConfig.cmake files use cmake_minimum_required, which reset the policy value that
|
|
# might have been set by the project developer or the user.
|
|
# And a function uses the policy values that were set when the function was defined, not when
|
|
# it is called.
|
|
__qt_internal_get_directory_scope_policy_cmp0156(policy_value)
|
|
|
|
# Apple linkers (legacy Apple ld64, as well as the new ld-prime) don't care about the
|
|
# link line order when linking static libraries, compared to Linux GNU ld.
|
|
# But they care about duplicate static frameworks (not libraries) when used in conjunction with
|
|
# the -ObjC flag, which force loads all static libraries / frameworks that contain Objective-C
|
|
# categories or classes. This can cause duplicate symbol errors.
|
|
# To avoid the issue, we want to enable the policy, so we de-duplicate the libraries.
|
|
if(APPLE)
|
|
set(default_policy_value NEW)
|
|
set(unsupported_policy_value OLD)
|
|
set(platform_string "Apple")
|
|
else()
|
|
# For non-Apple linkers, we keep the previous behavior of not deduplicating libraries,
|
|
# because we haven't done the necessary testing to identify on which platforms
|
|
# it is safe to deduplicate.
|
|
set(default_policy_value OLD)
|
|
set(unsupported_policy_value NEW)
|
|
set(platform_string "non-Apple")
|
|
endif()
|
|
|
|
# Force set the default policy value for the given platform, even if the policy value is
|
|
# the same or empty. That's because in the calling function scope, the value can be empty
|
|
# due to the cmake_minimum_required call in Qt6Config.cmake resetting the policy value.
|
|
get_cmake_property(debug_message_shown _qt_internal_cmp0156_debug_message_shown)
|
|
if(NOT debug_message_shown)
|
|
message(DEBUG "Force setting the CMP0156 policy to '${default_policy_value}' "
|
|
"for ${platform_string} platforms.")
|
|
set_property(GLOBAL PROPERTY _qt_internal_cmp0156_debug_message_shown TRUE)
|
|
endif()
|
|
|
|
cmake_policy(SET CMP0156 "${default_policy_value}")
|
|
|
|
# If the policy is explicitly set to a value other than the default, issue a warning.
|
|
# Don't show the warning if the policy is unset, which would be the default for most
|
|
# projects, because it's too much noise. Also don't show it for Qt builds.
|
|
if("${policy_value}" STREQUAL "${unsupported_policy_value}" AND NOT QT_BUILDING_QT)
|
|
message(WARNING
|
|
"CMP0156 is set to '${policy_value}'. Qt forces the '${default_policy_value}'"
|
|
" behavior of this policy for ${platform_string} platforms by default."
|
|
" Set QT_FORCE_CMP0156_TO_VALUE=${unsupported_policy_value} to force"
|
|
" the '${unsupported_policy_value}' behavior for Qt commands that create"
|
|
" library or executable targets.")
|
|
endif()
|
|
endfunction()
|