CMake: Conditionally pass PATHS to FindWrapHelper package lookup

The setup:
- build Qt with '-static -qt-zlib'
- configure a user project with plain cmake and -DQt6_DIR pointing to
  the Qt6 package

In this case, the implicit find_dependency(BundledZlib) call will
fail with:

CMake Error at lib/cmake/Qt6/QtFindWrapHelper.cmake:120 (message):
  Can't find Qt6::BundledZLIB.
Call Stack (most recent call first):
  lib/cmake/Qt6/FindWrapZLIB.cmake:6 (qt_find_package_system_or_bundled)
  cmake/share/cmake-3.31/Modules/CMakeFindDependencyMacro.cmake:76
    (find_package)
  lib/cmake/Qt6/QtPublicDependencyHelpers.cmake:36 (find_dependency)
  lib/cmake/Qt6Core/Qt6CoreDependencies.cmake:39
    (_qt_internal_find_third_party_dependencies)
  lib/cmake/Qt6Core/Qt6CoreConfig.cmake:42 (include)
  lib/cmake/Qt6/Qt6Config.cmake:233 (find_package)
  CMakeLists.txt:7 (find_package)

For example it would fail for the rasterwindow example configured with:
 cmake ~/qtbase/examples/gui/rasterwindow \
   -DQt6_DIR=$HOME/builds/dev-mac-static/qtbase/lib/cmake/Qt6

The failure happens because we don't pass any additional paths to the
find_package call that looks for BundledZlib, as opposed to how we do
it for module packages.

The project configuration does not fail if it is configured with any
of the following variables:
- Qt6_ROOT or
- CMAKE_PREFIX_PATH or
- the Qt generated toolchain file.

That's because these implicitly add relevant paths where to look for
Qt packages.

This came up in qtdeclarative RunCMake CI tests, where we only pass
Qt6_DIR to the test projects. It didn't come up in qtbase, because
none of the current qtbase RunCMake tests try to find Qt6Core.

To fix this particular case, conditionally pass the same paths that
Qt6Config.cmake uses when looking for module packages, to the
find_package call that looks for the bundled target.

We do it conditionally for bundled targets only, because for system
libraries we want to default looking for the module
FindWrapSystemFoo.cmake files.

Add a RunCMake test which will try to find a few Qt modules solely
based on having only Qt6_DIR set.

Pick-to: 6.8 6.9
Change-Id: I4d4e548f4c10370c4964ab8968b5772e26855dd4
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Alexandru Croitor 2025-05-06 18:28:42 +02:00
parent 57191901d7
commit 15178c9919
5 changed files with 76 additions and 1 deletions

View File

@ -66,7 +66,26 @@ macro(qt_find_package_system_or_bundled _unique_prefix)
endif()
if(NOT TARGET "${${_unique_prefix}_qt_package_target_to_use}")
find_package("${${_unique_prefix}_qt_package_name_to_use}")
if(QT_USE_BUNDLED_${_qfwrap_${_unique_prefix}_BUNDLED_PACKAGE_TARGET})
set(${_unique_prefix}_qt_use_no_default_path_for_qt_packages "NO_DEFAULT_PATH")
if(QT_DISABLE_NO_DEFAULT_PATH_IN_QT_PACKAGES)
set(${_unique_prefix}_qt_use_no_default_path_for_qt_packages "")
endif()
# For bundled targets, we want to limit search paths to the relevant Qt search paths.
find_package("${${_unique_prefix}_qt_package_name_to_use}"
PATHS
${QT_BUILD_CMAKE_PREFIX_PATH}
"${CMAKE_CURRENT_LIST_DIR}/.."
${_qt_cmake_dir}
${_qt_additional_packages_prefix_paths}
${${_unique_prefix}_qt_use_no_default_path_for_qt_packages}
)
else()
# For the non-bundled case we will look for FindWrapSystemFoo.cmake module files,
# which means we should not specify any PATHS.
find_package("${${_unique_prefix}_qt_package_name_to_use}")
endif()
endif()
if(TARGET "${${_unique_prefix}_qt_package_target_to_use}")

View File

@ -1,3 +1,18 @@
# Add RunCMake tests using `add_RunCMake_test()`
add_RunCMake_test(QtFlagHandlingHelpers "-DQt6_DIR=${Qt6_DIR}")
set(extra_run_cmake_args "-DQt6_DIR=${Qt6_DIR}")
if(TARGET Qt::Gui)
list(APPEND extra_run_cmake_args "-DHAS_GUI=TRUE")
endif()
if(TARGET Qt::DBus)
list(APPEND extra_run_cmake_args "-DHAS_DBUS=TRUE")
endif()
if(TARGET Qt::Widgets)
list(APPEND extra_run_cmake_args "-DHAS_WIDGETS=TRUE")
endif()
if(TARGET Qt::OpenGL)
list(APPEND extra_run_cmake_args "-DHAS_OPENGL=TRUE")
endif()
add_RunCMake_test(Qt6DirConfiguration ${extra_run_cmake_args})

View File

@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.16)
project(${RunCMake_TEST} LANGUAGES CXX)
include(${RunCMake_TEST}.cmake)

View File

@ -0,0 +1,19 @@
include(RunCMake)
set(cmake_opts "-DQt6_DIR=${Qt6_DIR}")
# Depending on which module features were used when building Qt, look up each of the respective
# packages.
if(HAS_GUI)
list(APPEND cmake_opts "-DHAS_GUI=TRUE")
endif()
if(HAS_DBUS)
list(APPEND cmake_opts "-DHAS_DBUS=TRUE")
endif()
if(HAS_WIDGETS)
list(APPEND cmake_opts "-DHAS_WIDGETS=TRUE")
endif()
if(HAS_OPENGL)
list(APPEND cmake_opts "-DHAS_OPENGL=TRUE")
endif()
run_cmake_with_options(project ${cmake_opts})

View File

@ -0,0 +1,19 @@
# This should successfully find the Qt6::BundledZLIB package in a -qt-zlib
# configuration.
find_package(Qt6 COMPONENTS Core)
# Depending on which module features were used when building Qt, look up each of the respective
# packages, those might also look for bundled libraries.
if(HAS_GUI)
find_package(Qt6 COMPONENTS Gui)
endif()
if(HAS_DBUS)
find_package(Qt6 COMPONENTS DBus)
endif()
if(HAS_WIDGETS)
find_package(Qt6 COMPONENTS Widgets)
endif()
if(HAS_OPENGL)
find_package(Qt6 COMPONENTS OpenGL)
endif()