summaryrefslogtreecommitdiffstats
path: root/cmake/QtFindPackageHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtFindPackageHelpers.cmake')
-rw-r--r--cmake/QtFindPackageHelpers.cmake91
1 files changed, 87 insertions, 4 deletions
diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake
index 6fae5346da..dd10bde75a 100644
--- a/cmake/QtFindPackageHelpers.cmake
+++ b/cmake/QtFindPackageHelpers.cmake
@@ -1,5 +1,5 @@
# Copyright (C) 2022 The Qt Company Ltd.
-# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+# 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.
@@ -16,6 +16,15 @@ function(qt_find_package_promote_targets_to_global_scope target)
"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)
@@ -34,6 +43,20 @@ macro(qt_find_package)
# 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})
@@ -141,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()
@@ -200,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)
@@ -447,8 +515,15 @@ function(qt_register_target_dependencies target public_libs private_libs)
endif()
foreach(lib IN LISTS lib_list)
- if ("${lib}" MATCHES "^Qt::(.*)")
+ 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)
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}")
@@ -464,8 +539,16 @@ function(qt_register_target_dependencies target public_libs private_libs)
# INTERFACE libraries. INTERFACE libraries in most cases will be FooPrivate libraries.
if(target_is_shared AND private_libs)
foreach(lib IN LISTS private_libs)
- if ("${lib}" MATCHES "^Qt::(.*)")
- set(lib_namespaced "${lib}")
+ 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)