qt5base-lts/cmake/QtPlugins.cmake.in
Alexandru Croitor 87ba355d95 Fix automatic plugin importing in static builds
QtPlugins.cmake.in uses file(GENERATE) and target_sources() to
propagate the generated cpp files which contain plugin initialization
code to their consuming targets.

Unfortunately due to a bug in CMake, if the file is generated in a
different scope than the consuming target, the CMake generation
step will fail saying that the source file can not be found.
See https://gitlab.kitware.com/cmake/cmake/issues/18399 for details.

In the case of qtdeclarative, find_package(Qt6) is called at the top
level scope (this is when the file gets generated),
but the targets are created in subdirectory scopes, and the GENERATED
source file property is not propagated across scropes.

Circumvent the issue by instead using file(WRITE) and configure_file()
which create the file at configure time rather than generate time.

This will pollute the current binary directory with some more files,
but at least successfully fixes the build.

Change-Id: I3ab3b12dcbf6a9d0ab9ee87173e4a1952325b37b
Reviewed-by: Leander Beernaert <leander.beernaert@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Qt CMake Build Bot
2019-10-09 09:22:27 +00:00

98 lines
4.3 KiB
CMake

@QT_MODULE_PLUGIN_INCLUDES@
if(NOT @BUILD_SHARED_LIBS@)
set(_module_target "@INSTALL_CMAKE_NAMESPACE@::@QT_MODULE@")
# 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()
unset(_aliased_target)
set(_default_plugins_are_enabled "$<NOT:$<STREQUAL:$<GENEX_EVAL:$<TARGET_PROPERTY:QT_DEFAULT_PLUGINS>>,0>>")
# Make sure to boolify the result of the expression, in case if the returned property value
# is empty.
set(_default_plugins_are_enabled_wrapped "$<BOOL:${_default_plugins_are_enabled}>")
set(_manual_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS>>")
set(_no_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_NO_PLUGINS>>")
# 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}")
get_target_property(_classname "${_plugin_target}" QT_PLUGIN_CLASS_NAME)
if(NOT _classname)
message("Warning: plugin ${_plugin_target} has no class name, skipping.")
continue()
endif()
get_target_property(_plugin_type "${_plugin_target}" QT_PLUGIN_TYPE)
if(NOT _plugin_type)
message("Warning: plugin ${_plugin_target} has no type ('${_plugin_type}'), skipping.")
continue()
endif()
list(APPEND "QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${_plugin_type}" "${target}")
set(_plugin_is_default "$<TARGET_PROPERTY:${_plugin_target},QT_DEFAULT_PLUGIN>")
# INCLUDE
set(_plugin_is_whitelisted "$<IN_LIST:${_plugin_target},${_manual_plugins_genex}>")
# Note: qt_import_plugins sets the QT_PLUGINS_${_plugin_type} to "-"
# when excluding it with EXCLUDE_BY_TYPE,
# which ensures that no plug-in will be supported unless explicitly re-added afterwards.
string(CONCAT _plugin_is_not_blacklisted
"$<AND:"
"$<NOT:" # EXCLUDE
"$<IN_LIST:${_plugin_target},${_no_plugins_genex}>"
">,"
# excludes both plugins targeted by EXCLUDE_BY_TYPE and not included in INCLUDE_BY_TYPE
"$<STREQUAL:,$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>>>"
">"
)
# Support INCLUDE_BY_TYPE
string(CONCAT _plugin_is_in_type_whitelist
"$<IN_LIST:"
"${_plugin_target},"
"$<GENEX_EVAL:"
"$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>"
">"
">"
)
# Complete condition that defines whether a static plugin is linked
string(CONCAT _plugin_condition
"$<BOOL:$<OR:"
"${_plugin_is_whitelisted},"
"${_plugin_is_in_type_whitelist},"
"$<AND:"
"${_default_plugins_are_enabled_wrapped},"
"${_plugin_is_default},"
"${_plugin_is_not_blacklisted}"
">"
">>"
)
# If this condition is true, we link against the plug-in
set(_plugin_genex "$<${_plugin_condition}:${_plugin_target}>")
target_link_libraries(${_module_target} INTERFACE "${_plugin_genex}")
set(_generated_qt_plugin_file_name
"${CMAKE_CURRENT_BINARY_DIR}/qt_@QT_MODULE@_${target}.cpp")
set(_generated_qt_plugin_file_name_template "${_generated_qt_plugin_file_name}.in")
set(_generated_qt_plugin_file_content "#include <QtPlugin>\nQ_IMPORT_PLUGIN(${_classname})")
# Generate a source file to import that plug-in. Has to be done with configure_file,
# because file(GENERATE) and target_sources has issues with scopes.
file(WRITE "${_generated_qt_plugin_file_name_template}"
"${_generated_qt_plugin_file_content}")
configure_file("${_generated_qt_plugin_file_name_template}"
"${_generated_qt_plugin_file_name}")
target_sources(${_module_target} INTERFACE
"$<${_plugin_condition}:${_generated_qt_plugin_file_name}>")
endforeach()
endif()