From 3685483c4b79b4075bab6d341174a395359d1b4a Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 9 Sep 2020 16:19:11 +0200 Subject: [PATCH] CMake: Add facility to mark package dependencies as optional Every public dependency of a Qt module results in a find_package call in the consuming project. But not all public dependencies are mandatory. For example, vulkan is only needed if the user project actually uses Qt classes that pull in vulkan headers. This patch adds the option MARK_OPTIONAL to qt_find_package. Dependencies that are marked as optional will not produce an error on find failure. Task-number: QTBUG-86421 Change-Id: Ia767e7f36991e236582c7509cbd37ea3487bb695 Reviewed-by: Alexandru Croitor --- cmake/QtConfigDependencies.cmake.in | 16 ++++++++++++---- cmake/QtFindPackageHelpers.cmake | 10 ++++++---- cmake/QtModuleDependencies.cmake.in | 16 ++++++++++++---- cmake/QtPluginDependencies.cmake.in | 16 ++++++++++++---- cmake/QtPostProcessHelpers.cmake | 3 ++- 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/cmake/QtConfigDependencies.cmake.in b/cmake/QtConfigDependencies.cmake.in index 49e08b7ba6d..bccf6b372ce 100644 --- a/cmake/QtConfigDependencies.cmake.in +++ b/cmake/QtConfigDependencies.cmake.in @@ -1,12 +1,13 @@ -# note: _third_party_deps example: "ICU\\;1.0\\;i18n uc data;ZLIB\\;\\;" +# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;" set(_third_party_deps "@third_party_deps@") @third_party_extra@ foreach(_target_dep ${_third_party_deps}) list(GET _target_dep 0 pkg) - list(GET _target_dep 1 version) - list(GET _target_dep 2 components) + list(GET _target_dep 1 is_optional) + list(GET _target_dep 2 version) + list(GET _target_dep 3 components) set(find_package_args "${pkg}") if(version) list(APPEND find_package_args "${version}") @@ -27,7 +28,14 @@ foreach(_target_dep ${_third_party_deps}) set(@INSTALL_CMAKE_NAMESPACE@_DEPENDENCY_NOT_FOUND_MESSAGE "${__@INSTALL_CMAKE_NAMESPACE@_message}") - find_dependency(${find_package_args}) + if(is_optional) + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + list(APPEND find_package_args QUIET) + endif() + find_package(${find_package_args}) + else() + find_dependency(${find_package_args}) + endif() endforeach() set(@INSTALL_CMAKE_NAMESPACE@_DEPENDENCIES_FOUND TRUE) diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake index 0ca585d1d45..c68ba4d14ac 100644 --- a/cmake/QtFindPackageHelpers.cmake +++ b/cmake/QtFindPackageHelpers.cmake @@ -15,7 +15,8 @@ endfunction() macro(qt_find_package) # Get the target names we expect to be provided by the package. - set(options CONFIG NO_MODULE MODULE REQUIRED) + 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) cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -90,7 +91,7 @@ macro(qt_find_package) endif() # Ensure the options are back in the original unparsed arguments - foreach(opt IN LISTS options) + foreach(opt IN LISTS find_package_options) if(arg_${opt}) list(APPEND arg_UNPARSED_ARGUMENTS ${opt}) endif() @@ -129,8 +130,9 @@ macro(qt_find_package) set(qt_find_package_target_name ${aliased_target}) endif() - set_target_properties(${qt_find_package_target_name} - PROPERTIES INTERFACE_QT_PACKAGE_NAME ${ARGV0}) + 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}) diff --git a/cmake/QtModuleDependencies.cmake.in b/cmake/QtModuleDependencies.cmake.in index 3d19fac7841..24d132b57d0 100644 --- a/cmake/QtModuleDependencies.cmake.in +++ b/cmake/QtModuleDependencies.cmake.in @@ -4,13 +4,14 @@ find_dependency(@INSTALL_CMAKE_NAMESPACE@ @PROJECT_VERSION@ PATHS "${CMAKE_CURRENT_LIST_DIR}/.." ${QT_EXAMPLES_CMAKE_PREFIX_PATH} NO_DEFAULT_PATH ) -# note: _third_party_deps example: "ICU\\;1.0\\;i18n uc data;ZLIB\\;\\;" +# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;" set(_third_party_deps "@third_party_deps@") foreach(_target_dep ${_third_party_deps}) list(GET _target_dep 0 pkg) - list(GET _target_dep 1 version) - list(GET _target_dep 2 components) + list(GET _target_dep 1 is_optional) + list(GET _target_dep 2 version) + list(GET _target_dep 3 components) set(find_package_args "${pkg}") if(version) list(APPEND find_package_args "${version}") @@ -20,7 +21,14 @@ foreach(_target_dep ${_third_party_deps}) list(APPEND find_package_args COMPONENTS ${components}) endif() - find_dependency(${find_package_args}) + if(is_optional) + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + list(APPEND find_package_args QUIET) + endif() + find_package(${find_package_args}) + else() + find_dependency(${find_package_args}) + endif() endforeach() # Find Qt tool package. diff --git a/cmake/QtPluginDependencies.cmake.in b/cmake/QtPluginDependencies.cmake.in index bae6d85c7b4..9d16bedeba0 100644 --- a/cmake/QtPluginDependencies.cmake.in +++ b/cmake/QtPluginDependencies.cmake.in @@ -1,12 +1,13 @@ set(@target@_FOUND FALSE) -# note: _third_party_deps example: "ICU\\;1.0\\;i18n uc data;ZLIB\\;\\;" +# note: _third_party_deps example: "ICU\\;FALSE\\;1.0\\;i18n uc data;ZLIB\\;FALSE\\;\\;" set(_third_party_deps "@third_party_deps@") foreach(_target_dep ${_third_party_deps}) list(GET _target_dep 0 pkg) - list(GET _target_dep 1 version) - list(GET _target_dep 2 components) + list(GET _target_dep 1 is_optional) + list(GET _target_dep 2 version) + list(GET _target_dep 3 components) set(find_package_args "${pkg}") if(version) list(APPEND find_package_args "${version}") @@ -16,7 +17,14 @@ foreach(_target_dep ${_third_party_deps}) list(APPEND find_package_args COMPONENTS ${components}) endif() - find_dependency(${find_package_args}) + if(is_optional) + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + list(APPEND find_package_args QUIET) + endif() + find_package(${find_package_args}) + else() + find_dependency(${find_package_args}) + endif() endforeach() # note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0" diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index 0da6d9e4c34..56b2d5e56fe 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -43,6 +43,7 @@ macro(qt_collect_third_party_deps target) get_target_property(package_name ${dep} INTERFACE_QT_PACKAGE_NAME) if(dep_seen EQUAL -1 AND package_name) list(APPEND third_party_deps_seen ${dep}) + get_target_property(package_is_optional ${dep} INTERFACE_QT_PACKAGE_IS_OPTIONAL) get_target_property(package_version ${dep} INTERFACE_QT_PACKAGE_VERSION) if(NOT package_version) set(package_version "") @@ -54,7 +55,7 @@ macro(qt_collect_third_party_deps target) endif() list(APPEND third_party_deps - "${package_name}\;${package_version}\;${package_components}") + "${package_name}\;${package_is_optional}\;${package_version}\;${package_components}") endif() endif() endforeach()