summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2021-10-13 16:08:45 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-10-18 04:12:15 +0000
commit7ce23e5d9234dd5717e34a2140fdd696f5198915 (patch)
tree853d9c9c00704774d54f5d38b1c9429a8aab041f
parenta3bd4cd8bc7815303f8409d07df0321f2a8cf785 (diff)
CMake: Postpone target existence check for qml plugin targets
Each included qml Qt6FooPluginTargets.cmake file checks whether all the dependency targets that are referenced in the file already exist by the time the file is included. If one of the referenced targets is missing, the file sets ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE with a message mentioning which targets are missing and also sets ${CMAKE_FIND_PACKAGE_NAME}_FOUND to FALSE. All our qml package Config.cmake and Targets.cmake files are include()d by Qt6QmlPlugins.cmake using a file(GLOB) which means the order in which the files are loaded is implementation-defined. Furthermore we didn't check the above set variables after each inclusion, which means the values are overridden and the last plugin to be loaded determines whether the Qml package is found or not. If the last included file sets no error, it effectively silences any previously set error. Ever since we added dependencies between the qml plugin targets themselves, we hit the above situation and depending on the platform, no error was shown because the last file overrode any errors. But we finally got a specific platform (wasm) which unearthed the problem (QTBUG-97478). This can happen for any static Qt build though. To fix this properly, we will most likely have to rewrite the whole inclusion mechanism to use find_package() so that dependencies can be resolved recursively as needed. This is a non-trivial change that will have to be addressed in both qtbase and qtdeclarative. In the mean time, a stop-gap solution that this change implements is to include all the files while ignoring any error messages. Then include the files one more time and check for error message after each included file. All qml plugin targets should have been brought into scope with the first round of inclusions, thus circumventing "missing referenced target" errors, while still catching any other possible errors. Amends 6fd1216801f078f65be2cbc748cc459cb6912a4f 9fc302e6d146878103b3d105dce49c7695fcf93a c368175a9e0a0c120b5bb8a0a02859bfc0cf42ba in qtdeclarative. Fixes: QTBUG-97478 Task-number: QTBUG-95609 Task-number: QTBUG-97099 Change-Id: I157fa93fc979d726cd221d969b995b3642aeec77 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Alexey Edelev <alexey.edelev@qt.io> (cherry picked from commit aad4158959890b72afdd062614c1142c100c65b5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--cmake/QtPostProcessHelpers.cmake29
1 files changed, 29 insertions, 0 deletions
diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake
index 8af6f0f321..15cb45b6b4 100644
--- a/cmake/QtPostProcessHelpers.cmake
+++ b/cmake/QtPostProcessHelpers.cmake
@@ -410,11 +410,40 @@ function(qt_internal_create_plugins_files)
if(QT_MODULE STREQUAL "Qml")
set(QT_MODULE_PLUGIN_INCLUDES "${QT_MODULE_PLUGIN_INCLUDES}
+# Qml plugin targets might have dependencies on other qml plugin targets, but the Targets.cmake
+# files are included in the order that file(GLOB) returns, which means certain targets that are
+# referenced might not have been created yet, and \${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
+# might be set to a message saying those targets don't exist.
+#
+# Postpone checking of which targets don't exist until all Qml PluginConfig.cmake files have been
+# included, by including all the files one more time and checking for errors at each step.
+#
+# TODO: Find a better way to deal with this, perhaps by using find_package() instead of include
+# for the Qml PluginConfig.cmake files.
+
file(GLOB __qt_qml_plugins_config_file_list \"\${CMAKE_CURRENT_LIST_DIR}/QmlPlugins/${INSTALL_CMAKE_NAMESPACE}*Config.cmake\")
if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
+ # First round of inclusions ensure all qml plugin targets are brought into scope.
foreach(__qt_qml_plugin_config_file \${__qt_qml_plugins_config_file_list})
include(\${__qt_qml_plugin_config_file})
+
+ # Temporarily unset any failure markers.
+ unset(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
+ unset(\${CMAKE_FIND_PACKAGE_NAME}_FOUND)
endforeach()
+
+ # For the second round of inclusions, check and bail out early if there are errors.
+ foreach(__qt_qml_plugin_config_file \${__qt_qml_plugins_config_file_list})
+ include(\${__qt_qml_plugin_config_file})
+
+ if(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE)
+ string(APPEND \${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE
+ \"\nThe message was set in \${__qt_qml_plugin_config_file} \")
+ set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+ return()
+ endif()
+ endforeach()
+
endif()")
endif()