Currently qtloader.js fetches and copies the files manually. By doing so we are missing some preproccessing by Emscripten preload plugins. Use Emscripten API to preload files, so preload plugin for .so can download, compile and resolve dependencies of imported shared libraries. This makes looking for dependencies in preload_qml_import.py no longer needed. Remove redundant code. Fixes: QTBUG-121817 Change-Id: Idd35f25d5f54123910f813a636407eea23e157cb Reviewed-by: Piotr Wierciński <piotr.wiercinski@qt.io>
102 lines
3.6 KiB
Python
Executable File
102 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (C) 2023 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import json
|
|
|
|
# Paths to shared libraries and qml imports on the Qt installation on the web server.
|
|
# "$QTDIR" is replaced by qtloader.js at load time (defaults to "qt"), and makes
|
|
# possible to relocate the application build relative to the Qt build on the web server.
|
|
qt_lib_path = "$QTDIR/lib"
|
|
qt_qml_path = "$QTDIR/qml"
|
|
|
|
# Path to QML imports on the in-memory file system provided by Emscripten. This script emits
|
|
# preload commands which copies QML imports to this directory. In addition, preload_qt_plugins.py
|
|
# creates (and preloads) a qt.conf file which makes Qt load QML plugins from this location.
|
|
qt_deploy_qml_path = "/qt/qml"
|
|
|
|
|
|
def eprint(*args, **kwargs):
|
|
print(*args, file=sys.stderr, **kwargs)
|
|
|
|
|
|
def preload_file(source, destination):
|
|
preload_files.append({"source": source, "destination": destination})
|
|
|
|
|
|
def extract_preload_files_from_imports(imports):
|
|
libraries = []
|
|
for qml_import in imports:
|
|
try:
|
|
relative_path = qml_import["relativePath"]
|
|
plugin = qml_import["plugin"]
|
|
|
|
# plugin .so
|
|
plugin_filename = "lib" + plugin + ".so"
|
|
so_plugin_source_path = os.path.join(
|
|
qt_qml_path, relative_path, plugin_filename
|
|
)
|
|
so_plugin_destination_path = os.path.join(
|
|
qt_deploy_qml_path, relative_path, plugin_filename
|
|
)
|
|
|
|
preload_file(so_plugin_source_path, so_plugin_destination_path)
|
|
so_plugin_qt_install_path = os.path.join(
|
|
qt_wasm_path, "qml", relative_path, plugin_filename
|
|
)
|
|
|
|
# qmldir file
|
|
qmldir_source_path = os.path.join(qt_qml_path, relative_path, "qmldir")
|
|
qmldir_destination_path = os.path.join(
|
|
qt_deploy_qml_path, relative_path, "qmldir"
|
|
)
|
|
preload_file(qmldir_source_path, qmldir_destination_path)
|
|
except Exception as e:
|
|
eprint(e)
|
|
continue
|
|
return libraries
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 4:
|
|
print("Usage: python preload_qml_imports.py <qml-source-path> <qt-host-path> <qt-wasm-path>")
|
|
sys.exit(1)
|
|
|
|
qml_source_path = sys.argv[1]
|
|
qt_host_path = sys.argv[2]
|
|
qt_wasm_path = sys.argv[3]
|
|
|
|
qml_import_path = os.path.join(qt_wasm_path, "qml")
|
|
qmlimportsscanner_path = os.path.join(qt_host_path, "libexec/qmlimportscanner")
|
|
|
|
eprint("runing qmlimportsscanner")
|
|
command = [qmlimportsscanner_path, "-rootPath", qml_source_path, "-importPath", qml_import_path]
|
|
result = subprocess.run(command, stdout=subprocess.PIPE)
|
|
imports = json.loads(result.stdout)
|
|
|
|
preload_files = []
|
|
libraries = extract_preload_files_from_imports(imports)
|
|
|
|
# Deploy plugin dependencies, that is, shared libraries used by the plugins.
|
|
# Skip some of the obvious libraries which will be
|
|
skip_libraries = [
|
|
"libQt6Core.so",
|
|
"libQt6Gui.so",
|
|
"libQt6Quick.so",
|
|
"libQt6Qml.so" "libQt6Network.so",
|
|
"libQt6OpenGL.so",
|
|
]
|
|
|
|
libraries = set(libraries) - set(skip_libraries)
|
|
for library in libraries:
|
|
source = os.path.join(qt_lib_path, library)
|
|
# Emscripten looks for shared libraries on "/", shared libraries
|
|
# most be deployed there instead of at /qt/lib
|
|
destination = os.path.join("/", library)
|
|
preload_file(source, destination)
|
|
|
|
print(json.dumps(preload_files, indent=2))
|