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}