CMake: Suggest hints on how to debug missing packages

Depending on CMake version suggest usage of either
--debug-find-pkg or CMAKE_FIND_DEBUG_MODE to help troubleshoot
why dependent packages are not found.

To achieve that, append the hint message to the _NOT_FOUND_MESSAGE.

To ensure it works for qt dependencies, and not only tool and 3rd
party dependencies, _qt_internal_find_qt_dependencies
is modified to set variable names infixed by the target name, so the
name is consistent with the other dependency lookup functions.

The check and message are also added when a Qt6 component is not
found.

Pick-to: 6.4
Task-number: QTBUG-104998
Change-Id: I4ef23d1c53ac8e04eb72c260d6860c1eeec8d7a3
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Alexandru Croitor 2022-07-14 15:28:12 +02:00
parent 0e2b385c5b
commit 50d0296ed4
6 changed files with 51 additions and 15 deletions

View File

@ -150,6 +150,10 @@ set(__qt_sanitizer_options_set TRUE)
include(CMakeFindDependencyMacro)
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Dependencies.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Dependencies.cmake")
_qt_internal_suggest_dependency_debugging(
__qt_@INSTALL_CMAKE_NAMESPACE@_pkg ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
if(NOT @INSTALL_CMAKE_NAMESPACE@_FOUND)
# Clear the components, no need to look for them if dependencies were not found, otherwise
# you get a wall of recursive error messages.
@ -234,8 +238,12 @@ foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
endif()
if(@INSTALL_CMAKE_NAMESPACE@_FIND_REQUIRED_${module})
set(@INSTALL_CMAKE_NAMESPACE@_FOUND False)
set(_Qt_NOTFOUND_MESSAGE
"${_Qt_NOTFOUND_MESSAGE}Failed to find required Qt component \"${module}\". ${_qt_component_not_found_msg}")
set(_qt_full_component_name "@INSTALL_CMAKE_NAMESPACE@${module}")
_qt_internal_suggest_dependency_debugging(_qt_full_component_name _Qt_NOTFOUND_MESSAGE)
unset(_qt_full_component_name)
break()
elseif(NOT @INSTALL_CMAKE_NAMESPACE@_FIND_QUIETLY)
message(WARNING
@ -251,7 +259,6 @@ endforeach()
if(@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS AND _Qt_NOTFOUND_MESSAGE)
set(@INSTALL_CMAKE_NAMESPACE@_NOT_FOUND_MESSAGE "${_Qt_NOTFOUND_MESSAGE}")
set(@INSTALL_CMAKE_NAMESPACE@_FOUND False)
unset(_Qt_NOTFOUND_MESSAGE)
endif()

View File

@ -9,6 +9,6 @@ set(__qt_third_party_deps "@third_party_deps@")
# set _NOT_FOUND_MESSAGE which will be displayed by the includer of the Dependencies file.
set(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED FALSE)
_qt_internal_find_third_party_dependencies(Platform __qt_third_party_deps)
_qt_internal_find_third_party_dependencies(@INSTALL_CMAKE_NAMESPACE@ __qt_third_party_deps)
set(@INSTALL_CMAKE_NAMESPACE@_FOUND TRUE)

View File

@ -14,6 +14,8 @@ get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
# Find required dependencies, if any.
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
_qt_internal_suggest_dependency_debugging(
__qt_@target@_pkg ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
endif()
# If *ConfigDependencies.cmake exists, the variable value will be defined there.

View File

@ -33,7 +33,8 @@ _qt_internal_find_tool_dependencies("@target@" __qt_@target@_tool_deps)
# 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}/.." "${_qt_cmake_dir}")
_qt_internal_find_qt_dependencies(__qt_@target@_target_deps __qt_@target@_find_dependency_paths)
_qt_internal_find_qt_dependencies("@target@" __qt_@target@_target_deps
__qt_@target@_find_dependency_paths)
set(_@QT_CMAKE_EXPORT_NAMESPACE@@target@_MODULE_DEPENDENCIES "@qt_module_dependencies@")
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND TRUE)

View File

@ -12,6 +12,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 "@find_dependency_paths@")
_qt_internal_find_qt_dependencies(__qt_@target@_target_deps __qt_@target@_find_dependency_paths)
_qt_internal_find_qt_dependencies("@target@" __qt_@target@_target_deps
__qt_@target@_find_dependency_paths)
set(@target@_FOUND TRUE)

View File

@ -83,19 +83,19 @@ endmacro()
# Please note the target_dep_list accepts not the actual list values but the list names that
# contain preformed dependencies. See foreach block for reference.
# The same applies for find_dependency_path_list.
macro(_qt_internal_find_qt_dependencies target_dep_list find_dependency_path_list)
foreach(__qt_target_dep IN LISTS ${target_dep_list})
list(GET __qt_target_dep 0 __qt_pkg)
list(GET __qt_target_dep 1 __qt_version)
macro(_qt_internal_find_qt_dependencies target target_dep_list find_dependency_path_list)
foreach(__qt_${target}_target_dep IN LISTS ${target_dep_list})
list(GET __qt_${target}_target_dep 0 __qt_${target}_pkg)
list(GET __qt_${target}_target_dep 1 __qt_${target}_version)
if (NOT ${__qt_pkg}_FOUND)
set(__qt_pkg_names ${__qt_pkg})
if(__qt_pkg MATCHES "(.*)Private$")
set(__qt_pkg_names "${CMAKE_MATCH_1};${__qt_pkg}")
if (NOT ${__qt_${target}_pkg}_FOUND)
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}")
endif()
find_dependency(${__qt_pkg} ${__qt_version}
find_dependency(${__qt_${target}_pkg} ${__qt_${target}_version}
NAMES
${__qt_pkg_names}
${__qt_${target}_pkg_names}
PATHS
${${find_dependency_path_list}}
${_qt_additional_packages_prefix_paths}
@ -112,5 +112,30 @@ endmacro()
# The name is too generic, it doesn't look for any kind of dependencies but only Qt package
# dependencies.
macro(_qt_internal_find_dependencies target_dep_list find_dependency_path_list)
_qt_internal_find_qt_dependencies("${target_dep_list}" "${find_dependency_path_list}")
_qt_internal_find_qt_dependencies("none" "${target_dep_list}" "${find_dependency_path_list}")
endmacro()
# If a dependency package was not found, provide some hints in the error message on how to debug
# the issue.
# pkg_name_var should be the variable name that contains the package that was not found.
# e.g. __qt_Core_pkg
# message_out_var should contain the variable name of the original "not found" message, and it
# will have the hints appended to it as a string. e.g. ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
#
# The function should not be called in Dependencies.cmake files directly, because find_dependency
# returns out of the included file.
macro(_qt_internal_suggest_dependency_debugging pkg_name_var message_out_var)
if(${pkg_name_var}
AND NOT ${CMAKE_FIND_PACKAGE_NAME}_FOUND
AND ${message_out_var})
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.23")
string(APPEND ${message_out_var}
"\nConfiguring with --debug-find-pkg=${${pkg_name_var}} might reveal \
details why the package was not found.")
elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.17")
string(APPEND ${message_out_var}
"\nConfiguring with -DCMAKE_FIND_DEBUG_MODE=TRUE might reveal \
details why the package was not found.")
endif()
endif()
endmacro()