From 74c55fe6d87d94bb83f1a13da45f3599e5708297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Han=C3=A7erli?= <burak.hancerli@qt.io> Date: Thu, 23 Jan 2025 14:34:05 +0000 Subject: [PATCH] Remove importdummy dependency --- src/CMakeLists.txt | 104 ++++++++++++++++++++++++++++++++++-- src/backend/importdummy.qml | 45 ---------------- 2 files changed, 101 insertions(+), 48 deletions(-) delete mode 100644 src/backend/importdummy.qml diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4330115..327a9b6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,108 @@ find_package( Qt6 - COMPONENTS Core Widgets Quick Gui Qml Multimedia MultimediaWidgets Concurrent Network WebSockets + COMPONENTS + Core Widgets Quick Gui Qml Multimedia MultimediaWidgets Concurrent Network WebSockets + TextToSpeech Location Sensors WebView Positioning REQUIRED ) -find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Network WebSockets) +find_package( + QT NAMES Qt6 Qt5 REQUIRED + COMPONENTS + Core Network WebSockets TextToSpeech Location Sensors WebView Positioning) + +# In shared Qt builds, the qml plugins don't have dependencies on their backing libraries, and +# thus the backing library packages are not automatically looked up. +# The StandaloneTests directory contains Config files that find_package all installed Qt packages. +# Abuse that, and include all of them to make all the backing libraries available as imported +# targets. +find_package(Qt6 COMPONENTS BuildInternals) +if(Qt6BuildInternals_DIR) + set(standalone_tests_dir "${Qt6BuildInternals_DIR}/StandaloneTests") + if(EXISTS "${standalone_tests_dir}") + # Glob the config files in there. + file(GLOB_RECURSE standalone_tests_files "${standalone_tests_dir}/*TestsConfig.cmake") + + # Include each one of them. + foreach(standalone_tests_file IN LISTS standalone_tests_files) + include("${standalone_tests_file}") + endforeach() + endif() +endif() + +set(imports "") + +# Get all imported targets. +get_property(imported_targets DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY IMPORTED_TARGETS) + +# Horrible hack for shared qt builds, to ensure we bundle all known shared library qml plugins. +# Do that by finding all qml modules, their plugins, the location of the plugins, then finding the +# path to the qmldir files of the plugins, extract the module name, and adding it as an import +# statement into a dynamically generated qml file. +foreach(imported_target IN LISTS imported_targets) + # Get all qml module targets, they would have the _qt_qml_module_installed_plugin_target + # property set. + get_target_property(qml_plugin_target "${imported_target}" + _qt_qml_module_installed_plugin_target) + + if(qml_plugin_target) + message(STATUS + "Imported target: ${imported_target} -> ${qml_plugin_target}") + + # Get location of the plugin file. + get_target_property(imported_location "${qml_plugin_target}" IMPORTED_LOCATION) + if(NOT EXISTS "${imported_location}") + continue() + endif() + + # Get parent dir of the plugin file. + get_filename_component(imported_location_dir "${imported_location}" DIRECTORY) + + # Build path to qmldir in the same directory. We assume the qmldir is always next + # to the plugin file. That's at least usually the case for Qt qml plugins. + set(qmldir_path "${imported_location_dir}/qmldir") + if(NOT EXISTS "${qmldir_path}") + continue() + endif() + + # Read qmldir file contents. + file(READ "${qmldir_path}" qmldir_content) + if(qmldir_content STREQUAL "") + continue() + endif() + + # Find the module name in the qmldir file + string(REGEX MATCH "module ([^\n]+)" module_match "${qmldir_content}") + if(CMAKE_MATCH_1) + # Add the module name as an import to the imports list + list(APPEND imports "import ${CMAKE_MATCH_1}") + endif() + endif() +endforeach() + +set(imports_file_path "${CMAKE_CURRENT_BINARY_DIR}/dynamic_imports.qml") + +# Needed to stop __qt_get_relative_resource_path_for_file from erroring out. +set_source_files_properties("${imports_file_path}" + PROPERTIES QT_RESOURCE_ALIAS "dynamic_imports.qml") +if(imports) + list(REMOVE_DUPLICATES imports) + string(REPLACE ";" "\n" imports "${imports}") +endif() + +# Use file(GENERATE) to prevent touching the file if the contents hasn't changed. +set(dummy_valid_content "ApplicationWindow { + visible: true + width: 640 + height: 480 +}") + +file(GENERATE OUTPUT "${imports_file_path}" CONTENT "${imports} + +${dummy_valid_content} +") qt_add_executable(${PROJECT_NAME} - backend/importdummy.qml backend/main.cpp backend/logger.h backend/backend.cpp backend/backend.h @@ -27,6 +122,7 @@ qt_add_qml_module(${PROJECT_NAME} URI AndroidUI VERSION 1.0 QML_FILES + "${imports_file_path}" Constants.qml HomePage.qml Main.qml @@ -52,6 +148,8 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Qml Qt6::GuiPrivate Qt6::Multimedia Qt6::MultimediaWidgets Qt6::Concurrent Qt6::Network Qt6::WebSockets + Qt6::TextToSpeech Qt6::Location Qt6::Sensors + Qt6::WebView Qt6::Positioning ZXing::ZXing ) diff --git a/src/backend/importdummy.qml b/src/backend/importdummy.qml deleted file mode 100644 index f6836ef..0000000 --- a/src/backend/importdummy.qml +++ /dev/null @@ -1,45 +0,0 @@ -// Hack to force the qml plugins to be linked statically - -import QtQuick -import QtQuick.Controls - -import QtQml -import QtQml.Models -import QtQml.StateMachine - -import QtQuick3D -import QtQuick3D.AssetUtils -import QtQuick3D.Effects -import QtQuick3D.Helpers -import QtQuick3D.ParticleEffects -import QtQuick3D.Particles3D -import QtQuick.VirtualKeyboard - -import QtQuick.Studio.Application -import QtQuick.Studio.Components -import QtQuick.Studio.Effects -import QtQuick.Studio.EventSimulator -import QtQuick.Studio.EventSystem -import QtQuick.Studio.LogicHelper -import QtQuick.Studio.MultiText -import QtQuick.Studio.Utils -import QtQuick.Studio.DesignEffects - -import QtQuick.Timeline -import QtQuick.Timeline.BlendTrees - -import QtQuickUltralite.Extras -import QtQuickUltralite.Layers - -import QtCharts - -import FlowView -import Qt.labs.folderlistmodel - -import QtWebSockets - -ApplicationWindow { - visible: true - width: 640 - height: 480 -} -- GitLab