diff options
Diffstat (limited to 'util/wasm/preload/preload_qml_imports.py')
-rwxr-xr-x | util/wasm/preload/preload_qml_imports.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/util/wasm/preload/preload_qml_imports.py b/util/wasm/preload/preload_qml_imports.py new file mode 100755 index 0000000000..9af4fa2a28 --- /dev/null +++ b/util/wasm/preload/preload_qml_imports.py @@ -0,0 +1,101 @@ +#!/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)) |