396e6daea4
For -developer-buildS qt_find_package caches which packages were found
on the first configuration, to make the build system pick up a newly
added qt_find_package call one needs to follow one of the methods
that are now mentioned in the docs.
Hugely based on commit message from commit
6847a19e3e
.
Change-Id: I4a13d3c97a6172f504a57298c4b3edee30d21250
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
545 lines
25 KiB
CMake
545 lines
25 KiB
CMake
# 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.
|
|
#
|
|
# This is required for .prl file generation in top-level builds, to make sure that imported 3rd
|
|
# party library targets in any repo are made global, so there are no scoping issues.
|
|
#
|
|
# 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.
|
|
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")
|
|
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 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 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)
|
|
set(_qt_find_package_skip_find_package TRUE)
|
|
endif()
|
|
|
|
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})
|
|
if(NOT TARGET ${qt_find_package_target_name})
|
|
set(_qt_find_package_skip_find_package FALSE)
|
|
endif()
|
|
endforeach()
|
|
|
|
if(_qt_find_package_skip_find_package)
|
|
message(AUTHOR_WARNING "qt_find_package(${ARGV0}) called even though the package "
|
|
"was already found. Consider removing the call.")
|
|
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)
|
|
if(${ARGV1} MATCHES "^[0-9\.]+$")
|
|
set(package_version "${ARGV1}")
|
|
endif()
|
|
endif()
|
|
|
|
if(arg_COMPONENTS)
|
|
# Re-append components to forward them.
|
|
list(APPEND arg_UNPARSED_ARGUMENTS "COMPONENTS;${arg_COMPONENTS}")
|
|
endif()
|
|
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)
|
|
set(_qt_find_package_use_system_env_backup "${CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH}")
|
|
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH "OFF")
|
|
endif()
|
|
|
|
if(NOT (arg_CONFIG OR arg_NO_MODULE OR arg_MODULE) AND NOT _qt_find_package_skip_find_package)
|
|
# Try to find a config package first in quiet mode
|
|
set(config_package_arg ${arg_UNPARSED_ARGUMENTS})
|
|
list(APPEND config_package_arg "CONFIG;QUIET")
|
|
find_package(${config_package_arg})
|
|
|
|
# Double check that in config mode the targets become visible. Sometimes
|
|
# only the module mode creates the targets. For example with vcpkg, the sqlite
|
|
# package provides sqlite3-config.cmake, which offers multi-config targets but
|
|
# 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.
|
|
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(_qt_any_target_found TRUE)
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
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()
|
|
|
|
# Ensure the options are back in the original unparsed arguments
|
|
foreach(opt IN LISTS find_package_options)
|
|
if(arg_${opt})
|
|
list(APPEND arg_UNPARSED_ARGUMENTS ${opt})
|
|
endif()
|
|
endforeach()
|
|
|
|
# TODO: Handle packages with components where a previous component is already found.
|
|
# 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)
|
|
# Call original function without our custom arguments.
|
|
find_package(${arg_UNPARSED_ARGUMENTS})
|
|
endif()
|
|
|
|
if(QT_NO_USE_FIND_PACKAGE_SYSTEM_ENVIRONMENT_PATH)
|
|
if("${_qt_find_package_use_system_env_backup}" STREQUAL "")
|
|
unset(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH)
|
|
else()
|
|
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH "${_qt_find_package_use_system_env_backup}")
|
|
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()
|
|
# calls. Also make the provided targets global, so that the properties can be read in
|
|
# all scopes.
|
|
foreach(qt_find_package_target_name ${arg_PROVIDED_TARGETS})
|
|
if(TARGET ${qt_find_package_target_name})
|
|
# Allow usage of aliased targets by setting properties on the actual target
|
|
get_target_property(aliased_target ${qt_find_package_target_name} ALIASED_TARGET)
|
|
if(aliased_target)
|
|
set(qt_find_package_target_name ${aliased_target})
|
|
endif()
|
|
|
|
set_target_properties(${qt_find_package_target_name} PROPERTIES
|
|
INTERFACE_QT_PACKAGE_NAME ${ARGV0}
|
|
INTERFACE_QT_PACKAGE_IS_OPTIONAL ${arg_MARK_OPTIONAL})
|
|
if(package_version)
|
|
set_target_properties(${qt_find_package_target_name}
|
|
PROPERTIES INTERFACE_QT_PACKAGE_VERSION ${ARGV1})
|
|
endif()
|
|
|
|
if(arg_COMPONENTS)
|
|
string(REPLACE ";" " " components_as_string "${arg_COMPONENTS}")
|
|
set_property(TARGET ${qt_find_package_target_name}
|
|
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)
|
|
__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()
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
if(arg_MODULE_NAME AND arg_QMAKE_LIB
|
|
AND (NOT arg_QMAKE_LIB IN_LIST QT_QMAKE_LIBS_FOR_${arg_MODULE_NAME}))
|
|
set(QT_QMAKE_LIBS_FOR_${arg_MODULE_NAME}
|
|
${QT_QMAKE_LIBS_FOR_${arg_MODULE_NAME}};${arg_QMAKE_LIB} CACHE INTERNAL "")
|
|
set(QT_TARGETS_OF_QMAKE_LIB_${arg_QMAKE_LIB} ${arg_PROVIDED_TARGETS} CACHE INTERNAL "")
|
|
foreach(provided_target ${arg_PROVIDED_TARGETS})
|
|
set(QT_QMAKE_LIB_OF_TARGET_${provided_target} ${arg_QMAKE_LIB} CACHE INTERNAL "")
|
|
endforeach()
|
|
endif()
|
|
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_found_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)
|
|
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()
|
|
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)
|
|
endfunction()
|
|
|
|
# This function records a dependency between ${main_target_name} and ${dep_package_name}.
|
|
# at the CMake package level.
|
|
# E.g. The Tools package that provides the qtwaylandscanner target
|
|
# needs to call find_package(WaylandScanner) (non-qt-package).
|
|
# main_target_name = qtwaylandscanner
|
|
# dep_package_name = WaylandScanner
|
|
function(qt_record_extra_package_dependency main_target_name dep_package_name dep_package_version)
|
|
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_packages "${main_target_name}" QT_EXTRA_PACKAGE_DEPENDENCIES)
|
|
if(NOT extra_packages)
|
|
set(extra_packages "")
|
|
endif()
|
|
|
|
list(APPEND extra_packages "${dep_package_name}\;${dep_package_version}")
|
|
set_target_properties("${main_target_name}" PROPERTIES QT_EXTRA_PACKAGE_DEPENDENCIES
|
|
"${extra_packages}")
|
|
endif()
|
|
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(Qt6EntryPointPrivate).
|
|
# main_target_name = Core
|
|
# 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)
|
|
# 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
|
|
# onto the ${dep_package_name} tools package.
|
|
# E.g. The QtWaylandCompositor package needs to call find_package(QtWaylandScannerTools).
|
|
# main_target_name = WaylandCompositor
|
|
# dep_package_name = Qt6WaylandScannerTools
|
|
function(qt_record_extra_main_tools_package_dependency
|
|
main_target_name dep_package_name dep_package_version)
|
|
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_packages "${main_target_name}"
|
|
QT_EXTRA_TOOLS_PACKAGE_DEPENDENCIES)
|
|
if(NOT extra_packages)
|
|
set(extra_packages "")
|
|
endif()
|
|
|
|
list(APPEND extra_packages "${dep_package_name}\;${dep_package_version}")
|
|
set_target_properties("${main_target_name}" PROPERTIES QT_EXTRA_TOOLS_PACKAGE_DEPENDENCIES
|
|
"${extra_packages}")
|
|
endif()
|
|
endfunction()
|
|
|
|
# This function records a 'QtFooTools' package dependency for the ${main_target_name} target
|
|
# onto the ${dep_non_versioned_package_name} Tools package.
|
|
# main_target_name = WaylandCompositor
|
|
# dep_non_versioned_package_name = WaylandScannerTools
|
|
# This is just a convenience function to avoid hardcoding the qtified version in the dep package
|
|
# name.
|
|
function(qt_record_extra_qt_main_tools_package_dependency main_target_name
|
|
dep_non_versioned_package_name
|
|
dep_package_version)
|
|
# WaylandScannerTools -> Qt6WaylandScannerTools.
|
|
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()
|
|
|
|
# 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)
|
|
if(NOT target_deps)
|
|
set(target_deps "")
|
|
endif()
|
|
|
|
get_target_property(target_type ${target} TYPE)
|
|
set(lib_list ${public_libs})
|
|
|
|
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::(.*)")
|
|
set(lib "${CMAKE_MATCH_1}")
|
|
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)
|
|
if ("${lib}" MATCHES "^Qt::(.*)")
|
|
set(lib_namespaced "${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()
|
|
|
|
# Sets out_var to to TRUE if the target was marked to not be promoted to global scope.
|
|
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()
|