diff --git a/cmake/Qt3rdPartyLibraryHelpers.cmake b/cmake/Qt3rdPartyLibraryHelpers.cmake index d144977c7f..4d5ffb96ff 100644 --- a/cmake/Qt3rdPartyLibraryHelpers.cmake +++ b/cmake/Qt3rdPartyLibraryHelpers.cmake @@ -175,17 +175,6 @@ function(qt_internal_add_3rdparty_library target) qt_autogen_tools_initial_setup(${target}) endif() - if(NOT arg_INTERFACE) - # This property is used for super builds with static libraries. We use - # it in QtPlugins.cmake.in to avoid "polluting" the dependency chain - # for the target in it's project directory. - # E.g: When we process find_package(Qt6 ... Gui) in QtDeclarative, the - # rules in QtPugins.cmake add all the known Gui plugins as interface - # dependencies. This in turn causes circular dependencies on every - # plugin which links against Gui. Plugin A -> GUI -> Plugin A .... - set_target_properties(${target} PROPERTIES QT_BUILD_PROJECT_NAME ${PROJECT_NAME}) - endif() - if(NOT arg_EXCEPTIONS AND NOT arg_INTERFACE) qt_internal_set_exceptions_flags("${target}" FALSE) elseif(arg_EXCEPTIONS) diff --git a/cmake/QtExecutableHelpers.cmake b/cmake/QtExecutableHelpers.cmake index c6ffd69fc2..c2ad66c484 100644 --- a/cmake/QtExecutableHelpers.cmake +++ b/cmake/QtExecutableHelpers.cmake @@ -174,4 +174,42 @@ function(qt_internal_add_executable name) if("Qt::Gui" IN_LIST linked_libs AND TARGET qpa_default_plugins) add_dependencies("${name}" qpa_default_plugins) endif() + + if(NOT BUILD_SHARED_LIBS) + # For static builds, we need to explicitly link to plugins we want to be + # loaded with the executable. User projects get that automatically, but + # for tools built as part of Qt, we can't use that mechanism because it + # would pollute the targets we export as part of an install and lead to + # circular dependencies. The logic here is a simpler equivalent of the + # more dynamic logic in QtPlugins.cmake.in, but restricted to only + # adding plugins that are provided by the same module as the module + # libraries the executable links to. + set(libs + ${arg_LIBRARIES} + ${arg_PUBLIC_LIBRARIES} + ${extra_libraries} + Qt::PlatformCommonInternal + ) + list(REMOVE_DUPLICATES libs) + foreach(lib IN LISTS libs) + if(NOT TARGET "${lib}") + continue() + endif() + string(MAKE_C_IDENTIFIER "${name}_plugin_imports_${lib}" out_file) + string(APPEND out_file .cpp) + set(class_names "$>") + file(GENERATE OUTPUT ${out_file} CONTENT +"// This file is auto-generated. Do not edit. +#include + +Q_IMPORT_PLUGIN($) +" + CONDITION "$>" + ) + target_sources(${name} PRIVATE + "$<$>:${out_file}>" + ) + target_link_libraries(${name} PRIVATE "$") + endforeach() + endif() endfunction() diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake index 6268bfe960..efd9cd9a8e 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -241,15 +241,6 @@ function(qt_internal_add_module target) endif() if(NOT arg_HEADER_MODULE) - # This property is used for super builds with static libraries. We use - # it in QtPlugins.cmake.in to avoid "polluting" the dependency chain - # for the target in it's project directory. - # E.g: When we process find_package(Qt6 ... Gui) in QtDeclarative, the - # rules in QtPugins.cmake add all the known Gui plugins as interface - # dependencies. This in turn causes circular dependencies on every - # plugin which links against Gui. Plugin A -> GUI -> Plugin A .... - - set_target_properties(${target} PROPERTIES QT_BUILD_PROJECT_NAME ${PROJECT_NAME}) # Plugin types associated to a module if(NOT "x${arg_PLUGIN_TYPES}" STREQUAL "x") # Reset the variable containing the list of plugins for the given plugin type diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake index b53a958344..530e71aeda 100644 --- a/cmake/QtPluginHelpers.cmake +++ b/cmake/QtPluginHelpers.cmake @@ -136,6 +136,17 @@ function(qt_internal_add_plugin target) # Add the plug-in to the list of plug-ins of this module if(TARGET "${qt_module}") set_property(TARGET "${qt_module}" APPEND PROPERTY QT_PLUGINS "${target}") + get_target_property(module_source_dir ${qt_module} SOURCE_DIR) + get_directory_property(module_project_name + DIRECTORY ${module_source_dir} + DEFINITION PROJECT_NAME + ) + if(module_project_name STREQUAL PROJECT_NAME) + set_property(TARGET ${qt_module} APPEND PROPERTY QT_REPO_PLUGINS "${target}") + set_property(TARGET ${qt_module} APPEND PROPERTY QT_REPO_PLUGIN_CLASS_NAMES + "$" + ) + endif() endif() # Change the configuration file install location for qml plugins into the Qml package location. diff --git a/cmake/QtPlugins.cmake.in b/cmake/QtPlugins.cmake.in index fd3370b9a2..d57611caec 100644 --- a/cmake/QtPlugins.cmake.in +++ b/cmake/QtPlugins.cmake.in @@ -35,18 +35,6 @@ function(__qt_internal_add_static_plugins_once) # Plugin genex marker for prl processing. set(_is_plugin_marker_genex "$") - # In super builds the rules below pollute the dependency rule for the - # plugin target when it's being build, causing cyclic dependencies. - # to overcome this, we check if the current target where this rule evaluates - # has a QT_BUILD_PROJECT_NAME equal to the current PROJECT_NAME. - # If so we disable the injection of plugin link rules to avoid cyclic - # dependencies. - if (@QT_SUPERBUILD@) - set(_build_allow_plugin_link_rules_genex "$,@PROJECT_NAME@>>") - else() - set(_build_allow_plugin_link_rules_genex 1) - endif() - # The code in here uses the properties defined in qt_import_plugins (Qt6CoreMacros.cmake) foreach(target ${_qt_plugins}) set(_plugin_target "@INSTALL_CMAKE_NAMESPACE@::${target}") @@ -115,7 +103,6 @@ function(__qt_internal_add_static_plugins_once) string(CONCAT _plugin_condition "$