diff --git a/cmake/QtConfig.cmake.in b/cmake/QtConfig.cmake.in index 2c4058f0da1..7ad92faeb24 100644 --- a/cmake/QtConfig.cmake.in +++ b/cmake/QtConfig.cmake.in @@ -47,9 +47,41 @@ elseif(APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS") list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/ios") endif() -set(QT_ADDITIONAL_PACKAGES_PREFIX_PATH "" CACHE STRING "Additional directories where find(Qt6 ...) components are searched") -file(TO_CMAKE_PATH "${QT_ADDITIONAL_PACKAGES_PREFIX_PATH}" _qt_additional_packages_prefix_path) -file(TO_CMAKE_PATH "$ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH}" _qt_additional_packages_prefix_path_env) +set(QT_ADDITIONAL_PACKAGES_PREFIX_PATH "" CACHE STRING + "Additional directories where find(Qt6 ...) components are searched") + +# Collect additional package prefix paths to look for Qt packages, both from command line and the +# env variable. +if(NOT DEFINED _qt_additional_packages_prefix_paths) + set(_qt_additional_packages_prefix_paths "") + + set(_qt_additional_packages_prefixes "") + if(QT_ADDITIONAL_PACKAGES_PREFIX_PATH) + list(APPEND _qt_additional_packages_prefixes ${QT_ADDITIONAL_PACKAGES_PREFIX_PATH}) + endif() + if(DEFINED ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH} + AND NOT "$ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH}" STREQUAL "") + list(APPEND _qt_additional_packages_prefixes $ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH}) + endif() + + foreach(_qt_additional_path IN LISTS _qt_additional_packages_prefixes) + file(TO_CMAKE_PATH "${_qt_additional_path}" _qt_additional_path) + + # The prefix paths need to end with lib/cmake to ensure the packages are found when + # cross compiling. Search for REROOT_PATH_ISSUE_MARKER in the qt.toolchain.cmake file for + # details. + # We must pass the values via the PATHS options because the main find_package call uses + # NO_DEFAULT_PATH, and thus CMAKE_PREFIX_PATH values are discarded. + # CMAKE_FIND_ROOT_PATH values are not discarded and togegher with the PATHS option, it + # ensures packages from additional prefixes are found. + if(NOT _qt_additional_path MATCHES "/lib/cmake$") + string(APPEND _qt_additional_path "/lib/cmake") + endif() + list(APPEND _qt_additional_packages_prefix_paths "${_qt_additional_path}") + endforeach() + unset(_qt_additional_path) + unset(_qt_additional_packages_prefixes) +endif() # Public helpers available to all Qt packages. include("${CMAKE_CURRENT_LIST_DIR}/QtFeature.cmake") @@ -121,8 +153,7 @@ foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS}) ${_@INSTALL_CMAKE_NAMESPACE@_FIND_PARTS_QUIET} PATHS ${_qt_cmake_dir} - ${_qt_additional_packages_prefix_path} - ${_qt_additional_packages_prefix_path_env} + ${_qt_additional_packages_prefix_paths} ${QT_EXAMPLES_CMAKE_PREFIX_PATH} ${__qt_find_package_host_qt_path} ${__qt_use_no_default_path_for_qt_packages} diff --git a/cmake/QtModuleDependencies.cmake.in b/cmake/QtModuleDependencies.cmake.in index eb967c597f9..55763ee3ef9 100644 --- a/cmake/QtModuleDependencies.cmake.in +++ b/cmake/QtModuleDependencies.cmake.in @@ -8,8 +8,8 @@ endif() find_dependency(@INSTALL_CMAKE_NAMESPACE@ @PROJECT_VERSION@ PATHS "${CMAKE_CURRENT_LIST_DIR}/.." - ${_qt_additional_packages_prefix_path} - ${_qt_additional_packages_prefix_path_env} + "${_qt_cmake_dir}" + ${_qt_additional_packages_prefix_paths} ${QT_EXAMPLES_CMAKE_PREFIX_PATH} ${__qt_use_no_default_path_for_qt_packages} ) @@ -70,8 +70,7 @@ foreach(__qt_@target@_target_dep ${__qt_@target@_tool_deps}) endif() find_package(${__qt_@target@_pkg} ${__qt_@target@_version} ${__qt_@target@_find_package_args} PATHS - ${_qt_additional_packages_prefix_path} - ${_qt_additional_packages_prefix_path_env} + ${_qt_additional_packages_prefix_paths} ) if (NOT ${__qt_@target@_pkg}_FOUND) if(NOT "${QT_HOST_PATH}" STREQUAL "") @@ -88,7 +87,7 @@ endif() # note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0" set(__qt_@target@_target_deps "@target_deps@") -set(__qt_@target@_find_dependency_paths "${CMAKE_CURRENT_LIST_DIR}/..") +set(__qt_@target@_find_dependency_paths "${CMAKE_CURRENT_LIST_DIR}/.." "${_qt_cmake_dir}") _qt_internal_find_dependencies(__qt_@target@_target_deps __qt_@target@_find_dependency_paths) set(_@QT_CMAKE_EXPORT_NAMESPACE@@target@_MODULE_DEPENDENCIES "@qt_module_dependencies@") diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index 912a0744220..4c898c5378f 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -292,12 +292,15 @@ function(qt_internal_create_plugin_depends_file target) if(third_party_deps OR target_deps) # Setup build and install paths - set(find_dependency_paths "\${CMAKE_CURRENT_LIST_DIR}/..") + + # Plugins should look for their dependencies in their associated module package folder as + # well as the Qt6 package folder which is stored by the Qt6 package in _qt_cmake_dir. + set(find_dependency_paths "\${CMAKE_CURRENT_LIST_DIR}/..;\${_qt_cmake_dir}") if(plugin_install_package_suffix) set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${plugin_install_package_suffix}") if(plugin_install_package_suffix MATCHES "/QmlPlugins") # Qml plugins are one folder deeper. - set(find_dependency_paths "\${CMAKE_CURRENT_LIST_DIR}/../..") + set(find_dependency_paths "\${CMAKE_CURRENT_LIST_DIR}/../..;\${_qt_cmake_dir}") endif() else() diff --git a/cmake/QtPublicDependencyHelpers.cmake b/cmake/QtPublicDependencyHelpers.cmake index 84c9e8be92f..a1e422107a4 100644 --- a/cmake/QtPublicDependencyHelpers.cmake +++ b/cmake/QtPublicDependencyHelpers.cmake @@ -16,8 +16,7 @@ macro(_qt_internal_find_dependencies target_dep_list find_dependency_path_list) ${__qt_pkg_names} PATHS ${${find_dependency_path_list}} - ${_qt_additional_packages_prefix_path} - ${_qt_additional_packages_prefix_path_env} + ${_qt_additional_packages_prefix_paths} ${QT_EXAMPLES_CMAKE_PREFIX_PATH} ${__qt_use_no_default_path_for_qt_packages} ) diff --git a/cmake/qt.toolchain.cmake.in b/cmake/qt.toolchain.cmake.in index 49553c9bbf4..9a8019a3da4 100644 --- a/cmake/qt.toolchain.cmake.in +++ b/cmake/qt.toolchain.cmake.in @@ -58,13 +58,58 @@ get_filename_component(QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX # one level higher is what we're looking for. get_filename_component(QT_TOOLCHAIN_RELOCATABLE_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) +# REROOT_PATH_ISSUE_MARKER # There's a subdirectory check in cmake's cmFindCommon::RerootPaths() function, that doesn't handle # the case of CMAKE_PREFIX_PATH == CMAKE_FIND_ROOT_PATH for a particular pair of entries. # Instead of collapsing the search prefix (which is the case when one is a subdir of the other), # it concatenates them creating an invalid path. Workaround it by setting the root path to the # Qt install prefix, and the prefix path to the lib/cmake subdir. -set(CMAKE_PREFIX_PATH "${QT_TOOLCHAIN_RELOCATABLE_CMAKE_DIR};${CMAKE_PREFIX_PATH}") -set(CMAKE_FIND_ROOT_PATH "${QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX};${CMAKE_FIND_ROOT_PATH}") +list(PREPEND CMAKE_PREFIX_PATH "${QT_TOOLCHAIN_RELOCATABLE_CMAKE_DIR}") +list(PREPEND CMAKE_FIND_ROOT_PATH "${QT_TOOLCHAIN_RELOCATABLE_INSTALL_PREFIX}") + +# Handle packages located in QT_ADDITIONAL_PACKAGES_PREFIX_PATH when cross-compiling. Needed for +# Conan. +# We prepend to CMAKE_PREFIX_PATH so that a find_package(Qt6Foo) call works, without having to go +# through the Qt6 umbrella package. The paths must end in lib/cmake to esnsure the package is found. +# See REROOT_PATH_ISSUE_MARKER. +# We prepend to CMAKE_FIND_ROOT_PATH, due to the bug mentioned at REROOT_PATH_ISSUE_MARKER. +set(__qt_toolchain_additional_packages_prefixes "") +if(QT_ADDITIONAL_PACKAGES_PREFIX_PATH) + list(APPEND __qt_toolchain_additional_packages_prefixes + ${QT_ADDITIONAL_PACKAGES_PREFIX_PATH}) +endif() +if(DEFINED ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH} + AND NOT "$ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH}" STREQUAL "") + list(APPEND __qt_toolchain_additional_packages_prefixes + $ENV{QT_ADDITIONAL_PACKAGES_PREFIX_PATH}) +endif() + +if(__qt_toolchain_additional_packages_prefixes) + set(__qt_toolchain_additional_packages_root_paths "") + set(__qt_toolchain_additional_packages_prefix_paths "") + + foreach(__qt_additional_path IN LISTS __qt_toolchain_additional_packages_prefixes) + file(TO_CMAKE_PATH "${__qt_additional_path}" __qt_additional_path) + get_filename_component(__qt_additional_path "${__qt_additional_path}" ABSOLUTE) + set(__qt_additional_path_lib_cmake "${__qt_additional_path}") + if(NOT __qt_additional_path_lib_cmake MATCHES "/lib/cmake$") + string(APPEND __qt_additional_path_lib_cmake "/lib/cmake") + endif() + + list(APPEND __qt_toolchain_additional_packages_root_paths + "${__qt_additional_path}") + list(APPEND __qt_toolchain_additional_packages_prefix_paths + "${__qt_additional_path_lib_cmake}") + endforeach() + list(PREPEND CMAKE_PREFIX_PATH ${__qt_toolchain_additional_packages_prefix_paths}) + list(PREPEND CMAKE_FIND_ROOT_PATH ${__qt_toolchain_additional_packages_root_paths}) + + unset(__qt_additional_path) + unset(__qt_additional_path_lib_cmake) + unset(__qt_toolchain_additional_packages_root_paths) + unset(__qt_toolchain_additional_packages_prefix_paths) +endif() +unset(__qt_toolchain_additional_packages_prefixes) @init_qt_host_path_checks@