From 2be02608aef7922befde1f4207ef0df909836cd4 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Wed, 30 Oct 2024 18:18:05 +0100 Subject: [PATCH] Add the QT_PLUGIN_TARGETS transitive compile property Use the freshly introduced TRANSITIVE_COMPILE_PROPERTIES functionality to handle plugin targets across Qt modules. This will allow accessing all Qt plugins that are required for targets at once, without the need of iterating over the Qt targets at configure time. This mechanism duplicates the already existing plugin collecting routines, since we still need to support the older CMake version. This commit only introduces the helper functions and plugins collecting, but doesn't use the QT_PLUGIN_TARGETS anywhere. We don't use the direct export of properties by CMake but still rely on plugin collecting mechanism we use before to cover the situation when Qt is built using CMake versions < 3.30 and then is used to build user applications with CMake versions >= 3.30. Task-number: QTBUG-129302 Change-Id: Id3b516b92e8e16552d46b2c702b76c571366f2b5 Reviewed-by: Alexandru Croitor --- cmake/QtModuleHelpers.cmake | 3 +++ cmake/QtPluginHelpers.cmake | 2 ++ cmake/QtPublicCMakeHelpers.cmake | 22 ++++++++++++++++++ cmake/QtPublicPluginHelpers.cmake | 37 +++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake index 1b593d663b0..4b59b670313 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -499,6 +499,9 @@ function(qt_internal_add_module target) # Plugin types associated to a module if(NOT "x${arg_PLUGIN_TYPES}" STREQUAL "x") qt_internal_add_plugin_types("${target}" "${arg_PLUGIN_TYPES}") + # Ensure that QT_PLUGIN_TARGETS is a known transitive compile property. Works with CMake + # versions >= 3.30. + _qt_internal_add_transitive_property(${target} COMPILE QT_PLUGIN_TARGETS) endif() endif() diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake index ec7782fa9e8..434d32d8e94 100644 --- a/cmake/QtPluginHelpers.cmake +++ b/cmake/QtPluginHelpers.cmake @@ -218,6 +218,7 @@ function(qt_internal_add_plugin target) # This QT_PLUGINS assignment is only used by QtPostProcessHelpers to decide if a # QtModulePlugins.cmake file should be generated. set_property(TARGET "${qt_module_target}" APPEND PROPERTY QT_PLUGINS "${target}") + __qt_internal_add_interface_plugin_target(${qt_module_target} ${target} BUILD_ONLY) else() # The _qt_plugins property is considered when collecting the plugins in # deployment process. The usecase is following: @@ -225,6 +226,7 @@ function(qt_internal_add_plugin target) # The plugin is built in some application build tree and its PLUGIN_TYPE is associated # with QtModuleX. set_property(TARGET "${qt_module_target}" APPEND PROPERTY _qt_plugins "${target}") + __qt_internal_add_interface_plugin_target(${qt_module_target} ${target}) endif() set(plugin_target_versioned "${QT_CMAKE_EXPORT_NAMESPACE}::${target}") diff --git a/cmake/QtPublicCMakeHelpers.cmake b/cmake/QtPublicCMakeHelpers.cmake index 5bb260c5383..881edaf80af 100644 --- a/cmake/QtPublicCMakeHelpers.cmake +++ b/cmake/QtPublicCMakeHelpers.cmake @@ -675,3 +675,25 @@ function(_qt_internal_forward_function_args) set(${arg_FORWARD_OUT_VAR} "${forward_args}" PARENT_SCOPE) endfunction() + +# Function adds the transitive property of the specified type to a target, avoiding duplicates. +# Supported types: COMPILE, LINK +# +# See: +# https://cmake.org/cmake/help/latest/prop_tgt/TRANSITIVE_COMPILE_PROPERTIES.html +# https://cmake.org/cmake/help/latest/prop_tgt/TRANSITIVE_LINK_PROPERTIES.html +function(_qt_internal_add_transitive_property target type property) + if(CMAKE_VERSION VERSION_LESS 3.30) + return() + endif() + if(NOT type MATCHES "^(COMPILE|LINK)$") + message(FATAL_ERROR "Attempt to assign unknown TRANSITIVE_${type}_PROPERTIES property") + endif() + + get_target_property(transitive_properties ${target} + TRANSITIVE_${type}_PROPERTIES) + if(NOT "${property}" IN_LIST transitive_properties) + set_property(TARGET ${target} + APPEND PROPERTY TRANSITIVE_${type}_PROPERTIES ${property}) + endif() +endfunction() diff --git a/cmake/QtPublicPluginHelpers.cmake b/cmake/QtPublicPluginHelpers.cmake index 7087c31234f..3a9f18d797f 100644 --- a/cmake/QtPublicPluginHelpers.cmake +++ b/cmake/QtPublicPluginHelpers.cmake @@ -488,6 +488,36 @@ function(__qt_internal_apply_plugin_imports_finalizer_mode target) set_target_properties(${target} PROPERTIES _qt_plugin_finalizer_imports_processed TRUE) endfunction() +# Adds the specific plugin target to the INTERFACE_QT_PLUGIN_TARGETS transitive compile property. +# The property is then propagated to all targets that link the plugin_module_target and +# can be accessed using $ genex. +# +# Note: this is only supported in CMake versions 3.30 and higher. +function(__qt_internal_add_interface_plugin_target plugin_module_target plugin_target) + if(CMAKE_VERSION VERSION_LESS 3.30) + return() + endif() + + cmake_parse_arguments(arg "BUILD_ONLY" "" "" ${ARGN}) + if(arg_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unexpected arguments: ${arg_UNPARSED_ARGUMENTS}") + endif() + + __qt_internal_get_static_plugin_condition_genex(${plugin_target} plugin_target_condition) + string(JOIN "" plugin_target_name_wrapped + "$<${plugin_target_condition}:" + "$" + ">" + ) + + if(arg_BUILD_ONLY) + set(plugin_target_name_wrapped "$") + endif() + + set_property(TARGET ${plugin_module_target} + APPEND PROPERTY INTERFACE_QT_PLUGIN_TARGETS ${plugin_target_name_wrapped}) +endfunction() + # Include CMake plugin packages that belong to the Qt module ${target} and initialize automatic # linkage of the plugins in static builds. # The variables inside the macro have to be named unique to the module because an included Plugin @@ -504,6 +534,11 @@ macro(__qt_internal_include_plugin_packages target) set(__qt_${target}_plugin_module_target ${_aliased_target}) endif() + # Ensure that QT_PLUGIN_TARGETS is a known transitive compile property. Works with CMake + # versions >= 3.30. + _qt_internal_add_transitive_property(${__qt_${target}_plugin_module_target} + COMPILE QT_PLUGIN_TARGETS) + # Include all PluginConfig.cmake files and update the _qt_plugins and QT_PLUGINS property of # the module. The underscored version is the one we will use going forward to have compatibility # with INTERFACE libraries. QT_PLUGINS is now deprecated and only kept so that we don't break @@ -518,6 +553,8 @@ macro(__qt_internal_include_plugin_packages target) include("${__qt_${target}_plugin_config_file}") if(TARGET "${QT_CMAKE_EXPORT_NAMESPACE}::${__qt_${target}_qt_plugin}") list(APPEND __qt_${target}_plugins ${__qt_${target}_qt_plugin}) + __qt_internal_add_interface_plugin_target(${__qt_${target}_plugin_module_target} + ${__qt_${target}_qt_plugin}) endif() endforeach() set_property(TARGET ${__qt_${target}_plugin_module_target}