summaryrefslogtreecommitdiffstats
path: root/cmake/QtFindPackageHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtFindPackageHelpers.cmake')
-rw-r--r--cmake/QtFindPackageHelpers.cmake365
1 files changed, 318 insertions, 47 deletions
diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake
index 2ccd61c938..dd10bde75a 100644
--- a/cmake/QtFindPackageHelpers.cmake
+++ b/cmake/QtFindPackageHelpers.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# This function recursively walks transitive link libraries of the given target
# and promotes those targets to be IMPORTED_GLOBAL if they are not.
#
@@ -7,30 +10,53 @@
# Only works if called from qt_find_package(), because the promotion needs to happen in the same
# directory scope where the imported target is first created.
#
-# Uses qt_internal_walk_libs.
+# Uses __qt_internal_walk_libs.
function(qt_find_package_promote_targets_to_global_scope target)
- qt_internal_walk_libs("${target}" _discarded_out_var _discarded_out_var_2
- "qt_find_package_targets_dict" "promote_global")
+ __qt_internal_walk_libs("${target}" _discarded_out_var _discarded_out_var_2
+ "qt_find_package_targets_dict" "promote_global")
endfunction()
+# As an optimization when using -developer-build, qt_find_package records which
+# packages were found during the initial configuration. Then on subsequent
+# reconfigurations it skips looking for packages that were not found on the
+# initial run.
+# For the build system to pick up a newly added qt_find_package call, you need to:
+# - Start with a clean build dir
+# - Or remove the <builddir>/CMakeCache.txt file and configure from scratch
+# - Or remove the QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES cache variable (by
+# editing CMakeCache.txt) and reconfigure.
macro(qt_find_package)
# Get the target names we expect to be provided by the package.
set(find_package_options CONFIG NO_MODULE MODULE REQUIRED)
set(options ${find_package_options} MARK_OPTIONAL)
set(oneValueArgs MODULE_NAME QMAKE_LIB)
- set(multiValueArgs PROVIDED_TARGETS COMPONENTS)
+ set(multiValueArgs PROVIDED_TARGETS COMPONENTS OPTIONAL_COMPONENTS)
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# If some Qt internal project calls qt_find_package(WrapFreeType), but WrapFreeType was already
# found as part of a find_dependency() call from a ModuleDependencies.cmake file (or similar),
# and the provided target is also found, that means this might have been an unnecessary
# qt_find_package() call, because the dependency was already found via some other transitive
- # dependency. Return early, so that CMake doesn't fail wiht an error with trying to promote the
+ # dependency. Return early, so that CMake doesn't fail with an error with trying to promote the
# targets to be global. This behavior is not enabled by default, because there are cases
# when a regular find_package() (non qt_) can find a package (Freetype -> PNG), and a subsequent
# qt_find_package(PNG PROVIDED_TARGET PNG::PNG) still needs to succeed and register the provided
# targets. To enable the debugging behavior, set QT_DEBUG_QT_FIND_PACKAGE to 1.
set(_qt_find_package_skip_find_package FALSE)
+
+ # Skip looking for packages that were not found on initial configuration, because they likely
+ # won't be found again, and only waste configuration time.
+ # Speeds up reconfiguration configuration for certain platforms and repos.
+ # Due to this behavior being different from what general CMake projects expect, it is only
+ # done for -developer-builds.
+ if(QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES AND
+ NOT "${ARGV0}" IN_LIST QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES
+ AND "${ARGV0}" IN_LIST QT_INTERNAL_PREVIOUSLY_SEARCHED_PACKAGES)
+ set(_qt_find_package_skip_find_package TRUE)
+ endif()
+
+ set_property(GLOBAL APPEND PROPERTY _qt_previously_searched_packages "${ARGV0}")
+
if(QT_DEBUG_QT_FIND_PACKAGE AND ${ARGV0}_FOUND AND arg_PROVIDED_TARGETS)
set(_qt_find_package_skip_find_package TRUE)
foreach(qt_find_package_target_name ${arg_PROVIDED_TARGETS})
@@ -45,6 +71,12 @@ macro(qt_find_package)
endif()
endif()
+ # When configure.cmake is included only to record summary entries, there's no point in looking
+ # for the packages.
+ if(__QtFeature_only_record_summary_entries)
+ set(_qt_find_package_skip_find_package TRUE)
+ endif()
+
# Get the version if specified.
set(package_version "")
if(${ARGC} GREATER_EQUAL 2)
@@ -57,7 +89,10 @@ macro(qt_find_package)
# Re-append components to forward them.
list(APPEND arg_UNPARSED_ARGUMENTS "COMPONENTS;${arg_COMPONENTS}")
endif()
- # TODO: Handle REQUIRED_COMPONENTS.
+ if(arg_OPTIONAL_COMPONENTS)
+ # Re-append optional components to forward them.
+ list(APPEND arg_UNPARSED_ARGUMENTS "OPTIONAL_COMPONENTS;${arg_OPTIONAL_COMPONENTS}")
+ endif()
# Don't look for packages in PATH if requested to.
if(QT_NO_USE_FIND_PACKAGE_SYSTEM_ENVIRONMENT_PATH)
@@ -77,16 +112,31 @@ macro(qt_find_package)
# in their own way. CMake has FindSQLite3.cmake and with the original
# qt_find_package(SQLite3) call it is our intention to use the cmake package
# in module mode.
- if (${ARGV0}_FOUND AND arg_PROVIDED_TARGETS)
- unset(any_target_found)
+ unset(_qt_any_target_found)
+ unset(_qt_should_unset_found_var)
+ if(${ARGV0}_FOUND AND arg_PROVIDED_TARGETS)
foreach(expected_target ${arg_PROVIDED_TARGETS})
if (TARGET ${expected_target})
- set(any_target_found TRUE)
+ set(_qt_any_target_found TRUE)
break()
endif()
endforeach()
- if(NOT any_target_found)
- unset(${ARGV0}_FOUND)
+ if(NOT _qt_any_target_found)
+ set(_qt_should_unset_found_var TRUE)
+ endif()
+ endif()
+ # If we consider the package not to be found, make sure to unset both regular
+ # and CACHE vars, otherwise CMP0126 set to NEW might cause issues with
+ # packages not being found correctly.
+ if(NOT ${ARGV0}_FOUND OR _qt_should_unset_found_var)
+ unset(${ARGV0}_FOUND)
+ unset(${ARGV0}_FOUND CACHE)
+
+ # Unset the NOTFOUND ${package}_DIR var that might have been set by the previous
+ # find_package call, to get rid of "not found" messages in the feature summary
+ # if the package is found by the next find_package call.
+ if(DEFINED CACHE{${ARGV0}_DIR} AND NOT ${ARGV0}_DIR)
+ unset(${ARGV0}_DIR CACHE)
endif()
endif()
endif()
@@ -102,13 +152,6 @@ macro(qt_find_package)
# E.g. find_package(Qt6 COMPONENTS BuildInternals) followed by
# qt_find_package(Qt6 COMPONENTS Core) doesn't end up calling find_package(Qt6Core).
if (NOT ${ARGV0}_FOUND AND NOT _qt_find_package_skip_find_package)
- # Unset the NOTFOUND ${package}_DIR var that might have been set by the previous
- # find_package call, to get rid of "not found" messagees in the feature summary
- # if the package is found by the next find_package call.
- if(DEFINED CACHE{${ARGV0}_DIR} AND NOT ${ARGV0}_DIR)
- unset(${ARGV0}_DIR CACHE)
- endif()
-
# Call original function without our custom arguments.
find_package(${arg_UNPARSED_ARGUMENTS})
endif()
@@ -121,6 +164,11 @@ macro(qt_find_package)
endif()
endif()
+ if(${ARGV0}_FOUND)
+ # Record that the package was found, so that future reconfigurations can be sped up.
+ set_property(GLOBAL APPEND PROPERTY _qt_previously_found_packages "${ARGV0}")
+ endif()
+
if(${ARGV0}_FOUND AND arg_PROVIDED_TARGETS AND NOT _qt_find_package_skip_find_package)
# If package was found, associate each target with its package name. This will be used
# later when creating Config files for Qt libraries, to generate correct find_dependency()
@@ -148,13 +196,19 @@ macro(qt_find_package)
PROPERTY INTERFACE_QT_PACKAGE_COMPONENTS ${components_as_string})
endif()
+ if(arg_OPTIONAL_COMPONENTS)
+ string(REPLACE ";" " " components_as_string "${arg_OPTIONAL_COMPONENTS}")
+ set_property(TARGET ${qt_find_package_target_name}
+ PROPERTY INTERFACE_QT_PACKAGE_OPTIONAL_COMPONENTS
+ ${components_as_string})
+ endif()
+
get_property(is_global TARGET ${qt_find_package_target_name} PROPERTY
IMPORTED_GLOBAL)
qt_internal_should_not_promote_package_target_to_global(
"${qt_find_package_target_name}" should_not_promote)
if(NOT is_global AND NOT should_not_promote)
- set_property(TARGET ${qt_find_package_target_name} PROPERTY
- IMPORTED_GLOBAL TRUE)
+ __qt_internal_promote_target_to_global(${qt_find_package_target_name})
qt_find_package_promote_targets_to_global_scope(
"${qt_find_package_target_name}")
endif()
@@ -174,6 +228,46 @@ macro(qt_find_package)
endif()
endmacro()
+# Save found packages in the cache. They will be read on next reconfiguration to skip looking
+# for packages that were not previously found.
+# Only applies to -developer-builds by default.
+# Can also be opted in or opted out via QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES.
+# Opting out will need two reconfigurations to take effect.
+function(qt_internal_save_previously_visited_packages)
+ if(DEFINED QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES)
+ set(should_save "${QT_INTERNAL_SAVE_PREVIOUSLY_FOUND_PACKAGES}")
+ else()
+ if(FEATURE_developer_build OR QT_FEATURE_developer_build)
+ set(should_save ON)
+ else()
+ set(should_save OFF)
+ endif()
+ endif()
+
+ if(NOT should_save)
+ # When the value is flipped to OFF, remove any previously saved packages.
+ unset(QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES CACHE)
+ unset(QT_INTERNAL_PREVIOUSLY_SEARCHED_PACKAGES CACHE)
+ return()
+ endif()
+
+ get_property(_qt_previously_found_packages GLOBAL PROPERTY _qt_previously_found_packages)
+ if(_qt_previously_found_packages)
+ list(REMOVE_DUPLICATES _qt_previously_found_packages)
+ set(QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES "${_qt_previously_found_packages}" CACHE INTERNAL
+ "List of CMake packages found during configuration using qt_find_package.")
+ endif()
+
+ get_property(_qt_previously_searched_packages GLOBAL PROPERTY _qt_previously_searched_packages)
+ if(_qt_previously_searched_packages)
+ list(REMOVE_DUPLICATES _qt_previously_searched_packages)
+ set(QT_INTERNAL_PREVIOUSLY_SEARCHED_PACKAGES
+ "${_qt_previously_searched_packages}" CACHE INTERNAL
+ "List of CMake packages searched during configuration using qt_find_package."
+ )
+ endif()
+endfunction()
+
# Return qmake library name for the given target, e.g. return "vulkan" for "Vulkan::Vulkan".
function(qt_internal_map_target_to_qmake_lib target out_var)
set(${out_var} "${QT_QMAKE_LIB_OF_TARGET_${target}}" PARENT_SCOPE)
@@ -203,17 +297,17 @@ endfunction()
# This function records a dependency between ${main_target_name} and ${dep_target_name}
# at the CMake package level.
-# E.g. Qt6CoreConfig.cmake needs to find_package(Qt6EntryPoint).
+# E.g. Qt6CoreConfig.cmake needs to find_package(Qt6EntryPointPrivate).
# main_target_name = Core
-# dep_target_name = EntryPoint
+# dep_target_name = EntryPointPrivate
# This is just a convenience function that deals with Qt targets and their associated packages
# instead of raw package names.
function(qt_record_extra_qt_package_dependency main_target_name dep_target_name
dep_package_version)
- # EntryPoint -> Qt6EntryPoint.
- qt_internal_module_info(qtfied_target_name "${dep_target_name}")
- qt_record_extra_package_dependency("${main_target_name}" "${qtfied_target_name_versioned}"
- "${dep_package_version}")
+ # EntryPointPrivate -> Qt6EntryPointPrivate.
+ qt_internal_qtfy_target(qtfied_target_name "${dep_target_name}")
+ qt_record_extra_package_dependency("${main_target_name}"
+ "${qtfied_target_name_versioned}" "${dep_package_version}")
endfunction()
# This function records a 'QtFooTools' package dependency for the ${main_target_name} target
@@ -249,12 +343,150 @@ function(qt_record_extra_qt_main_tools_package_dependency main_target_name
dep_non_versioned_package_name
dep_package_version)
# WaylandScannerTools -> Qt6WaylandScannerTools.
- qt_internal_module_info(qtfied_package_name "${dep_non_versioned_package_name}")
+ qt_internal_qtfy_target(qtfied_package_name "${dep_non_versioned_package_name}")
qt_record_extra_main_tools_package_dependency(
"${main_target_name}" "${qtfied_package_name_versioned}" "${dep_package_version}")
endfunction()
-# This function stores the list of Qt modules a library depend on,
+# Record an extra 3rd party target as a dependency for ${main_target_name}.
+#
+# Adds a find_package(${dep_target_package_name}) in ${main_target_name}Dependencies.cmake.
+#
+# Needed to record a dependency on the package that provides WrapVulkanHeaders::WrapVulkanHeaders.
+# The package version, components, whether the package is optional, etc, are queried from the
+# ${dep_target} target properties.
+# Usually these are set at the qt_find_package() call site of a configure.cmake file e.g. using
+# Qt's MARK_OPTIONAL option.
+function(qt_record_extra_third_party_dependency main_target_name dep_target)
+ if(NOT TARGET "${main_target_name}")
+ qt_get_tool_target_name(main_target_name "${main_target_name}")
+ endif()
+ if(TARGET "${main_target_name}")
+ get_target_property(extra_deps "${main_target_name}" _qt_extra_third_party_dep_targets)
+ if(NOT extra_deps)
+ set(extra_deps "")
+ endif()
+
+ list(APPEND extra_deps "${dep_target}")
+ set_target_properties("${main_target_name}" PROPERTIES _qt_extra_third_party_dep_targets
+ "${extra_deps}")
+ endif()
+endfunction()
+
+# Sets out_var to TRUE if the non-namespaced ${lib} target is exported as part of Qt6Targets.cmake.
+function(qt_internal_is_lib_part_of_qt6_package lib out_var)
+ if (lib STREQUAL "Platform"
+ OR lib STREQUAL "GlobalConfig"
+ OR lib STREQUAL "GlobalConfigPrivate"
+ OR lib STREQUAL "PlatformModuleInternal"
+ OR lib STREQUAL "PlatformPluginInternal"
+ OR lib STREQUAL "PlatformToolInternal"
+ OR lib STREQUAL "PlatformCommonInternal"
+ )
+ set(${out_var} "TRUE" PARENT_SCOPE)
+ else()
+ set(${out_var} "FALSE" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Try to get the CMake package version of a Qt target.
+#
+# Query the target's _qt_package_version property, or try to read it from the CMake package version
+# variable set from calling find_package(Qt6${target}).
+# Not all targets will have a find_package _VERSION variable, for example if the target is an
+# executable.
+# A heuristic is used to handle QtFooPrivate module targets.
+# If no version can be found, fall back to ${PROJECT_VERSION} and issue a warning.
+function(qt_internal_get_package_version_of_target target package_version_out_var)
+ qt_internal_is_lib_part_of_qt6_package("${target}" is_part_of_qt6)
+
+ if(is_part_of_qt6)
+ # When building qtbase, Qt6_VERSION is not set (unless examples are built in-tree,
+ # non-ExternalProject). Use the Platform target's version instead which would be the
+ # equivalent.
+ if(TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::Platform")
+ get_target_property(package_version
+ "${QT_CMAKE_EXPORT_NAMESPACE}::Platform" _qt_package_version)
+ endif()
+ if(NOT package_version)
+ set(package_version "${${QT_CMAKE_EXPORT_NAMESPACE}_VERSION}")
+ endif()
+ else()
+ # Try to get the version from the target.
+ # Try the Private target first and if it doesn't exist, try the non-Private target later.
+ if(TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
+ get_target_property(package_version
+ "${QT_CMAKE_EXPORT_NAMESPACE}::${target}" _qt_package_version)
+ endif()
+
+ # Try to get the version from the corresponding package version variable.
+ if(NOT package_version)
+ set(package_version "${${QT_CMAKE_EXPORT_NAMESPACE}${target}_VERSION}")
+ endif()
+
+ # Try non-Private target.
+ if(NOT package_version AND target MATCHES "(.*)Private$")
+ set(target "${CMAKE_MATCH_1}")
+ endif()
+
+ if(NOT package_version AND TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
+ get_target_property(package_version
+ "${QT_CMAKE_EXPORT_NAMESPACE}::${target}" _qt_package_version)
+ endif()
+
+ if(NOT package_version)
+ set(package_version "${${QT_CMAKE_EXPORT_NAMESPACE}${target}_VERSION}")
+ endif()
+ endif()
+
+ if(NOT package_version)
+ set(package_version "${PROJECT_VERSION}")
+ if(FEATURE_developer_build)
+ message(WARNING
+ "Could not determine package version of target ${target}. "
+ "Defaulting to project version ${PROJECT_VERSION}.")
+ endif()
+ endif()
+
+ set(${package_version_out_var} "${package_version}" PARENT_SCOPE)
+endfunction()
+
+# Get the CMake package name that contains / exported the Qt module target.
+function(qt_internal_get_package_name_of_target target package_name_out_var)
+ qt_internal_is_lib_part_of_qt6_package("${target}" is_part_of_qt6)
+
+ if(is_part_of_qt6)
+ set(package_name "${INSTALL_CMAKE_NAMESPACE}")
+ else()
+ # Get the package name from the module's target property.
+ # If not set, fallback to a name based on the target name.
+ #
+ # TODO: Remove fallback once sufficient time has passed, aka all developers updated
+ # their builds not to contain stale FooDependencies.cmakes files without the
+ # _qt_package_name property.
+ set(package_name "")
+ set(package_name_default "${INSTALL_CMAKE_NAMESPACE}${target}")
+ set(target_namespaced "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
+ if(TARGET "${target_namespaced}")
+ get_target_property(package_name_from_prop "${target_namespaced}" _qt_package_name)
+ if(package_name_from_prop)
+ set(package_name "${package_name_from_prop}")
+ endif()
+ endif()
+ if(NOT package_name)
+ message(WARNING
+ "Could not find target ${target_namespaced} to query its package name. "
+ "Defaulting to package name ${package_name_default}. Consider re-arranging the "
+ "project structure to ensure the target exists by this point."
+ )
+ set(package_name "${package_name_default}")
+ endif()
+ endif()
+
+ set(${package_name_out_var} "${package_name}" PARENT_SCOPE)
+endfunction()
+
+# This function stores the list of Qt targets a library depend on,
# along with their version info, for usage in ${target}Depends.cmake file
function(qt_register_target_dependencies target public_libs private_libs)
get_target_property(target_deps "${target}" _qt_target_deps)
@@ -262,31 +494,74 @@ function(qt_register_target_dependencies target public_libs private_libs)
set(target_deps "")
endif()
- # Only process private dependencies if target is a static library
get_target_property(target_type ${target} TYPE)
set(lib_list ${public_libs})
- if (target_type STREQUAL "STATIC_LIBRARY")
+
+ set(target_is_shared FALSE)
+ set(target_is_static FALSE)
+ if(target_type STREQUAL "SHARED_LIBRARY")
+ set(target_is_shared TRUE)
+ elseif(target_type STREQUAL "STATIC_LIBRARY")
+ set(target_is_static TRUE)
+ endif()
+
+ # Record 'Qt::Foo'-like private dependencies of static library targets, this will be used to
+ # generate find_dependency() calls.
+ #
+ # Private static library dependencies will become $<LINK_ONLY:> dependencies in
+ # INTERFACE_LINK_LIBRARIES.
+ if(target_is_static)
list(APPEND lib_list ${private_libs})
endif()
foreach(lib IN LISTS lib_list)
- if ("${lib}" MATCHES "^Qt::(.*)")
+ if("${lib}" MATCHES "^Qt::(.*)")
set(lib "${CMAKE_MATCH_1}")
- if (lib STREQUAL Platform
- OR lib STREQUAL GlobalConfig
- OR lib STREQUAL GlobalConfigPrivate
- OR lib STREQUAL PlatformModuleInternal
- OR lib STREQUAL PlatformPluginInternal
- OR lib STREQUAL PlatformToolInternal)
- list(APPEND target_deps "Qt6\;${PROJECT_VERSION}")
- elseif ("${lib}" MATCHES "(.*)Private")
- list(APPEND target_deps "${INSTALL_CMAKE_NAMESPACE}${CMAKE_MATCH_1}\;${PROJECT_VERSION}")
- else()
- list(APPEND target_deps "${INSTALL_CMAKE_NAMESPACE}${lib}\;${PROJECT_VERSION}")
- endif()
+ elseif("${lib}" MATCHES "^${QT_CMAKE_EXPORT_NAMESPACE}::(.*)")
+ set(lib "${CMAKE_MATCH_1}")
+ else()
+ set(lib "")
+ endif()
+
+ if(lib)
+ qt_internal_get_package_name_of_target("${lib}" package_name)
+ qt_internal_get_package_version_of_target("${lib}" package_version)
+ list(APPEND target_deps "${package_name}\;${package_version}")
endif()
endforeach()
+ # Record 'Qt::Foo'-like shared private dependencies of shared library targets.
+ #
+ # Private shared library dependencies are listed in the target's
+ # IMPORTED_LINK_DEPENDENT_LIBRARIES and used in rpath-link calculation.
+ # See QTBUG-86533 for some details.
+ # We filter out static libraries and common platform targets, but include both SHARED and
+ # INTERFACE libraries. INTERFACE libraries in most cases will be FooPrivate libraries.
+ if(target_is_shared AND private_libs)
+ foreach(lib IN LISTS private_libs)
+ set(lib_namespaced "${lib}")
+ if("${lib}" MATCHES "^Qt::(.*)")
+ set(lib "${CMAKE_MATCH_1}")
+ elseif("${lib}" MATCHES "^${QT_CMAKE_EXPORT_NAMESPACE}::(.*)")
+ set(lib "${CMAKE_MATCH_1}")
+ else()
+ set(lib "")
+ endif()
+
+ if(lib)
+ set(lib "${CMAKE_MATCH_1}")
+
+ qt_internal_is_lib_part_of_qt6_package("${lib}" is_part_of_qt6)
+ get_target_property(lib_type "${lib_namespaced}" TYPE)
+ if(NOT lib_type STREQUAL "STATIC_LIBRARY" AND NOT is_part_of_qt6)
+ qt_internal_get_package_name_of_target("${lib}" package_name)
+ qt_internal_get_package_version_of_target("${lib}" package_version)
+ list(APPEND target_deps "${package_name}\;${package_version}")
+ endif()
+ endif()
+ endforeach()
+ endif()
+
set_target_properties("${target}" PROPERTIES _qt_target_deps "${target_deps}")
endfunction()
@@ -295,7 +570,3 @@ function(qt_internal_should_not_promote_package_target_to_global target out_var)
get_property(should_not_promote TARGET "${target}" PROPERTY _qt_no_promote_global)
set("${out_var}" "${should_not_promote}" PARENT_SCOPE)
endfunction()
-
-function(qt_internal_disable_find_package_global_promotion target)
- set_target_properties("${target}" PROPERTIES _qt_no_promote_global TRUE)
-endfunction()