CMake: Add qt 'policy' support
This mimics CMake's policy support. The policy state is stored in an internal __QT_INTERNAL_POLICY_<policy> variable; by using normal variables, we gain support for stacking for free. Policies can be explicitly en- or disable via qt6_policy; that command also has a GET mode to retrieve them again. Furthermore, one can now pass min and max version to qt6_standard_project_setup, to opt in to a certain set of defaults introduced in a given Qt version. We add support for policies in QtModuleHelpers, so that we can check for known policies while building Qt itself. No actual policies exist yet; but a follow up commit will introduce one for qt_add_qml_module. Change-Id: I57a0404c9193926dd499f94cc5f73e359355c0b3 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>bb10
parent
8aae821b5a
commit
b9c80ecc08
|
|
@ -39,6 +39,7 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
|
|||
EXTRA_CMAKE_INCLUDES
|
||||
NO_PCH_SOURCES
|
||||
EXTERNAL_HEADERS
|
||||
POLICIES
|
||||
${__default_private_args}
|
||||
${__default_public_args}
|
||||
${__default_private_module_args}
|
||||
|
|
@ -674,6 +675,21 @@ set(QT_LIBINFIX \"${QT_LIBINFIX}\")")
|
|||
|
||||
set(extra_cmake_code "")
|
||||
|
||||
if(arg_POLICIES)
|
||||
set(policies "")
|
||||
foreach(policy IN LISTS arg_POLICIES)
|
||||
list(APPEND policies "set(QT_KNOWN_POLICY_${policy} TRUE)")
|
||||
|
||||
# When building Qt, tests and examples might expect a policy to be known, but they
|
||||
# won't be known depending on which scope or when a find_package(Module) with the
|
||||
# respective policy is called. Check the global list of known policies to accommodate
|
||||
# that.
|
||||
set_property(GLOBAL APPEND PROPERTY _qt_global_known_policies "${policy}")
|
||||
endforeach()
|
||||
list(JOIN policies "\n" policies_str)
|
||||
string(APPEND extra_cmake_code "${policies_str}\n")
|
||||
endif()
|
||||
|
||||
# Generate metatypes
|
||||
if(${arg_GENERATE_METATYPES})
|
||||
# No mention of NO_GENERATE_METATYPES. You should not use it.
|
||||
|
|
|
|||
|
|
@ -2617,6 +2617,64 @@ unset(__qt_deploy_support_files)
|
|||
")
|
||||
endfunction()
|
||||
|
||||
# We basically mirror CMake's policy setup
|
||||
# A policy can be set to OLD, set to NEW or unset
|
||||
# unset is the default state
|
||||
#
|
||||
function(qt6_policy mode policy behaviorOrVariable)
|
||||
# When building Qt, tests and examples might expect a policy to be known, but they won't be
|
||||
# known depending on which scope or when a find_package(Module) with the respective policy
|
||||
# is called. Check the global list of known policies to accommodate that.
|
||||
if(QT_BUILDING_QT AND NOT DEFINED QT_KNOWN_POLICY_${policy})
|
||||
get_property(global_known_policies GLOBAL PROPERTY _qt_global_known_policies)
|
||||
if(policy IN_LIST global_known_policies)
|
||||
set(QT_KNOWN_POLICY_${policy} TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED QT_KNOWN_POLICY_${policy})
|
||||
message(FATAL_ERROR
|
||||
"${policy} is not a known Qt policy. Did you include the necessary Qt module?"
|
||||
)
|
||||
endif()
|
||||
if (${mode} STREQUAL "SET")
|
||||
set(behavior ${behaviorOrVariable})
|
||||
if (${behavior} STREQUAL "NEW" OR ${behavior} STREQUAL "OLD")
|
||||
set(__QT_INTERNAL_POLICY_${policy} ${behavior} PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Qt policies must be either set to NEW or OLD, but got ${behavior}")
|
||||
endif()
|
||||
else(${mode} STREQUAL "GET")
|
||||
set(variable "${behaviorOrVariable}")
|
||||
set("${variable}" "${__QT_INTERNAL_POLICY_${policy}}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Internal helper function; can be used in any module before doing a policy check
|
||||
function(__qt_internal_setup_policy policy sinceversion policyexplanation)
|
||||
if(DEFINED __QT_INTERNAL_POLICY_${policy})
|
||||
if (__QT_INTERNAL_POLICY_${policy} STREQUAL "OLD")
|
||||
# policy is explicitly disabled
|
||||
message(DEPRECATION
|
||||
"Qt policy ${policy} is set to OLD. "
|
||||
"Support for the old behavior will be removed in a future major version of Qt."
|
||||
)
|
||||
endif()
|
||||
#else: policy is already enabled, nothing to do
|
||||
elseif (${sinceversion} VERSION_LESS_EQUAL __qt_policy_check_version)
|
||||
# we cannot use the public function here as we want to set it in parent scope
|
||||
set(__QT_INTERNAL_POLICY_${policy} "NEW" PARENT_SCOPE)
|
||||
elseif(NOT "${QT_NO_SHOW_OLD_POLICY_WARNINGS}")
|
||||
message(AUTHOR_WARNING
|
||||
"Qt policy ${policy} is not set. "
|
||||
"Use the qt6_set_policy command to set it and suppress this warning. "
|
||||
"You can also silence all policy warnings by setting QT_NO_SHOW_OLD_POLICY_WARNINGS "
|
||||
"to true.\n"
|
||||
"${policyexplanation}"
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Note this needs to be a macro because it sets variables intended for the
|
||||
# calling scope.
|
||||
macro(qt6_standard_project_setup)
|
||||
|
|
@ -2625,6 +2683,46 @@ macro(qt6_standard_project_setup)
|
|||
# They can set this variable to true to effectively disable this function.
|
||||
if(NOT QT_NO_STANDARD_PROJECT_SETUP)
|
||||
|
||||
set(__qt_sps_args_option)
|
||||
set(__qt_sps_args_single
|
||||
MIN_VERSION
|
||||
MAX_VERSION
|
||||
)
|
||||
set(__qt_sps_args_multi)
|
||||
cmake_parse_arguments(__qt_sps_arg
|
||||
"${__qt_sps_args_option}"
|
||||
"${__qt_sps_args_single}"
|
||||
"${__qt_sps_args_multi}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if(__qt_sps_arg_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "Unexpected arguments: ${arg_UNPARSED_ARGUMENTS}")
|
||||
endif()
|
||||
|
||||
set(__qt_policy_check_version "6.0.0")
|
||||
if(Qt6_VERSION_MAJOR)
|
||||
set(__qt_current_version
|
||||
"${Qt6_VERSION_MAJOR}.${Qt6_VERSION_MINOR}.${Qt6_VERSION_PATCH}")
|
||||
elseif(QT_BUILDING_QT)
|
||||
set(__qt_current_version
|
||||
"${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
else()
|
||||
message(FATAL_ERROR "Can not determine Qt version.")
|
||||
endif()
|
||||
if (__qt_sps_arg_MIN_VERSION)
|
||||
if ("${__qt_current_version}" VERSION_LESS "${__qt_sps_arg_MIN_VERSION}")
|
||||
message(FATAL_ERROR "Project required a Qt minimum version of ${__qt_sps_arg_MIN_VERSION}, but current version is only ${__qt_current_version}")
|
||||
endif()
|
||||
set(__qt_policy_check_version "${__qt_sps_arg_MIN_VERSION}")
|
||||
endif()
|
||||
if (__qt_sps_arg_MAX_VERSION)
|
||||
if (${__qt_sps_arg_MAX_VERSION} VERSION_LESS ${__qt_sps_arg_MIN_VERSION})
|
||||
message(FATAL_ERROR "MAX_VERSION must be larger or equal than MIN_VERSION")
|
||||
endif()
|
||||
set(__qt_policy_check_version "${__qt_sps_arg_MAX_VERSION}")
|
||||
endif()
|
||||
|
||||
# All changes below this point should not result in a change to an
|
||||
# existing value, except for CMAKE_INSTALL_RPATH which may append new
|
||||
# values (but no duplicates).
|
||||
|
|
@ -2689,6 +2787,9 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
|||
macro(qt_standard_project_setup)
|
||||
qt6_standard_project_setup(${ARGV})
|
||||
endmacro()
|
||||
macro(qt_policy)
|
||||
qt6_policy(${ARGV})
|
||||
endmacro()
|
||||
endif()
|
||||
|
||||
function(qt6_generate_deploy_script)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\page qt-policy.html
|
||||
\ingroup cmake-commands-qtcore
|
||||
|
||||
\summary {Modify the default behavior of Qt's CMake API.}
|
||||
|
||||
\include cmake-find-package-core.qdocinc
|
||||
|
||||
\cmakecommandsince 6.5
|
||||
|
||||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt_policy(
|
||||
[SET policy behavior]
|
||||
[GET policy variable]
|
||||
)
|
||||
\endcode
|
||||
|
||||
\versionlessCMakeCommandsNote qt6_policy()
|
||||
|
||||
\section1 Description
|
||||
This command has two modes:
|
||||
\list
|
||||
\li When the \c{SET} keyword is used, this command can be used to opt in to
|
||||
behavior changes in Qt's CMake API, or to explicitly opt out of them.
|
||||
\li When the \c{GET} keyword is used, \c{variable} is set to the current
|
||||
value for the policy.
|
||||
\endlist
|
||||
\c{policyname} must be the name of a Qt cmake policy. Using an unknown policy
|
||||
is an error; code supporting older Qt versions should check with
|
||||
\badcode
|
||||
if(QT_KNOWN_POLICY_<policy_name>)
|
||||
\endcode
|
||||
whether the policy exists before querying or setting it.
|
||||
|
||||
\c{behavior} can
|
||||
either be
|
||||
\list
|
||||
\li \c{NEW} to opt into the new behavior, or
|
||||
\li \c{OLD} to explicitly opt-out of it.
|
||||
\endlist
|
||||
|
||||
\sa qt_standard_project_setup
|
||||
|
||||
*/
|
||||
|
|
@ -17,7 +17,10 @@
|
|||
\section1 Synopsis
|
||||
|
||||
\badcode
|
||||
qt_standard_project_setup()
|
||||
qt_standard_project_setup(
|
||||
[MIN_VERSION policy_min]
|
||||
[MAX_VERSION policy_max]
|
||||
)
|
||||
\endcode
|
||||
|
||||
\versionlessCMakeCommandsNote qt6_standard_project_setup()
|
||||
|
|
@ -47,6 +50,16 @@ have been defined. It does the following things:
|
|||
Qt-internal targets in this folder.
|
||||
\endlist
|
||||
|
||||
Moreover, since Qt 6.5 it can be used to change the default behavior of Qt's CMake
|
||||
API, by opting in to changes from newer Qt versions. If \c{MIN_VERSION} is
|
||||
specified, all suggested changes introduced in Qt up to \c{MIN_VERSION} are enabled,
|
||||
and using an older Qt version will result in an error.
|
||||
If additionally \c{MAX_VERSION} has been specified, any new changes introduced
|
||||
in versions up to \c{MAX_VERSION} are also enabled (but using an older Qt
|
||||
version is not an error).
|
||||
This is similar to CMake's policy concept (compare \l{cmake_policy}).
|
||||
|
||||
|
||||
On platforms that support \c{RPATH} (other than Apple platforms), two values
|
||||
are appended to the \c{CMAKE_INSTALL_RPATH} variable by this command.
|
||||
\c{$ORIGIN} is appended so that libraries will find other libraries they depend
|
||||
|
|
@ -67,6 +80,7 @@ The \c{qt_standard_project_setup()} command can effectively be disabled by
|
|||
setting the \l{QT_NO_STANDARD_PROJECT_SETUP} variable to true.
|
||||
|
||||
\sa {qt6_generate_deploy_app_script}{qt_generate_deploy_app_script()}
|
||||
\sa {qt6_policy}
|
||||
|
||||
\section1 Example
|
||||
|
||||
|
|
|
|||
|
|
@ -131,3 +131,8 @@
|
|||
\externalpage https://cmake.org/cmake/help/latest/prop_tgt/FOLDER.html
|
||||
\title FOLDER
|
||||
*/
|
||||
|
||||
/*!
|
||||
\externalpage https://cmake.org/cmake/help/latest/command/cmake_policy.html
|
||||
\title cmake_policy
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue