diff options
Diffstat (limited to 'cmake/QtFindPackageHelpers.cmake')
-rw-r--r-- | cmake/QtFindPackageHelpers.cmake | 91 |
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) |