Dynamic linking on WebAssembly involves preloading .so libraries during startup of application. Normally, those plugin preload lists are generating manually by user, which can be tedious. Add a bash script which demonstrates how to call python programs to generate preload lists. Change-Id: I0a9869ad0d26606f8b33af2c38248cec3088dd0d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> (cherry picked from commit 010ed1788402bf98d9b98500fdb1f61c333cebe5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
211 lines
9.5 KiB
CMake
211 lines
9.5 KiB
CMake
# Copyright (C) 2022 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
# Copy in Qt HTML/JS launch files for apps.
|
|
function(_qt_internal_wasm_add_target_helpers target)
|
|
|
|
_qt_test_emscripten_version()
|
|
get_target_property(targetType "${target}" TYPE)
|
|
if("${targetType}" STREQUAL "EXECUTABLE")
|
|
|
|
if(QT6_INSTALL_PREFIX)
|
|
set(WASM_BUILD_DIR "${QT6_INSTALL_PREFIX}")
|
|
elseif(QT_BUILD_DIR)
|
|
set(WASM_BUILD_DIR "${QT_BUILD_DIR}")
|
|
endif()
|
|
|
|
get_target_property(output_name ${target} OUTPUT_NAME)
|
|
if(output_name)
|
|
set(_target_output_name "${output_name}")
|
|
else()
|
|
set(_target_output_name "${target}")
|
|
endif()
|
|
|
|
set(APPNAME ${_target_output_name})
|
|
_qt_internal_wasm_export_name_for_target(_export_name ${target})
|
|
set(APPEXPORTNAME ${_export_name})
|
|
|
|
# Shared library builds preload plugins and qml imports by default.
|
|
# The json files are generated by scripts in qtbase/util/wasm/preload
|
|
if (QT_FEATURE_shared)
|
|
set(PRELOAD "preload: ['qt_plugins.json', 'qt_qml_imports.json'],")
|
|
else()
|
|
set(PRELOAD "")
|
|
endif()
|
|
|
|
get_target_property(target_output_directory ${target} RUNTIME_OUTPUT_DIRECTORY)
|
|
|
|
get_target_property(is_test ${target} _qt_is_test_executable)
|
|
get_target_property(is_manual_test ${target} _qt_is_manual_test)
|
|
if(is_test AND NOT is_manual_test)
|
|
# Keep in sync with testrunner_files in testlib/CMakeLists.txt
|
|
configure_file("${WASM_BUILD_DIR}/libexec/batchedtestrunner.html"
|
|
"${target_output_directory}/${_target_output_name}.html" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/qtestoutputreporter.css"
|
|
"${target_output_directory}/qtestoutputreporter.css" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/batchedtestrunner.js"
|
|
"${target_output_directory}/batchedtestrunner.js" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/emrunadapter.js"
|
|
"${target_output_directory}/emrunadapter.js" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/qwasmjsruntime.js"
|
|
"${target_output_directory}/qwasmjsruntime.js" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/qwasmtestmain.js"
|
|
"${target_output_directory}/qwasmtestmain.js" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/qtestoutputreporter.js"
|
|
"${target_output_directory}/qtestoutputreporter.js" COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/libexec/util.js"
|
|
"${target_output_directory}/util.js" COPYONLY)
|
|
else()
|
|
get_target_property(no_wasm_files ${target} NO_WASM_DEFAULT_FILES)
|
|
|
|
if(target_output_directory)
|
|
set(_target_directory "${target_output_directory}")
|
|
else()
|
|
set(_target_directory "${CMAKE_CURRENT_BINARY_DIR}")
|
|
endif()
|
|
|
|
if (NOT no_wasm_files)
|
|
configure_file("${WASM_BUILD_DIR}/plugins/platforms/wasm_shell.html"
|
|
"${_target_directory}/${_target_output_name}.html" @ONLY)
|
|
if(CMAKE_CONFIGURATION_TYPES) # if multiconfig generator
|
|
add_custom_command(
|
|
TARGET ${target} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
|
"${_target_directory}/${_target_output_name}.html"
|
|
${_target_directory}/$<CONFIG>/${_target_output_name}.html
|
|
)
|
|
add_custom_command(
|
|
TARGET ${target} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
|
"${WASM_BUILD_DIR}/plugins/platforms/qtloader.js"
|
|
${_target_directory}/$<CONFIG>/qtloader.js
|
|
)
|
|
add_custom_command(
|
|
TARGET ${target} POST_BUILD
|
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
|
"${WASM_BUILD_DIR}/plugins/platforms/qtlogo.svg"
|
|
${_target_directory}/$<CONFIG>/qtlogo.svg
|
|
)
|
|
else()
|
|
configure_file("${WASM_BUILD_DIR}/plugins/platforms/qtloader.js"
|
|
${_target_directory}/qtloader.js COPYONLY)
|
|
configure_file("${WASM_BUILD_DIR}/plugins/platforms/qtlogo.svg"
|
|
${_target_directory}/qtlogo.svg COPYONLY)
|
|
if(QT_FEATURE_shared)
|
|
set(TARGET_DIR "${_target_directory}")
|
|
set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
set(QT_HOST_DIR "${QT_HOST_PATH}")
|
|
set(QT_WASM_DIR "${WASM_BUILD_DIR}")
|
|
set(QT_INSTALL_DIR "${QT6_INSTALL_PREFIX}")
|
|
configure_file("${WASM_BUILD_DIR}/libexec/generate_default_preloads.sh.in"
|
|
"${_target_directory}/generate_default_preloads_for_${target}.sh" @ONLY)
|
|
endif()
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
if(QT_FEATURE_thread)
|
|
set(POOL_SIZE 4)
|
|
get_target_property(_tmp_poolSize "${target}" QT_WASM_PTHREAD_POOL_SIZE)
|
|
if(_tmp_poolSize)
|
|
set(POOL_SIZE ${_tmp_poolSize})
|
|
elseif(DEFINED QT_WASM_PTHREAD_POOL_SIZE)
|
|
set(POOL_SIZE ${QT_WASM_PTHREAD_POOL_SIZE})
|
|
endif()
|
|
target_link_options("${target}" PRIVATE "SHELL:-s PTHREAD_POOL_SIZE=${POOL_SIZE}")
|
|
message(DEBUG "Setting PTHREAD_POOL_SIZE to ${POOL_SIZE} for ${target}")
|
|
endif()
|
|
|
|
# Set initial memory size, either from user setting or to a minimum amount required by Qt.
|
|
get_target_property(_tmp_initialMemory "${target}" QT_WASM_INITIAL_MEMORY)
|
|
if(_tmp_initialMemory)
|
|
set(QT_WASM_INITIAL_MEMORY "${_tmp_initialMemory}")
|
|
elseif(NOT DEFINED QT_WASM_INITIAL_MEMORY)
|
|
set(QT_WASM_INITIAL_MEMORY "50MB")
|
|
endif()
|
|
target_link_options("${target}" PRIVATE "SHELL:-s INITIAL_MEMORY=${QT_WASM_INITIAL_MEMORY}")
|
|
|
|
# Set maximum memory size, either from user setting or to 4GB (the 32-bit maximum)
|
|
get_target_property(_tmp_maximumMemory "${target}" QT_WASM_MAXIMUM_MEMORY)
|
|
if(_tmp_maximumMemory)
|
|
set(QT_WASM_MAXIMUM_MEMORY "${_tmp_maximumMemory}")
|
|
elseif(NOT DEFINED QT_WASM_MAXIMUM_MEMORY)
|
|
if(QT_FEATURE_wasm_jspi)
|
|
# Work around Emscripten >2GB and JSPI compatibility issue.
|
|
set(QT_WASM_MAXIMUM_MEMORY "2GB")
|
|
else()
|
|
set(QT_WASM_MAXIMUM_MEMORY "4GB")
|
|
endif()
|
|
endif()
|
|
target_link_options("${target}" PRIVATE "SHELL:-s MAXIMUM_MEMORY=${QT_WASM_MAXIMUM_MEMORY}")
|
|
|
|
endif()
|
|
endfunction()
|
|
|
|
function(_qt_internal_add_wasm_extra_exported_methods target)
|
|
get_target_property(wasm_extra_exported_methods "${target}" QT_WASM_EXTRA_EXPORTED_METHODS)
|
|
|
|
set(wasm_default_exported_methods "UTF16ToString,stringToUTF16,JSEvents,specialHTMLTargets,FS,callMain")
|
|
|
|
if(NOT wasm_extra_exported_methods)
|
|
set(wasm_extra_exported_methods ${QT_WASM_EXTRA_EXPORTED_METHODS})
|
|
endif()
|
|
|
|
if(wasm_extra_exported_methods)
|
|
target_link_options("${target}" PRIVATE
|
|
"SHELL:-s EXPORTED_RUNTIME_METHODS=${wasm_default_exported_methods},${wasm_extra_exported_methods}"
|
|
)
|
|
else()
|
|
# an errant dangling comma will break this
|
|
target_link_options("${target}" PRIVATE
|
|
"SHELL:-s EXPORTED_RUNTIME_METHODS=${wasm_default_exported_methods}"
|
|
)
|
|
endif()
|
|
# TODO: Remove these flags when LLVM got fixed - QTBUG-131279
|
|
if(QT_FEATURE_thread)
|
|
target_link_options("${target}" PRIVATE
|
|
"SHELL:-s EXPORTED_FUNCTIONS=_main,__embind_initialize_bindings")
|
|
endif()
|
|
endfunction()
|
|
|
|
function(_qt_internal_set_wasm_export_name target)
|
|
_qt_internal_wasm_export_name_for_target(export_name ${target})
|
|
target_link_options("${target}" PRIVATE "SHELL:-s MODULARIZE=1")
|
|
target_link_options("${target}" PRIVATE "SHELL:-s EXPORT_NAME=${export_name}")
|
|
endfunction()
|
|
|
|
function(_qt_internal_wasm_export_name_for_target out target)
|
|
get_target_property(export_name "${target}" QT_WASM_EXPORT_NAME)
|
|
if(export_name)
|
|
set(${out} "${export_name}" PARENT_SCOPE)
|
|
else()
|
|
# Modify target name to remove characters which are not valid in
|
|
# JavaScript identifiers.
|
|
|
|
# Prefix leading digit with '_' (2dpaint -> _2dpaint)
|
|
if("${target}" MATCHES "^[0-9]")
|
|
set(targ "_${target}")
|
|
else()
|
|
set(targ "${target}")
|
|
endif()
|
|
|
|
# Replace remaining non-legal chars with '_' (target-foo -> target_foo)
|
|
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" targ "${targ}")
|
|
|
|
# Append "_entry" and return
|
|
set(${out} "${targ}_entry" PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
function(_qt_internal_set_wasm_embind_option target)
|
|
target_link_libraries("${target}" PRIVATE embind)
|
|
endfunction()
|
|
|
|
function(_qt_internal_finalize_wasm_app target)
|
|
_qt_internal_set_wasm_export_name("${target}")
|
|
_qt_internal_add_wasm_extra_exported_methods("${target}")
|
|
_qt_internal_wasm_add_target_helpers("${target}")
|
|
_qt_internal_set_wasm_embind_option("${target}")
|
|
endfunction()
|
|
|