diff options
author | Craig Scott <craig.scott@qt.io> | 2021-03-19 20:04:23 +1100 |
---|---|---|
committer | Craig Scott <craig.scott@qt.io> | 2021-03-23 11:15:33 +1100 |
commit | 5807e1ae8168a5702ad0f6890d2b35223cfebdee (patch) | |
tree | 83b8815b8d11154c2a9d0a602f750585e3d0afb8 /cmake/QtExecutableHelpers.cmake | |
parent | dd7920821ec4ac51375084ed625c726cd6dbdb48 (diff) |
Add plugins to Qt tools and executables for static builds
In static builds, we cannot allow any part of the main build to make a
call to find_package(Qt6...) where such a call may load a
Qt6*Plugins.cmake file. That would add additional dependencies to the
main module targets, setting up a circular dependency in the set of
*Config.cmake files which cannot be resolved. This scenario would be
triggered by per-repo builds or user projects.
But Qt's tools and other executables still need to load some plugins
in static builds. Sometimes a platform plugin may be enough, other
times we may want all supportable plugins (e.g. Qt Designer).
Therefore, add all plugins we can identify as relevant for an
executable that is part of the Qt build, but add them directly to the
executable without affecting the linking relationships between the
main module libraries.
Also remove the now unnecessary check for QT_BUILD_PROJECT_NAME in
top level builds because there should be no difference between per-repo
and top level builds any more (as far as linking static plugins is
concerned).
Examples that build as part of the main build will still build
successfully after this change, but they will not run if they require
a platform plugin. Examples need to be moved out to a separate build
where they can call find_package(Qt6) without QT_NO_CREATE_TARGETS
set to TRUE to be runnable (see QTBUG-90820).
Fixes: QTBUG-91915
Pick-to: 6.1
Change-Id: I8088baddb54e394ca111b103313596d6743570ba
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Diffstat (limited to 'cmake/QtExecutableHelpers.cmake')
-rw-r--r-- | cmake/QtExecutableHelpers.cmake | 38 |
1 files changed, 38 insertions, 0 deletions
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 "$<GENEX_EVAL:$<TARGET_PROPERTY:${lib},QT_REPO_PLUGIN_CLASS_NAMES>>") + file(GENERATE OUTPUT ${out_file} CONTENT +"// This file is auto-generated. Do not edit. +#include <QtPlugin> + +Q_IMPORT_PLUGIN($<JOIN:${class_names},)\nQ_IMPORT_PLUGIN(>) +" + CONDITION "$<NOT:$<STREQUAL:${class_names},>>" + ) + target_sources(${name} PRIVATE + "$<$<NOT:$<STREQUAL:${class_names},>>:${out_file}>" + ) + target_link_libraries(${name} PRIVATE "$<TARGET_PROPERTY:${lib},QT_REPO_PLUGINS>") + endforeach() + endif() endfunction() |