summaryrefslogtreecommitdiffstats
path: root/cmake/QtPluginHelpers.cmake
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2021-04-20 17:29:48 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2021-04-22 16:15:41 +0200
commit6969496e0078f9f9df9bef817caad71cf5213e3a (patch)
tree668710d62c50a5f25c49b6b84fb1466821b33237 /cmake/QtPluginHelpers.cmake
parenta40a512dec0f34e84eb63812af556608f03713ff (diff)
CMake: Fix auto-linking of static plugins for non-QML in-tree tests
Certain repositories like qtsvg, qtimageformats and qtvirtualkyboard build plugins associated with Qt modules from other repositories (qtsvg's QSvgPlugin associated to qtbase's QtGui). When configuring in-tree tests in the same build folder as the repository, the test executables would not automatically link to these plugins. Fix this by recording the existence of such plugins in a separate property of the associated Qt module and only link them when both the test executable and plugin are from the same project (their PROJECT_NAME coincides). This is in addition to linking the plugins associated with the module where both are built in the same repository. The logic is a bit tricky and ensures that plugins are not accidentally initialized twice, so that in-tree tests work for both top-level and per-repo builds. As a drive-by, added a TODO explaining why in-tree tests that need to link to static QML plugins won't work (somewhat unrelated to this change). Amends 734d2cdbc4ff6db6b3df8fffbb23dbbb565c076b Amends b1fcdad9c9b9ad2bddd00f7301c8dd1159d523c2 Pick-to: 6.1 Task-number: QTBUG-87580 Change-Id: I3e1ff8166864f92dea931ec2ea34b6f56b4eec60 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'cmake/QtPluginHelpers.cmake')
-rw-r--r--cmake/QtPluginHelpers.cmake65
1 files changed, 52 insertions, 13 deletions
diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake
index a3a4c94a80..2368531d99 100644
--- a/cmake/QtPluginHelpers.cmake
+++ b/cmake/QtPluginHelpers.cmake
@@ -176,30 +176,69 @@ function(qt_internal_add_plugin target)
endif()
get_target_property(is_imported_qt_module ${qt_module_target} IMPORTED)
+ # Associate plugin with its Qt module when both are both built in the same repository.
+ # Check that by comparing the PROJECT_NAME of each.
+ # This covers auto-linking of the majority of plugins to executables and in-tree tests.
+ # Linking of plugins in standalone tests (when the Qt module will be an imported target)
+ # is handled instead by the complicated genex logic in QtModulePlugins.cmake.in.
+ set(is_plugin_and_module_in_same_project FALSE)
if(NOT is_imported_qt_module)
+ # This QT_PLUGINS assignment is only used by QtPostProcessHelpers to decide if a
+ # QtModulePlugins.cmake file should be generated (which only happens in static builds).
set_property(TARGET "${qt_module_target}" APPEND PROPERTY QT_PLUGINS "${target}")
+
get_target_property(module_source_dir ${qt_module_target} SOURCE_DIR)
get_directory_property(module_project_name
DIRECTORY ${module_source_dir}
DEFINITION PROJECT_NAME
)
+ if(module_project_name STREQUAL PROJECT_NAME)
+ set(is_plugin_and_module_in_same_project TRUE)
+ endif()
# When linking static plugins with the special logic in qt_internal_add_executable,
# make sure to skip non-default plugins.
- if(module_project_name STREQUAL PROJECT_NAME AND _default_plugin)
- set_property(TARGET ${qt_module_target} APPEND PROPERTY _qt_repo_plugins "${target}")
- set_property(TARGET ${qt_module_target} APPEND PROPERTY _qt_repo_plugin_class_names
- "$<TARGET_PROPERTY:${target},QT_PLUGIN_CLASS_NAME>"
- )
+ if(is_plugin_and_module_in_same_project AND _default_plugin)
+ set_property(TARGET ${qt_module_target} APPEND PROPERTY
+ _qt_initial_repo_plugins
+ "${target}")
+ set_property(TARGET ${qt_module_target} APPEND PROPERTY
+ _qt_initial_repo_plugin_class_names
+ "$<TARGET_PROPERTY:${target},QT_PLUGIN_CLASS_NAME>"
+ )
endif()
- else()
- # TODO: If a repo A provides an internal executable E and a plugin P, with the plugin
- # type belonging to a Qt module defined in a different repo, and executable E needs to
- # link to plugin P in a static build, currently that won't happen. The executable E
- # will link to plugins mentioned in the Qt module's _qt_repo_plugins property, but that
- # property will not list P because the Qt module will be an imported target and won't
- # have a SOURCE_DIR or PROJECT NAME, so the checks above will not be met.
- # Figure out how to handle such a scenario.
+ endif()
+
+ # Associate plugin with its Qt module when the plugin is built in the current repository
+ # but the module is built in a different repository (qtsvg's QSvgPlugin associated with
+ # qtbase's QtGui).
+ # The association is done in a separate property, to ensure that reconfiguring in-tree tests
+ # in qtbase doesn't accidentally cause linking to a plugin from a previously built qtsvg.
+ # Needed for in-tree tests like in qtsvg, qtimageformats.
+ # This is done for each Qt module regardless if it's an imported target or not, to handle
+ # both per-repo and top-level builds (in per-repo build of qtsvg QtGui is imported, in a
+ # top-level build Gui is not imported, but in both cases qtsvg tests need to link to
+ # QSvgPlugin).
+ #
+ # TODO: Top-level in-tree tests and qdeclarative per-repo in-tree tests that depend on
+ # static Qml plugins won't work due to the requirement of running qmlimportscanner
+ # at configure time, but qmlimportscanner is not built at that point. Moving the
+ # execution of qmlimportscanner to build time is non-trivial because qmlimportscanner
+ # not only generates a cpp file to compile but also outputs a list of static plugins
+ # that should be linked and there is no straightforward way to tell CMake to link
+ # against a list of libraries that was discovered at build time (apart from
+ # response files, which apparently might not work on all platforms).
+ # qmake doesn't have this problem because each project is configured separately so
+ # qmlimportscanner is always built by the time it needs to be run for a test.
+ if(NOT is_plugin_and_module_in_same_project AND _default_plugin)
+ string(MAKE_C_IDENTIFIER "${PROJECT_NAME}" current_project_name)
+ set(prop_prefix "_qt_repo_${current_project_name}")
+ set_property(TARGET ${qt_module_target} APPEND PROPERTY
+ ${prop_prefix}_plugins "${target}")
+ set_property(TARGET ${qt_module_target} APPEND PROPERTY
+ ${prop_prefix}_plugin_class_names
+ "$<TARGET_PROPERTY:${target},QT_PLUGIN_CLASS_NAME>"
+ )
endif()
endif()