summaryrefslogtreecommitdiffstats
path: root/cmake/QtFindPackageHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtFindPackageHelpers.cmake')
-rw-r--r--cmake/QtFindPackageHelpers.cmake137
1 files changed, 131 insertions, 6 deletions
diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake
index 407e41b833..b71226f322 100644
--- a/cmake/QtFindPackageHelpers.cmake
+++ b/cmake/QtFindPackageHelpers.cmake
@@ -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)
@@ -41,10 +50,13 @@ macro(qt_find_package)
# 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)
+ 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})
@@ -178,6 +190,15 @@ macro(qt_find_package)
PROPERTIES INTERFACE_QT_PACKAGE_VERSION ${ARGV1})
endif()
+ # Save the retrieved package version.
+ set(_qt_find_package_found_version "")
+ if(${ARGV0}_VERSION)
+ set(_qt_find_package_found_version "${${ARGV0}_VERSION}")
+ set_target_properties(${qt_find_package_target_name}
+ PROPERTIES
+ _qt_package_found_version "${_qt_find_package_found_version}")
+ endif()
+
if(arg_COMPONENTS)
string(REPLACE ";" " " components_as_string "${arg_COMPONENTS}")
set_property(TARGET ${qt_find_package_target_name}
@@ -191,6 +212,18 @@ macro(qt_find_package)
${components_as_string})
endif()
+ # Work around: QTBUG-125371
+ if(NOT "${ARGV0}" STREQUAL "Qt6")
+ # Record the package + component + optional component provided targets.
+ qt_internal_record_package_component_provided_targets(
+ PACKAGE_NAME "${ARGV0}"
+ ON_TARGET ${qt_find_package_target_name}
+ PROVIDED_TARGETS ${arg_PROVIDED_TARGETS}
+ COMPONENTS ${arg_COMPONENTS}
+ OPTIONAL_COMPONENTS ${arg_OPTIONAL_COMPONENTS}
+ )
+ endif()
+
get_property(is_global TARGET ${qt_find_package_target_name} PROPERTY
IMPORTED_GLOBAL)
qt_internal_should_not_promote_package_target_to_global(
@@ -200,8 +233,25 @@ macro(qt_find_package)
qt_find_package_promote_targets_to_global_scope(
"${qt_find_package_target_name}")
endif()
- endif()
+ set(_qt_find_package_sbom_args "")
+
+ if(_qt_find_package_found_version)
+ list(APPEND _qt_find_package_sbom_args
+ PACKAGE_VERSION "${_qt_find_package_found_version}"
+ )
+ endif()
+
+ # Work around: QTBUG-125371
+ if(NOT "${ARGV0}" STREQUAL "Qt6")
+ _qt_internal_sbom_record_system_library_usage(
+ "${qt_find_package_target_name}"
+ TYPE SYSTEM_LIBRARY
+ FRIENDLY_PACKAGE_NAME "${ARGV0}"
+ ${_qt_find_package_sbom_args}
+ )
+ endif()
+ endif()
endforeach()
if(arg_MODULE_NAME AND arg_QMAKE_LIB
@@ -216,12 +266,62 @@ macro(qt_find_package)
endif()
endmacro()
+# Records information about a package's provided targets, given a specific list of components.
+#
+# A package might contain multiple components, and create only a subset of targets based on which
+# components are looked for.
+# This function computes a unique key / id using the package name and the components that are
+# passed.
+# Then it saves the id in a property on the ON_TARGET target. The ON_TARGET target is one
+# of the provided targets for that package id. This allows us to create a relationship to find
+# the package id, given a target.
+# The function also appends the list of provided targets for that package id to a global property.
+# This information will later be saved into the module Dependencies.cmake file.
+function(qt_internal_record_package_component_provided_targets)
+ set(opt_args "")
+ set(single_args
+ PACKAGE_NAME
+ ON_TARGET
+ )
+ set(multi_args
+ COMPONENTS
+ OPTIONAL_COMPONENTS
+ PROVIDED_TARGETS
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_PACKAGE_NAME)
+ message(FATAL_ERROR "PACKAGE_NAME is required.")
+ endif()
+
+ if(NOT arg_ON_TARGET)
+ message(FATAL_ERROR "ON_TARGET is required.")
+ endif()
+
+ _qt_internal_get_package_components_id(
+ PACKAGE_NAME "${arg_PACKAGE_NAME}"
+ COMPONENTS ${arg_COMPONENTS}
+ OPTIONAL_COMPONENTS ${arg_OPTIONAL_COMPONENTS}
+ OUT_VAR_KEY package_key
+ )
+
+ set_target_properties(${arg_ON_TARGET} PROPERTIES
+ _qt_package_components_id "${package_key}"
+ )
+
+ _qt_internal_append_to_cmake_property_without_duplicates(
+ _qt_find_package_${package_key}_provided_targets
+ "${arg_PROVIDED_TARGETS}"
+ )
+endfunction()
+
# 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_found_packages)
+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()
@@ -235,6 +335,7 @@ function(qt_internal_save_previously_found_packages)
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()
@@ -244,6 +345,15 @@ function(qt_internal_save_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".
@@ -493,8 +603,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}")
@@ -510,8 +627,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)