aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2020-11-17 18:39:51 +0100
committerAlexandru Croitor <alexandru.croitor@qt.io>2020-11-18 19:16:06 +0100
commite2f6c69c228fd2553514d3de49edcc4ec7d167e2 (patch)
tree5c565cd9710ebbaea322c2811ea17d7707d90f9f /src/qml
parent8a54a6fc2efd13f0310ec71793f624cdf28bd1c9 (diff)
CMake: Match qmake generated resource name for qmldir files
When doing static builds, mkspecs/qml_module.prf embeds the qmldir file and any additional foo.qml files into a generated Qt resource file. The resource name is called qmake_<qml_plugin_uri>.qrc. In turn, certain Qt modules and plugins code call Q_INIT_RESOURCE(<qml_plugin_uri>) to initialize the resources. When Qt is built with CMake there were 2 differences. Because the resource files are not compiled into the static libraries but rather passed around as object files, there is no need to call Q_INIT_RESOURCE() anymore. The second difference was that the generated resource name for resources containing the qmldir file was '<qml_plugin_uri>_qmldir'. The differences in the CMake build caused issues when linking a QtQuick3D example project with a static Qt. That happened due to the mismatch of the generated resource name in the Q_INIT_RESOURCE() call. Unfortunately these calls can't be removed during the build system transition phase because that would break qmake Qt builds. To fix this, change the name of the CMake generated resource to match the qmake name. This avoids the undefined symbol errors during linking, but is actually a no-op! That's because the global initializer in the linked resource object file will be called before the manual Q_INIT_RESOURCE() call, effectively making the latter a no-op. Note there is one more difference regarding the CMake build. The Qt CMake builds creates 2 different resource files, one for the qmldir file (inside qt6_add_qml_module) and another separate resource for qml files (inside qt6_target_qml_files). qmake in comparison creates only one resource file for both. In practice this shouldn't affect or break anything, because even if there is no explicit Q_INIT_RESOURCE() call for the qml files resource, the global initializer will still be called from the linked in object file. An issue might happen if there are qml files, but no qmldir file, because then the qmake-required Q_INIT_RESOURCE() would not be called due to the missing qmldir resource (as generated by CMake). I think such a scenario is very unlikely if not impossible. Task-number: QTBUG-88425 Change-Id: Ib12d93d0dae52785ba8182db6829f03524723ca7 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/Qt6QmlMacros.cmake13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake
index 733dd6725e..7cf2e9bef4 100644
--- a/src/qml/Qt6QmlMacros.cmake
+++ b/src/qml/Qt6QmlMacros.cmake
@@ -371,8 +371,19 @@ function(qt6_add_qml_module target)
# Embed qmldir in static builds
if (is_static)
+ # The qmldir resource name needs to match the one generated by qmake's qml_module.prf, to
+ # ensure that all Q_INIT_RESOURCE(resource_name) calls in Qt code don't lead to undefined
+ # symbol errors when linking an application project.
+ # The Q_INIT_RESOURCE() calls are not strictly necessary anymore because the CMake Qt
+ # build passes around the compiled resources as object files.
+ # These object files have global initiliazers that don't get discared when linked into
+ # an application (as opposed to when the resource libraries were embedded into the static
+ # libraries when Qt was built with qmake).
+ # The reason to match the naming is to ensure that applications link successfully regardless
+ # if Qt was built with CMake or qmake, while the build system transition phase is still
+ # happening.
string(REPLACE "/" "_" qmldir_resource_name ${arg_TARGET_PATH})
- string(APPEND qmldir_resource_name "_qmldir")
+ string(PREPEND qmldir_resource_name "qmake_")
set_source_files_properties("${qmldir_file}"
PROPERTIES QT_RESOURCE_ALIAS "qmldir"