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
This commit is contained in:
Alexandru Croitor 2019-10-08 18:13:03 +02:00
parent f959882616
commit 87ba355d95

View File

@ -79,11 +79,19 @@ if(NOT @BUILD_SHARED_LIBS@)
set(_plugin_genex "$<${_plugin_condition}:${_plugin_target}>")
target_link_libraries(${_module_target} INTERFACE "${_plugin_genex}")
# Generate a source file to import that plug-in
file(GENERATE
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/qt_@QT_MODULE@_${target}.cpp"
CONTENT "#include <QtPlugin>\nQ_IMPORT_PLUGIN(${_classname})"
)
target_sources(${_module_target} INTERFACE "$<${_plugin_condition}:${CMAKE_CURRENT_BINARY_DIR}/qt_@QT_MODULE@_${target}.cpp>")
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()