6fcc272ac9
Allow linking all plugin initializer object libraries directly into the final target (executable or shared library). The finalizer mode is triggered when the project adds a call to qt_import_plugins, as well when the project has an explicit call to qt_finalize_executable or when it is defer called by CMake 3.19+. Otherwise the old non-finalizer mode is used, where each plugin initializer object library is propagated via the usage requirements of its associated module. A user can explicitly opt in or out of the new mode by calling qt_enable_import_plugins_finalizer_mode(target TRUE/FALSE) The implementation, at configure time, recursively collects all dependencies of the target to extract a list of used Qt modules. From each module we extract its list of associated plugins and their genex conditions. These genexes are used to conditionally link the plugins and the initializers. Renamed QT_PLUGINS property to _qt_plugins, so we can safely query the property even on INTERFACE libraries with lower CMake versions. QT_PLUGINS is kept for backwards compatibility with projects already using it, but should be removed in Qt 7. The upside of the finalizer mode is that it avoids creating link cycles (e.g. Gui -> SvgPlugin -> Gui case) which causes CMake to duplicate the library on the link line, slowing down link time as well as possibly breaking link order dependencies. The downside is that finalizer mode can't cope with generator expressions at the moment. So if a Qt module target is wrapped in a generator expression, it's plugins will not be detected and thus linked. Task-number: QTBUG-80863 Task-number: QTBUG-92933 Change-Id: Ic40c8ae5807a154ed18fcac18b25f00864c8f143 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
68 lines
2.8 KiB
CMake
68 lines
2.8 KiB
CMake
include_guard(DIRECTORY)
|
|
@QT_MODULE_PLUGIN_INCLUDES@
|
|
|
|
# Use a function to hide all the temporary variables we use so they don't leak
|
|
# out into the consuming scope
|
|
function(__qt_internal_add_static_plugins_once)
|
|
set(_module_target "@INSTALL_CMAKE_NAMESPACE@::@QT_MODULE@")
|
|
set(_qt_plugins "")
|
|
|
|
# Properties can't be set on aliased targets, so make sure to unalias the target. This is needed
|
|
# when Qt examples are built as part of the Qt build itself.
|
|
get_target_property(_aliased_target ${_module_target} ALIASED_TARGET)
|
|
if(_aliased_target)
|
|
set(_module_target ${_aliased_target})
|
|
endif()
|
|
|
|
# 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
|
|
# existing projects using it (like CMake itself).
|
|
file(GLOB _qt_plugin_config_files "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@*PluginConfig.cmake")
|
|
foreach(_config_file ${_qt_plugin_config_files})
|
|
string(REGEX REPLACE "^.*/@INSTALL_CMAKE_NAMESPACE@(.*Plugin)Config.cmake$" "\\1" _qt_plugin "${_config_file}")
|
|
include("${_config_file}")
|
|
if(TARGET "@INSTALL_CMAKE_NAMESPACE@::${_qt_plugin}")
|
|
list(APPEND _qt_plugins ${_qt_plugin})
|
|
endif()
|
|
endforeach()
|
|
set_property(TARGET ${_module_target} PROPERTY _qt_plugins ${_qt_plugins})
|
|
|
|
# TODO: Deprecated. Remove in Qt 7.
|
|
set_property(TARGET ${_module_target} PROPERTY QT_PLUGINS ${_qt_plugins})
|
|
|
|
get_target_property(_have_added_plugins_already ${_module_target} __qt_internal_plugins_added)
|
|
if(_have_added_plugins_already)
|
|
return()
|
|
endif()
|
|
|
|
foreach(plugin_target ${_qt_plugins})
|
|
__qt_internal_plugin_get_plugin_type("${plugin_target}" __has_plugin_type __plugin_type)
|
|
if(NOT __has_plugin_type)
|
|
continue()
|
|
endif()
|
|
|
|
__qt_internal_plugin_has_class_name("${plugin_target}" __has_class_name)
|
|
if(NOT __has_class_name)
|
|
continue()
|
|
endif()
|
|
|
|
list(APPEND "QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type}" "${plugin_target}")
|
|
|
|
__qt_internal_add_static_plugin_linkage("${plugin_target}" "${_module_target}")
|
|
__qt_internal_add_static_plugin_import_macro(
|
|
"${plugin_target}" ${_module_target} "@QT_MODULE@")
|
|
endforeach()
|
|
|
|
set("QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type}"
|
|
"${QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${__plugin_type}}"
|
|
PARENT_SCOPE
|
|
)
|
|
|
|
set_target_properties(${_module_target} PROPERTIES __qt_internal_plugins_added TRUE)
|
|
endfunction()
|
|
|
|
if(NOT @BUILD_SHARED_LIBS@ AND NOT QT_NO_CREATE_TARGETS)
|
|
__qt_internal_add_static_plugins_once()
|
|
endif()
|