CMake: Record the precise package name where Private modules live

Previously if a target depended on CorePrivate, we would write a
_qt_internal_find_qt_dependencies(... Qt6CorePrivate) call into a
FooDependencies.cmake file.
That find_qt_deps call would remove the 'Private' suffix and would run
find_dependency with NAMES set to both the altered and non-altered
names.
This would find the relevant package but it would set the wrong
_FOUND variable name, e.g it would set Qt6CorePrivate_FOUND instead
of Qt6Core_FOUND.
This in turn could cause multiple lookups of the Qt6Core package
during dependency handling because the correct _FOUND var would not be
set.

Instead of always looking for the Qt6CorePrivate package, make sure
we look for an appropriately named package for all Privates modules,
because we have the necessary info to determine the correct name.

Note that INTERNAL modules will still be looked up via a Private
suffixed package name because that's how the package name is chosen
for them.

Remove the code that accounted for Private modules in
qt_internal_remove_qt_dependency_duplicates because it's not needed
anymore.

Warn when a package name can't be queried from a target's property
because the target might not exist yet.

Add a TODO comment for the code that searches with two NAMES.
We can't remove it right now, because it might break user projects
that use stale Dependencies.cmake files.

The dbus subdirectory is added before the tools subdirectory
to ensure that the new package name extraction does not error out, due
to trying to access a target that does not yet exist.

Amends 425ff34aa1

Pick-to: 6.4
Task-number: QTBUG-104998
Change-Id: Ib34ae5ed92f68b4265518c2b8802daeb1a3a04d6
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Alexandru Croitor 2022-07-19 18:12:18 +02:00
parent d48e596b3c
commit dffcc2370e
4 changed files with 46 additions and 14 deletions

View File

@ -378,6 +378,41 @@ function(qt_internal_get_package_version_of_target target package_version_out_va
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)
@ -409,14 +444,9 @@ function(qt_register_target_dependencies target public_libs private_libs)
foreach(lib IN LISTS lib_list)
if ("${lib}" MATCHES "^Qt::(.*)")
set(lib "${CMAKE_MATCH_1}")
qt_internal_is_lib_part_of_qt6_package("${lib}" is_part_of_qt6)
qt_internal_get_package_name_of_target("${lib}" package_name)
qt_internal_get_package_version_of_target("${lib}" package_version)
if (is_part_of_qt6)
list(APPEND target_deps "Qt6\;${package_version}")
else()
list(APPEND target_deps "${INSTALL_CMAKE_NAMESPACE}${lib}\;${package_version}")
endif()
list(APPEND target_deps "${package_name}\;${package_version}")
endif()
endforeach()
@ -436,8 +466,9 @@ function(qt_register_target_dependencies target public_libs private_libs)
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 "${INSTALL_CMAKE_NAMESPACE}${lib}\;${package_version}")
list(APPEND target_deps "${package_name}\;${package_version}")
endif()
endif()
endforeach()

View File

@ -80,11 +80,6 @@ function(qt_internal_remove_qt_dependency_duplicates out_deps deps)
if(dep)
list(FIND ${out_deps} "${dep}" dep_seen)
# If the library depends on the Private and non-Private targets,
# we only need to 'find_dependency' for one of them.
if(dep_seen EQUAL -1 AND "${dep}" MATCHES "(.+)Private\;(.+)")
list(FIND ${out_deps} "${CMAKE_MATCH_1};${CMAKE_MATCH_2}" dep_seen)
endif()
if(dep_seen EQUAL -1)
list(LENGTH dep len)
if(NOT (len EQUAL 2))

View File

@ -94,6 +94,10 @@ macro(_qt_internal_find_qt_dependencies target target_dep_list find_dependency_p
list(GET __qt_${target}_target_dep 1 __qt_${target}_version)
if (NOT ${__qt_${target}_pkg}_FOUND)
# TODO: Remove Private handling once sufficient time has passed, aka all developers
# updated their builds not to contain stale FooDependencies.cmake files without the
# _qt_package_name property.
set(__qt_${target}_pkg_names ${__qt_${target}_pkg})
if(__qt_${target}_pkg MATCHES "(.*)Private$")
set(__qt_${target}_pkg_names "${CMAKE_MATCH_1};${__qt_${target}_pkg}")

View File

@ -58,11 +58,13 @@ endif()
if (QT_FEATURE_xml)
add_subdirectory(xml)
endif()
add_subdirectory(tools)
if (QT_FEATURE_dbus)
add_subdirectory(dbus)
endif()
add_subdirectory(tools)
if(QT_FEATURE_gui)
add_subdirectory(gui)