summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Wierciński <[email protected]>2024-06-26 16:32:00 +0200
committerPiotr Wierciński <[email protected]>2024-10-21 18:34:57 +0200
commitf0f89d3c1946fa819c01b28d757ba0a5074dd163 (patch)
treef540e6c069b64c226ce65f5c8483f81048ee3d57
parentbc2ed77a72cbcafecb6954ffa8703cbb5335490a (diff)
wasm: Generate plugin preloads for dynamic linking at install step
Dynamic linking on WebAssembly involves preloading .so libraries during startup of application. Normally, those plugin preload lists are generating manually by user. Automate this process as part of installation step. Change-Id: I364ebdb170f9fac53da241c96f601613352972d8 Reviewed-by: Morten Johan Sørvig <[email protected]>
-rw-r--r--cmake/QtBaseGlobalTargets.cmake8
-rw-r--r--src/corelib/Qt6WasmMacros.cmake43
-rwxr-xr-xutil/wasm/preload/preload_qml_imports.py15
-rwxr-xr-xutil/wasm/preload/preload_qt_plugins.py11
4 files changed, 64 insertions, 13 deletions
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index dc14a6110cd..ceea7726eae 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -378,9 +378,17 @@ if(APPLE)
elseif(WASM)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/wasmtestrunner/qt-wasmtestrunner.py"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" @ONLY)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qml_imports.py"
+ "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py" COPYONLY)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/preload/preload_qt_plugins.py"
+ "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py" COPYONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py"
DESTINATION "${INSTALL_LIBEXECDIR}")
+ qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qml_imports.py"
+ DESTINATION "${INSTALL_LIBEXECDIR}")
+ qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/preload_qt_plugins.py"
+ DESTINATION "${INSTALL_LIBEXECDIR}")
endif()
# Install CI support files to libexec.
diff --git a/src/corelib/Qt6WasmMacros.cmake b/src/corelib/Qt6WasmMacros.cmake
index 9166b7fdf3d..aabd39e83c0 100644
--- a/src/corelib/Qt6WasmMacros.cmake
+++ b/src/corelib/Qt6WasmMacros.cmake
@@ -91,6 +91,49 @@ function(_qt_internal_wasm_add_target_helpers target)
${_target_directory}/qtloader.js COPYONLY)
configure_file("${WASM_BUILD_DIR}/plugins/platforms/qtlogo.svg"
${_target_directory}/qtlogo.svg COPYONLY)
+
+ if(QT_FEATURE_shared)
+ configure_file("${WASM_BUILD_DIR}/libexec/preload_qml_imports.py"
+ ${_target_directory}/preload_qml_imports.py COPYONLY)
+ configure_file("${WASM_BUILD_DIR}/libexec/preload_qt_plugins.py"
+ ${_target_directory}/preload_qt_plugins.py COPYONLY)
+ endif()
+
+ if(CMAKE_STAGING_PREFIX)
+ install(FILES
+ ${_target_directory}/qtloader.js
+ ${_target_directory}/qtlogo.svg
+ ${_target_directory}/${_target_output_name}.html
+ ${_target_directory}/${_target_output_name}.wasm
+ ${_target_directory}/${_target_output_name}.js
+ DESTINATION ${CMAKE_STAGING_PREFIX})
+ if(QT_FEATURE_thread)
+ install(FILES
+ ${_target_directory}/${_target_output_name}.worker.js
+ DESTINATION ${CMAKE_STAGING_PREFIX})
+ endif()
+
+ if(QT_FEATURE_shared)
+ find_package(Python3 COMPONENTS Interpreter)
+ if(Python3_Interpreter_FOUND)
+ install(FILES
+ ${_target_directory}/preload_qml_imports.py
+ ${_target_directory}/preload_qt_plugins.py
+ DESTINATION ${CMAKE_STAGING_PREFIX})
+ install(CODE "execute_process(COMMAND ${Python3_EXECUTABLE} \
+ ${_target_directory}/preload_qml_imports.py \
+ ${CMAKE_CURRENT_SOURCE_DIR} ${QT_HOST_PATH} \
+ ${QT6_INSTALL_PREFIX} \
+ ${CMAKE_STAGING_PREFIX})")
+ install(CODE "execute_process(COMMAND ${Python3_EXECUTABLE} \
+ ${_target_directory}/preload_qt_plugins.py \
+ ${QT6_INSTALL_PREFIX} \
+ ${CMAKE_STAGING_PREFIX})")
+ else()
+ message(WARNING "Python 3 not found. Generating preload list for dynamic linking is disabled.")
+ endif()
+ endif()
+ endif()
endif()
endif()
endif()
diff --git a/util/wasm/preload/preload_qml_imports.py b/util/wasm/preload/preload_qml_imports.py
index 9af4fa2a282..b78ef5ee744 100755
--- a/util/wasm/preload/preload_qml_imports.py
+++ b/util/wasm/preload/preload_qml_imports.py
@@ -19,10 +19,6 @@ qt_qml_path = "$QTDIR/qml"
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})
@@ -55,24 +51,23 @@ def extract_preload_files_from_imports(imports):
)
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>")
+ if len(sys.argv) != 5:
+ print("Usage: python preload_qml_imports.py <qml-source-path> <qt-host-path> <qt-wasm-path> <output-dir>")
sys.exit(1)
qml_source_path = sys.argv[1]
qt_host_path = sys.argv[2]
qt_wasm_path = sys.argv[3]
+ output_dir = sys.argv[4]
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)
@@ -98,4 +93,6 @@ if __name__ == "__main__":
destination = os.path.join("/", library)
preload_file(source, destination)
- print(json.dumps(preload_files, indent=2))
+ with open(f"{output_dir}/qt_qml_imports.json", "w") as f:
+ f.write(json.dumps(preload_files, indent=2))
+
diff --git a/util/wasm/preload/preload_qt_plugins.py b/util/wasm/preload/preload_qt_plugins.py
index 362d1297320..4b9b3683a70 100755
--- a/util/wasm/preload/preload_qt_plugins.py
+++ b/util/wasm/preload/preload_qt_plugins.py
@@ -27,11 +27,12 @@ def find_so_files(directory):
if __name__ == "__main__":
- if len(sys.argv) != 2:
- print("Usage: python make_qt_symlinks.py <qt-wasm-path>")
+ if len(sys.argv) != 3:
+ print("Usage: python preload_qt_plugins.py <qt-wasm-path> <output-dir>")
sys.exit(1)
qt_wasm_path = sys.argv[1]
+ output_dir = sys.argv[2]
# preload all plugins
plugins = find_so_files(os.path.join(qt_wasm_path, "plugins"))
@@ -47,8 +48,10 @@ if __name__ == "__main__":
# and QML imports in /qt/plugins and /qt/qml. The qt.conf file is
# written to the current directory.
qtconf = "[Paths]\nPrefix = /qt\n"
- with open("qt.conf", "w") as f:
+ with open(f"{output_dir}/qt.conf", "w") as f:
f.write(qtconf)
preload.append({"source": "qt.conf", "destination": "/qt.conf"})
- print(json.dumps(preload, indent=2))
+ with open(f"{output_dir}/qt_plugins.json", "w") as f:
+ f.write(json.dumps(preload, indent=2))
+