summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.prev_configure.cmake12
-rw-r--r--CMakeLists.txt6
-rw-r--r--cmake/QtAutoDetect.cmake59
-rw-r--r--cmake/QtBaseConfigureTests.cmake2
-rw-r--r--cmake/QtBaseGlobalTargets.cmake1
-rw-r--r--cmake/QtBuild.cmake2
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsConfig.cmake2
-rw-r--r--cmake/QtCompilerOptimization.cmake9
-rw-r--r--cmake/QtExecutableHelpers.cmake3
-rw-r--r--cmake/QtFlagHandlingHelpers.cmake4
-rw-r--r--cmake/QtModuleHelpers.cmake4
-rw-r--r--cmake/QtPlatformSupport.cmake2
-rw-r--r--cmake/QtPluginHelpers.cmake4
-rw-r--r--cmake/QtPriHelpers.cmake5
-rw-r--r--cmake/QtWasmHelpers.cmake92
-rw-r--r--configure.cmake23
-rw-r--r--configure.json15
-rw-r--r--mkspecs/features/wasm/wasm.prf24
-rw-r--r--mkspecs/wasm-emscripten/qmake.conf12
-rw-r--r--src/corelib/CMakeLists.txt4
-rw-r--r--src/corelib/Qt6CoreConfigExtras.cmake.in4
-rw-r--r--src/corelib/Qt6CoreMacros.cmake3
-rw-r--r--src/corelib/Qt6WasmMacros.cmake31
-rw-r--r--src/gui/configure.cmake9
-rw-r--r--src/plugins/platforms/CMakeLists.txt2
-rw-r--r--src/plugins/platforms/wasm/CMakeLists.txt78
26 files changed, 370 insertions, 42 deletions
diff --git a/.prev_configure.cmake b/.prev_configure.cmake
index 3d76317909..f796eddc8a 100644
--- a/.prev_configure.cmake
+++ b/.prev_configure.cmake
@@ -341,7 +341,7 @@ qt_feature("android-style-assets" PRIVATE
)
qt_feature("shared" PUBLIC
LABEL "Building shared libraries"
- AUTODETECT NOT UIKIT
+ AUTODETECT NOT UIKIT AND NOT WASM
CONDITION BUILD_SHARED_LIBS
)
qt_feature_definition("shared" "QT_STATIC" NEGATE PREREQUISITE "!defined(QT_SHARED) && !defined(QT_STATIC)")
@@ -837,7 +837,7 @@ qt_feature_definition("concurrent" "QT_NO_CONCURRENT" NEGATE VALUE "1")
qt_feature("dbus" PUBLIC PRIVATE
LABEL "Qt D-Bus"
AUTODETECT NOT UIKIT AND NOT ANDROID
- CONDITION QT_FEATURE_thread
+ CONDITION QT_FEATURE_thread AND NOT WASM
)
qt_feature_definition("dbus" "QT_NO_DBUS" NEGATE VALUE "1")
qt_feature("dbus-linked" PRIVATE
@@ -866,7 +866,7 @@ qt_feature("printsupport" PRIVATE
)
qt_feature("sql" PRIVATE
LABEL "Qt Sql"
- CONDITION QT_FEATURE_thread
+ CONDITION QT_FEATURE_thread AND NOT WASM
)
qt_feature("testlib" PRIVATE
LABEL "Qt Testlib"
@@ -1034,6 +1034,7 @@ qt_configure_add_summary_entry(ARGS "pkg-config")
qt_configure_add_summary_entry(ARGS "libudev")
qt_configure_add_summary_entry(ARGS "system-zlib")
qt_configure_add_summary_entry(ARGS "zstd")
+qt_configure_add_summary_entry(ARGS "thread")
qt_configure_end_summary_section() # end of "Support enabled for" section
qt_configure_add_report_entry(
TYPE NOTE
@@ -1041,6 +1042,11 @@ qt_configure_add_report_entry(
CONDITION NOT QT_FEATURE_shared
)
qt_configure_add_report_entry(
+ TYPE NOTE
+ MESSAGE "Using pthreads"
+ CONDITION QT_FEATURE_thread
+)
+qt_configure_add_report_entry(
TYPE ERROR
MESSAGE "Debug build wihtout Release build is not currently supported on ios see QTBUG-71990. Use -debug-and-release."
CONDITION IOS AND QT_FEATURE_debug AND NOT QT_FEATURE_debug_and_release
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2e05aa52e8..18eaf95c50 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,6 +94,12 @@ if(NOT QT_BUILD_STANDALONE_TESTS)
# Needed when building qtbase for android.
include(src/corelib/Qt6AndroidMacros.cmake)
+ if(WASM)
+ # Needed when building for WebAssembly.
+ include(cmake/QtWasmHelpers.cmake)
+ qt_internal_setup_wasm_target_properties(Platform)
+ endif()
+
# Set up optimization flags like in qmake.
# This function must be called after the global QT_FEATURE_xxx variables have been set up,
# aka after QtBaseGlobalTargets is processed.
diff --git a/cmake/QtAutoDetect.cmake b/cmake/QtAutoDetect.cmake
index d3173dfad0..b32258e929 100644
--- a/cmake/QtAutoDetect.cmake
+++ b/cmake/QtAutoDetect.cmake
@@ -5,6 +5,64 @@
# Make sure to not run detection when building standalone tests, because the detection was already
# done when initially configuring qtbase.
+
+function(qt_auto_detect_wasm)
+ if("${QT_QMAKE_TARGET_MKSPEC}" STREQUAL "wasm-emscripten" AND DEFINED ENV{EMSDK})
+ if(NOT DEFINED QT_AUTODETECT_WASM)
+ set(QT_AUTODETECT_WASM TRUE CACHE BOOL "")
+ # detect EMSCRIPTEN_ROOT path
+ file(READ "$ENV{EMSDK}/.emscripten" ver)
+ string(REGEX MATCH "EMSCRIPTEN_ROOT.*$" EMROOT "${ver}")
+ string(REGEX MATCH "'([^' ]*)'" EMROOT2 "${EMROOT}")
+ string(REPLACE "'" "" EMROOT_PATH "${EMROOT2}")
+
+ # get emscripten version
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ set (EXECUTE_COMMANDPATH "$ENV{EMSDK}/${EMROOT_PATH}/emcc.bat")
+ else()
+ set (EXECUTE_COMMANDPATH "$ENV{EMSDK}/${EMROOT_PATH}/emcc")
+ endif()
+
+ file(TO_NATIVE_PATH "${EXECUTE_COMMANDPATH}" EXECUTE_COMMAND)
+ execute_process(COMMAND ${EXECUTE_COMMAND} --version
+ OUTPUT_VARIABLE emOutput
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE emrun_error
+ RESULT_VARIABLE result)
+ if(NOT emOutput)
+ message(FATAL_ERROR
+ "Can't determine Emscripten version! Error: ${emrun_error}")
+ endif()
+ string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" CMAKE_EMSDK_REGEX_VERSION "${emOutput}")
+ set(EMCC_VERSION "${CMAKE_EMSDK_REGEX_VERSION}" CACHE STRING INTERNAL FORCE)
+
+ # find toolchain file
+ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
+ set(wasm_toolchain_file "$ENV{EMSDK}/${EMROOT_PATH}/cmake/Modules/Platform/Emscripten.cmake")
+ set(CMAKE_TOOLCHAIN_FILE "${wasm_toolchain_file}" CACHE STRING "" FORCE)
+ endif()
+
+ if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
+ message(STATUS "Emscripten ${CMAKE_EMSDK_REGEX_VERSION} toolchain file detected at ${CMAKE_TOOLCHAIN_FILE}")
+ else()
+ message(FATAL_ERROR "Cannot find the toolchain file Emscripten.cmake. "
+ "Please specify the toolchain file with -DCMAKE_TOOLCHAIN_FILE=<file>.")
+ endif()
+
+ if(NOT DEFINED BUILD_SHARED_LIBS)
+ set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Qt statically or dynamically" FORCE)
+ endif()
+
+ if(BUILD_SHARED_LIBS)
+ message(FATAL_ERROR
+ "Building Qt for ${CMAKE_SYSTEM_NAME} as shared libraries is not supported.")
+ endif()
+ # this version of Qt needs this version of emscripten
+ set(QT_EMCC_RECOMMENDED_VERSION 2.0.14 CACHE STRING INTERNAL FORCE)
+ endif()
+ endif()
+endfunction()
+
function(qt_auto_detect_cmake_generator)
if(NOT CMAKE_GENERATOR MATCHES "Ninja" AND NOT QT_SILENCE_CMAKE_GENERATOR_WARNING)
message(WARNING
@@ -340,3 +398,4 @@ qt_auto_detect_ios()
qt_auto_detect_android()
qt_auto_detect_vpckg()
qt_auto_detect_pch()
+qt_auto_detect_wasm()
diff --git a/cmake/QtBaseConfigureTests.cmake b/cmake/QtBaseConfigureTests.cmake
index cbd482bd59..67cee65d4a 100644
--- a/cmake/QtBaseConfigureTests.cmake
+++ b/cmake/QtBaseConfigureTests.cmake
@@ -32,7 +32,7 @@ function(qt_run_config_test_architecture)
# With emscripten the application entry point is a .js file (to be run with node for example),
# but the real "data" is in the .wasm file, so that's where we need to look for the ABI, etc.
# information.
- if (EMSCRIPTEN)
+ if (WASM)
set(_arch_file_suffix ".wasm")
endif()
diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake
index 03f4b4d76a..580e84f80a 100644
--- a/cmake/QtBaseGlobalTargets.cmake
+++ b/cmake/QtBaseGlobalTargets.cmake
@@ -214,6 +214,7 @@ qt_copy_or_install(FILES
cmake/QtTestHelpers.cmake
cmake/QtToolchainHelpers.cmake
cmake/QtToolHelpers.cmake
+ cmake/QtWasmHelpers.cmake
cmake/QtWrapperScriptHelpers.cmake
cmake/QtWriteArgsFile.cmake
DESTINATION "${__GlobalConfig_install_dir}"
diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake
index 9766e7f683..f31a215a4a 100644
--- a/cmake/QtBuild.cmake
+++ b/cmake/QtBuild.cmake
@@ -302,7 +302,7 @@ elseif(IOS)
set(QT_DEFAULT_MKSPEC macx-ios-clang)
elseif(APPLE)
set(QT_DEFAULT_MKSPEC macx-clang)
-elseif(EMSCRIPTEN)
+elseif(WASM)
set(QT_DEFAULT_MKSPEC wasm-emscripten)
elseif(QNX)
# Certain POSIX defines are not set if we don't compile with -std=gnuXX
diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
index 9cd5c6ecfb..6192d809a3 100644
--- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
+++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
@@ -120,7 +120,7 @@ function(qt_build_internals_disable_pkg_config_if_needed)
set(pkg_config_enabled ON)
qt_build_internals_find_pkg_config_executable()
- if(APPLE OR WIN32 OR QNX OR ANDROID OR (NOT PKG_CONFIG_EXECUTABLE))
+ if(APPLE OR WIN32 OR QNX OR ANDROID OR WASM OR (NOT PKG_CONFIG_EXECUTABLE))
set(pkg_config_enabled OFF)
endif()
diff --git a/cmake/QtCompilerOptimization.cmake b/cmake/QtCompilerOptimization.cmake
index ed6921da53..c8c3da78d5 100644
--- a/cmake/QtCompilerOptimization.cmake
+++ b/cmake/QtCompilerOptimization.cmake
@@ -136,7 +136,7 @@ endif()
# TODO: Missing mkspecs flags we don't handle below: win32-clang-g++, win32-clang-msvc, rtems-base
#
# gcc and clang base
-if(GCC OR CLANG)
+if(GCC OR CLANG AND NOT WASM)
set(QT_CFLAGS_OPTIMIZE "-O2")
set(QT_CFLAGS_OPTIMIZE_FULL "-O3")
set(QT_CFLAGS_OPTIMIZE_DEBUG "-Og")
@@ -187,3 +187,10 @@ if(ICC)
set(QT_CFLAGS_OPTIMIZE_SIZE "-Os")
endif()
endif()
+
+if(WASM)
+ set(QT_CFLAGS_OPTIMIZE "-O2")
+ set(QT_CFLAGS_OPTIMIZE_FULL "-O3")
+ set(QT_CFLAGS_OPTIMIZE_SIZE "-Os")
+ set(QT_CFLAGS_OPTIMIZE_DEBUG "-g2")
+endif()
diff --git a/cmake/QtExecutableHelpers.cmake b/cmake/QtExecutableHelpers.cmake
index d96f2edaa1..c25a9ae8a3 100644
--- a/cmake/QtExecutableHelpers.cmake
+++ b/cmake/QtExecutableHelpers.cmake
@@ -33,6 +33,9 @@ function(qt_internal_add_executable name)
PROPERTY EXCLUDE_FROM_ALL "$<NOT:$<CONFIG:${QT_MULTI_CONFIG_FIRST_CONFIG}>>")
endif()
+ if(WASM)
+ qt6_wasm_add_target_helpers("${name}")
+ endif()
if (arg_VERSION)
if(arg_VERSION MATCHES "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+")
# nothing to do
diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake
index 003e1a45ec..cbc39cbf1a 100644
--- a/cmake/QtFlagHandlingHelpers.cmake
+++ b/cmake/QtFlagHandlingHelpers.cmake
@@ -88,7 +88,7 @@ function(qt_internal_apply_gc_binaries target visibility)
message(FATAL_ERROR "Visibitily setting must be one of PRIVATE, INTERFACE or PUBLIC.")
endif()
- if ((GCC OR CLANG) AND NOT EMSCRIPTEN AND NOT UIKIT AND NOT MSVC)
+ if ((GCC OR CLANG) AND NOT WASM AND NOT UIKIT AND NOT MSVC)
if(APPLE)
set(gc_sections_flag "-Wl,-dead_strip")
elseif(SOLARIS)
@@ -101,7 +101,7 @@ function(qt_internal_apply_gc_binaries target visibility)
target_link_options("${target}" ${visibility} "${gc_sections_flag}")
endif()
- if((GCC OR CLANG OR ICC) AND NOT EMSCRIPTEN AND NOT UIKIT AND NOT MSVC)
+ if((GCC OR CLANG OR ICC) AND NOT WASM AND NOT UIKIT AND NOT MSVC)
set(split_sections_flags "-ffunction-sections" "-fdata-sections")
endif()
if(split_sections_flags)
diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake
index 4a3237d4ea..95272d3932 100644
--- a/cmake/QtModuleHelpers.cmake
+++ b/cmake/QtModuleHelpers.cmake
@@ -552,7 +552,9 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})")
PRIVATE_HEADER DESTINATION ${INSTALL_INCLUDEDIR}/${module_include_name}/${PROJECT_VERSION}/${module}/private
)
- qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${INSTALL_LIBDIR}" RELATIVE_RPATH)
+ if(BUILD_SHARED_LIBS)
+ qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${INSTALL_LIBDIR}" RELATIVE_RPATH)
+ endif()
if (ANDROID AND NOT arg_HEADER_MODULE)
# Record install library location so it can be accessed by
diff --git a/cmake/QtPlatformSupport.cmake b/cmake/QtPlatformSupport.cmake
index 02c0c0fb63..94ff238418 100644
--- a/cmake/QtPlatformSupport.cmake
+++ b/cmake/QtPlatformSupport.cmake
@@ -16,7 +16,7 @@ qt_set01(QNX CMAKE_SYSTEM_NAME STREQUAL "QNX") # FIXME: How to identify this?
qt_set01(OPENBSD CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # FIXME: How to identify this?
qt_set01(FREEBSD CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FIXME: How to identify this?
qt_set01(NETBSD CMAKE_SYSTEM_NAME STREQUAL "NetBSD") # FIXME: How to identify this?
-qt_set01(WASM CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
+qt_set01(WASM CMAKE_SYSTEM_NAME STREQUAL "Emscripten" OR EMSCRIPTEN)
qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD)
diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake
index e2289a0561..86d59cb8ab 100644
--- a/cmake/QtPluginHelpers.cmake
+++ b/cmake/QtPluginHelpers.cmake
@@ -338,7 +338,9 @@ function(qt_internal_add_plugin target)
NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE}::
DESTINATION "${config_install_dir}"
)
- qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${install_directory}" RELATIVE_RPATH)
+ if(BUILD_SHARED_LIBS)
+ qt_apply_rpaths(TARGET "${target}" INSTALL_PATH "${install_directory}" RELATIVE_RPATH)
+ endif()
endif()
if (NOT arg_ALLOW_UNDEFINED_SYMBOLS)
diff --git a/cmake/QtPriHelpers.cmake b/cmake/QtPriHelpers.cmake
index 47be8a6194..e425a4ec2b 100644
--- a/cmake/QtPriHelpers.cmake
+++ b/cmake/QtPriHelpers.cmake
@@ -563,7 +563,6 @@ QT_PATCH_VERSION = ${PROJECT_VERSION_PATCH}
list(APPEND extra_statements "QT_LIBINFIX = ${QT_LIBINFIX}")
endif()
- # TODO: Add QT_EMCC_VERSION when WASM is ported over.
if(APPLECLANG)
set(compiler_version_major_var_name "QT_APPLE_CLANG_MAJOR_VERSION")
set(compiler_version_minor_var_name "QT_APPLE_CLANG_MINOR_VERSION")
@@ -603,6 +602,10 @@ QT_PATCH_VERSION = ${PROJECT_VERSION_PATCH}
list(APPEND extra_statements "QT_EDITION = Open Source")
+ if(WASM)
+ list(APPEND extra_statements
+ "QT_EMCC_VERSION = ${EMCC_VERSION}")
+ endif()
if(extra_statements)
string(REPLACE ";" "\n" extra_statements "${extra_statements}")
string(APPEND content "\n${extra_statements}\n")
diff --git a/cmake/QtWasmHelpers.cmake b/cmake/QtWasmHelpers.cmake
new file mode 100644
index 0000000000..1bbe5c928f
--- /dev/null
+++ b/cmake/QtWasmHelpers.cmake
@@ -0,0 +1,92 @@
+
+function (qt_internal_setup_wasm_target_properties wasmTarget)
+
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s EXIT_RUNTIME=1"
+ "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=1"
+ "SHELL:-s EXTRA_EXPORTED_RUNTIME_METHODS=[UTF16ToString,stringToUTF16]"
+ "SHELL:-s USE_WEBGL2=1"
+ "--bind"
+ "SHELL:-s FETCH=1")
+
+ # Hardcode wasm memory size. Emscripten does not currently support memory growth
+ # (ALLOW_MEMORY_GROWTH) in pthreads mode, and requires specifying the memory size
+ # at build time. Further, browsers limit the maximum initial memory size to 1GB.
+ # QT_WASM_INITIAL_MEMORY must be a multiple of 64KB (i.e. 65536)
+ if(NOT DEFINED QT_WASM_INITIAL_MEMORY AND QT_FEATURE_thread)
+ set(QT_WASM_INITIAL_MEMORY "1GB")
+ endif()
+
+ if(DEFINED QT_WASM_INITIAL_MEMORY)
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s INITIAL_MEMORY=${QT_WASM_INITIAL_MEMORY}")
+ message("Setting INITIAL_MEMORY to ${QT_WASM_INITIAL_MEMORY}")
+ endif()
+
+ if (QT_FEATURE_opengles3)
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s FULL_ES3=1")
+
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s FULL_ES3=1"
+ "SHELL:-s MAX_WEBGL_VERSION=2"
+ "SHELL:-s WEBGL2_BACKWARDS_COMPATIBILITY_EMULATION=1")
+ else()
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s FULL_ES2=1")
+ endif()
+
+ set(disable_exceptions_catching 1)
+ if (QT_FEATURE_exceptions)
+ set(disable_exceptions_catching 0)
+ endif()
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s DISABLE_EXCEPTION_CATCHING=${disable_exceptions_catching}")
+
+ if (QT_FEATURE_thread)
+ target_compile_options("${wasmTarget}" INTERFACE "SHELL:-s USE_PTHREADS=1")
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s USE_PTHREADS=1")
+
+ if(DEFINED QT_WASM_PTHREAD_POOL_SIZE)
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s PTHREAD_POOL_SIZE=${QT_WASM_PTHREAD_POOL_SIZE}")
+ message("Setting PTHREAD_POOL_SIZE to ${QT_WASM_PTHREAD_POOL_SIZE}")
+ endif()
+
+ else()
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s ALLOW_MEMORY_GROWTH=1")
+ endif()
+
+ # debug add_compile_options
+ if ("QT_WASM_SOURCE_MAP=1" IN_LIST QT_QMAKE_DEVICE_OPTIONS)
+ set(WASM_SOURCE_MAP_BASE "http://localhost:8000/")
+
+ if(DEFINED QT_WASM_SOURCE_MAP_BASE)
+ set(WASM_SOURCE_MAP_BASE "${QT_WASM_SOURCE_MAP_BASE}")
+ endif()
+
+ # Pass --source-map-base on the linker line. This informs the
+ # browser where to find the source files when debugging.
+ # -g4 to make source maps for debugging
+ target_link_options("${wasmTarget}" INTERFACE "-g4" "--source-map-base" "${WASM_SOURCE_MAP_BASE}")
+
+ endif()
+
+ # a few good defaults to make console more verbose while debugging
+ target_link_options("${wasmTarget}" INTERFACE $<$<CONFIG:Debug>:
+ SHELL:"-s DEMANGLE_SUPPORT=1"
+ SHELL:"-s GL_DEBUG=1"
+ SHELL:"-s ASSERTIONS=2"
+ --profiling-funcs>)
+
+ # target_link_options("${wasmTarget}" INTERFACE "SHELL:-s LIBRARY_DEBUG=1") # print out library calls, verbose
+ # target_link_options("${wasmTarget}" INTERFACE "SHELL:-s SYSCALL_DEBUG=1") # print out sys calls, verbose
+ # target_link_options("${wasmTarget}" INTERFACE "SHELL:-s FS_LOG=1") # print out filesystem ops, verbose
+ # target_link_options("${wasmTarget}" INTERFACE "SHELL:-s SOCKET_DEBUG") # print out socket,network data transfer
+
+ if ("QT_EMSCRIPTEN_ASYNCIFY=1" IN_LIST QT_QMAKE_DEVICE_OPTIONS)
+
+ # Emscripten recommends building with optimizations when using asyncify
+ # in order to reduce wasm file size, and may also generate broken wasm
+ # (with "wasm validation error: too many locals" type errors) if optimizations
+ # are omitted. Enable optimizations also for debug builds.
+ set(QT_CFLAGS_OPTIMIZE_DEBUG "-Os" CACHE STRING INTERNAL FORCE)
+ set(QT_FEATURE_optimize_debug ON CACHE BOOL INTERNAL FORCE)
+
+ target_link_options("${wasmTarget}" INTERFACE "SHELL:-s ASYNCIFY" "-Os")
+ target_compile_definitions("${wasmTarget}" INTERFACE QT_HAVE_EMSCRIPTEN_ASYNCIFY)
+ endif()
+endfunction()
diff --git a/configure.cmake b/configure.cmake
index 7d015717ed..b477499915 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -339,7 +339,7 @@ qt_feature("android-style-assets" PRIVATE
)
qt_feature("shared" PUBLIC
LABEL "Building shared libraries"
- AUTODETECT NOT UIKIT
+ AUTODETECT NOT UIKIT AND NOT WASM
CONDITION BUILD_SHARED_LIBS
)
qt_feature_definition("shared" "QT_STATIC" NEGATE PREREQUISITE "!defined(QT_SHARED) && !defined(QT_STATIC)")
@@ -600,6 +600,7 @@ qt_feature("c11" PUBLIC
qt_feature("precompile_header"
LABEL "Using precompiled headers"
CONDITION BUILD_WITH_PCH
+ AUTODETECT NOT WASM
)
qt_feature_config("precompile_header" QMAKE_PRIVATE_CONFIG)
set(__qt_ltcg_detected FALSE)
@@ -848,7 +849,7 @@ qt_feature_definition("concurrent" "QT_NO_CONCURRENT" NEGATE VALUE "1")
qt_feature("dbus" PUBLIC PRIVATE
LABEL "Qt D-Bus"
AUTODETECT NOT UIKIT AND NOT ANDROID
- CONDITION QT_FEATURE_thread
+ CONDITION QT_FEATURE_thread AND NOT WASM
)
qt_feature_definition("dbus" "QT_NO_DBUS" NEGATE VALUE "1")
qt_feature("dbus-linked" PRIVATE
@@ -877,7 +878,7 @@ qt_feature("printsupport" PRIVATE
)
qt_feature("sql" PRIVATE
LABEL "Qt Sql"
- CONDITION QT_FEATURE_thread
+ CONDITION QT_FEATURE_thread AND NOT WASM
)
qt_feature("testlib" PRIVATE
LABEL "Qt Testlib"
@@ -1050,6 +1051,7 @@ qt_configure_add_summary_entry(ARGS "pkg-config")
qt_configure_add_summary_entry(ARGS "libudev")
qt_configure_add_summary_entry(ARGS "system-zlib")
qt_configure_add_summary_entry(ARGS "zstd")
+qt_configure_add_summary_entry(ARGS "thread")
qt_configure_end_summary_section() # end of "Support enabled for" section
qt_configure_add_report_entry(
TYPE NOTE
@@ -1094,9 +1096,22 @@ qt_configure_add_report_entry(
MESSAGE "Setting a library infix is not supported for framework builds."
CONDITION QT_FEATURE_framework AND DEFINED QT_LIBINFIX
)
+qt_configure_add_report_entry(
+ TYPE NOTE
+ MESSAGE "Using pthreads"
+ CONDITION QT_FEATURE_thread
+)
+qt_configure_add_report_entry(
+ TYPE WARNING
+ MESSAGE "You should use the recommended Wasm version ${QT_EMCC_RECOMMENDED_VERSION} with this Qt. You have ${EMCC_VERSION}."
+ CONDITION WASM AND NOT ${EMCC_VERSION} MATCHES ${QT_EMCC_RECOMMENDED_VERSION}
+)
+if(WASM)
+ qt_extra_definition("QT_EMCC_VERSION" "\"${EMCC_VERSION}\"" PUBLIC)
+endif()
# special case end
-
qt_extra_definition("QT_VERSION_STR" "\"${PROJECT_VERSION}\"" PUBLIC)
qt_extra_definition("QT_VERSION_MAJOR" ${PROJECT_VERSION_MAJOR} PUBLIC)
qt_extra_definition("QT_VERSION_MINOR" ${PROJECT_VERSION_MINOR} PUBLIC)
qt_extra_definition("QT_VERSION_PATCH" ${PROJECT_VERSION_PATCH} PUBLIC)
+
diff --git a/configure.json b/configure.json
index c6790eab78..b656ad1bda 100644
--- a/configure.json
+++ b/configure.json
@@ -677,7 +677,7 @@
},
"shared": {
"label": "Building shared libraries",
- "autoDetect": "!config.uikit",
+ "autoDetect": "!config.uikit && !config.wasm",
"condition": "!config.integrity && !config.wasm && !config.rtems",
"output": [
"shared",
@@ -1010,6 +1010,7 @@
"precompile_header": {
"label": "Using precompiled headers",
"condition": "tests.precompile_header",
+ "autodetect": "!config.wasm",
"output": [
"privateConfig",
{ "type": "varRemove", "negative": true, "name": "CONFIG", "value": "'precompile_header'" }
@@ -1337,7 +1338,7 @@
"dbus": {
"label": "Qt D-Bus",
"autoDetect": "!config.uikit && !config.android",
- "condition": "features.thread",
+ "condition": "features.thread && !config.wasm",
"output": [ "privateFeature", "feature" ]
},
"dbus-linked": {
@@ -1378,7 +1379,7 @@
},
"sql": {
"label": "Qt Sql",
- "condition": "features.thread",
+ "condition": "features.thread && !config.wasm",
"output": [ "privateFeature" ]
},
"testlib": {
@@ -1512,8 +1513,9 @@
"message": "Qt requires a compliant STL library."
},
{
- "type": "emccVersion",
- "condition": "config.wasm"
+ "type": "note",
+ "condition": "features.thread",
+ "message": "Using pthreads"
},
{
"type": "error",
@@ -1673,7 +1675,8 @@
"pkg-config",
"libudev",
"system-zlib",
- "zstd"
+ "zstd",
+ "thread"
]
}
]
diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf
index 2e886fc4a5..882d2e49c8 100644
--- a/mkspecs/features/wasm/wasm.prf
+++ b/mkspecs/features/wasm/wasm.prf
@@ -13,8 +13,8 @@ exists($$QMAKE_QT_CONFIG) {
# Create worker threads at startup. This is supposed to be an optimization,
# however exceeding the pool size has been obesverved to hang the application.
POOL_SIZE = 4
- !isEmpty(QMAKE_WASM_PTHREAD_POOL_SIZE) {
- POOL_SIZE = $$QMAKE_WASM_PTHREAD_POOL_SIZE
+ !isEmpty(QT_WASM_PTHREAD_POOL_SIZE) {
+ POOL_SIZE = $$QT_WASM_PTHREAD_POOL_SIZE
}
message("Setting PTHREAD_POOL_SIZE to" $$POOL_SIZE)
@@ -23,18 +23,18 @@ exists($$QMAKE_QT_CONFIG) {
EMCC_THREAD_LFLAGS += -s ALLOW_MEMORY_GROWTH=1
}
- qtConfig(thread) | !isEmpty(QMAKE_WASM_TOTAL_MEMORY) {
+ qtConfig(thread) | !isEmpty(QT_WASM_INITIAL_MEMORY) {
# Hardcode wasm memory size. Emscripten does not currently support memory growth
# (ALLOW_MEMORY_GROWTH) in pthreads mode, and requires specifying the memory size
# at build time. Further, browsers limit the maximum initial memory size to 1GB.
- # QMAKE_WASM_TOTAL_MEMORY must be a multiple of 64KB
- TOTAL_MEMORY = 1GB
- !isEmpty(QMAKE_WASM_TOTAL_MEMORY) {
- TOTAL_MEMORY = $$QMAKE_WASM_TOTAL_MEMORY
+ # QT_WASM_INITIAL_MEMORY must be a multiple of 64KB
+ INITIAL_MEMORY = 1GB
+ !isEmpty(QT_WASM_INITIAL_MEMORY) {
+ INITIAL_MEMORY = $$QT_WASM_INITIAL_MEMORY
}
- message("Setting TOTAL_MEMORY to" $$TOTAL_MEMORY)
- EMCC_THREAD_LFLAGS += -s TOTAL_MEMORY=$$TOTAL_MEMORY
+ message("Setting INITIAL_MEMORY to" $$INITIAL_MEMORY)
+ EMCC_THREAD_LFLAGS += -s INITIAL_MEMORY=$$INITIAL_MEMORY
}
QMAKE_LFLAGS += $$EMCC_THREAD_LFLAGS
QMAKE_LFLAGS_DEBUG += $$EMCC_THREAD_LFLAGS
@@ -117,9 +117,9 @@ qtConfTest_emccVersion()
# Pass --source-map-base on the linker line. This informs the
# browser where to find the source files when debugging.
WASM_SOURCE_MAP_BASE = http://localhost:8000/
-!isEmpty(QMAKE_WASM_SOURCE_MAP_BASE):\
- WASM_SOURCE_MAP_BASE = $$QMAKE_WASM_SOURCE_MAP_BASE
-CONFIG(debug): QMAKE_LFLAGS += --source-map-base $$WASM_SOURCE_MAP_BASE
+!isEmpty(QT_WASM_SOURCE_MAP_BASE):\
+ WASM_SOURCE_MAP_BASE = $$QT_WASM_SOURCE_MAP_BASE
+CONFIG(debug): QMAKE_LFLAGS += -g4 --source-map-base $$WASM_SOURCE_MAP_BASE
# Creates the stand-alone version of the library from bitcode
!static:contains(TEMPLATE, .*lib): {
diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf
index 2b108a5e90..2788d925c4 100644
--- a/mkspecs/wasm-emscripten/qmake.conf
+++ b/mkspecs/wasm-emscripten/qmake.conf
@@ -8,11 +8,11 @@ include(../common/clang.conf)
load(device_config)
load(emcc_ver)
-# Support enabling asyncify by configuring with "-device-option EMSCRIPTEN_ASYNCIFY=1"
-!isEmpty(EMSCRIPTEN_ASYNCIFY): {
- !equals(EMSCRIPTEN_ASYNCIFY, 1):!equals(EMSCRIPTEN_ASYNCIFY, 0): \
- message(Error: The value for EMSCRIPTEN_ASYNCIFY must be 0 or 1)
- equals(EMSCRIPTEN_ASYNCIFY, 1): {
+# Support enabling asyncify by configuring with "-device-option QT_EMSCRIPTEN_ASYNCIFY=1"
+!isEmpty(QT_EMSCRIPTEN_ASYNCIFY): {
+ !equals(QT_EMSCRIPTEN_ASYNCIFY, 1):!equals(QT_EMSCRIPTEN_ASYNCIFY, 0): \
+ message(Error: The value for QT_EMSCRIPTEN_ASYNCIFY must be 0 or 1)
+ equals(QT_EMSCRIPTEN_ASYNCIFY, 1): {
QMAKE_CFLAGS += -DQT_HAVE_EMSCRIPTEN_ASYNCIFY
QMAKE_CXXFLAGS += -DQT_HAVE_EMSCRIPTEN_ASYNCIFY
QMAKE_LFLAGS += -s ASYNCIFY
@@ -56,7 +56,7 @@ EMCC_COMMON_LFLAGS_DEBUG = \
-s GL_DEBUG=1 \
--profiling-funcs
-QMAKE_LFLAGS_DEBUG += -g4
+QMAKE_LFLAGS_DEBUG += -g2
QMAKE_LFLAGS_RELEASE += -O2
QMAKE_COMPILER += emscripten
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 54b756d2a6..af6bba2dbe 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -20,6 +20,10 @@ if(ANDROID)
set(corelib_extra_cmake_files
"${CMAKE_CURRENT_SOURCE_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}AndroidMacros.cmake")
endif()
+if(WASM)
+ set(corelib_extra_cmake_files
+ "${CMAKE_CURRENT_SOURCE_DIR}/${QT_CMAKE_EXPORT_NAMESPACE}WasmMacros.cmake")
+endif()
# special case end
#####################################################################
diff --git a/src/corelib/Qt6CoreConfigExtras.cmake.in b/src/corelib/Qt6CoreConfigExtras.cmake.in
index e7892bbcc3..25b3f5acd5 100644
--- a/src/corelib/Qt6CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt6CoreConfigExtras.cmake.in
@@ -47,3 +47,7 @@ set(_Qt6CTestMacros "${_Qt6CoreConfigDir}/Qt6CTestMacros.cmake")
if(ANDROID_PLATFORM)
include("${CMAKE_CURRENT_LIST_DIR}/@QT_CMAKE_EXPORT_NAMESPACE@AndroidMacros.cmake")
endif()
+
+if(EMSCRIPTEN)
+ include("${CMAKE_CURRENT_LIST_DIR}/@QT_CMAKE_EXPORT_NAMESPACE@WasmMacros.cmake")
+endif()
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index b4ffa54578..54edcd102f 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -559,6 +559,9 @@ function(qt6_finalize_executable target)
qt6_android_generate_deployment_settings("${target}")
qt6_android_add_apk_target("${target}")
endif()
+ if(EMSCRIPTEN)
+ qt_wasm_add_target_helpers("${target}")
+ endif()
endfunction()
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
diff --git a/src/corelib/Qt6WasmMacros.cmake b/src/corelib/Qt6WasmMacros.cmake
new file mode 100644
index 0000000000..e9c19160a3
--- /dev/null
+++ b/src/corelib/Qt6WasmMacros.cmake
@@ -0,0 +1,31 @@
+
+function(qt6_wasm_add_target_helpers target)
+ # copy in Qt HTML/JS launch files for apps
+ get_target_property(targetType "${target}" TYPE)
+ if("${targetType}" STREQUAL "EXECUTABLE")
+
+ set(APPNAME ${target})
+
+ if(QT6_INSTALL_PREFIX)
+ set(WASM_BUILD_DIR "${QT6_INSTALL_PREFIX}")
+ elseif(QT_BUILD_DIR)
+ set(WASM_BUILD_DIR "${QT_BUILD_DIR}")
+ endif()
+
+ configure_file("${WASM_BUILD_DIR}/plugins/platforms/wasm_shell.html"
+ "${target}.html")
+ configure_file("${WASM_BUILD_DIR}/plugins/platforms/qtloader.js"
+ qtloader.js COPYONLY)
+ configure_file("${WASM_BUILD_DIR}/plugins/platforms/qtlogo.svg"
+ qtlogo.svg COPYONLY)
+
+ endif()
+endfunction()
+
+if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
+ function(qt_wasm_add_target_helpers)
+ if(QT_DEFAULT_MAJOR_VERSION EQUAL 6)
+ qt6_wasm_add_target_helpers(${ARGV})
+ endif()
+ endfunction()
+endif()
diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake
index 0e2482e380..449bd838b7 100644
--- a/src/gui/configure.cmake
+++ b/src/gui/configure.cmake
@@ -389,10 +389,19 @@ ioctl(fd, FBIOGET_VSCREENINFO, &vinfo);
")
# opengles3
+# special case begin
+if(WASM)
+ set(extra_compiler_options "-s FULL_ES3=1")
+endif()
+# special case end
+
qt_config_compile_test(opengles3
LABEL "OpenGL ES 3.0"
LIBRARIES
GLESv2::GLESv2
+# special case begin
+ COMPILE_OPTIONS ${extra_compiler_options}
+# special case end
CODE
"#ifdef __APPLE__
# include <OpenGLES/ES3/gl.h>
diff --git a/src/plugins/platforms/CMakeLists.txt b/src/plugins/platforms/CMakeLists.txt
index f6206942ea..8ef533ad43 100644
--- a/src/plugins/platforms/CMakeLists.txt
+++ b/src/plugins/platforms/CMakeLists.txt
@@ -47,7 +47,7 @@ if(HAIKU)
# add_subdirectory(haiku) # special case TODO
endif()
if(WASM)
- # add_subdirectory(wasm) # special case TODO
+ add_subdirectory(wasm)
endif()
if(QT_FEATURE_integrityfb)
# add_subdirectory(integrity) # special case TODO
diff --git a/src/plugins/platforms/wasm/CMakeLists.txt b/src/plugins/platforms/wasm/CMakeLists.txt
new file mode 100644
index 0000000000..10e247b7dd
--- /dev/null
+++ b/src/plugins/platforms/wasm/CMakeLists.txt
@@ -0,0 +1,78 @@
+# Generated from wasm.pro.
+
+#####################################################################
+## QWasmIntegrationPlugin Plugin:
+#####################################################################
+
+qt_internal_add_plugin(QWasmIntegrationPlugin
+ OUTPUT_NAME qwasm
+ DEFAULT_IF ${QT_QPA_DEFAULT_PLATFORM} MATCHES wasm # special case
+ TYPE platforms
+ STATIC
+ SOURCES
+ main.cpp
+ qwasmclipboard.cpp qwasmclipboard.h
+ qwasmcompositor.cpp qwasmcompositor.h
+ qwasmcursor.cpp qwasmcursor.h
+ qwasmeventdispatcher.cpp qwasmeventdispatcher.h
+ qwasmeventtranslator.cpp qwasmeventtranslator.h
+ qwasmfontdatabase.cpp qwasmfontdatabase.h
+ qwasmintegration.cpp qwasmintegration.h
+ qwasmoffscreensurface.cpp qwasmoffscreensurface.h
+ qwasmopenglcontext.cpp qwasmopenglcontext.h
+ qwasmscreen.cpp qwasmscreen.h
+ qwasmservices.cpp qwasmservices.h
+ qwasmstring.cpp qwasmstring.h
+ qwasmstylepixmaps_p.h
+ qwasmtheme.cpp qwasmtheme.h
+ qwasmwindow.cpp qwasmwindow.h
+ DEFINES
+ QT_EGL_NO_X11
+ QT_NO_FOREACH
+ PUBLIC_LIBRARIES
+ Qt::Core
+ Qt::CorePrivate
+ Qt::Gui
+ Qt::GuiPrivate
+)
+
+# Resources:
+set_source_files_properties("${QT_SOURCE_TREE}/src/3rdparty/wasm/Vera.ttf" PROPERTIES QT_RESOURCE_ALIAS "Vera.ttf")
+set_source_files_properties("${QT_SOURCE_TREE}/src/3rdparty/wasm/DejaVuSans.ttf" PROPERTIES QT_RESOURCE_ALIAS "DejaVuSans.ttf")
+set_source_files_properties("${QT_SOURCE_TREE}/src/3rdparty/wasm/DejaVuSansMono.ttf" PROPERTIES QT_RESOURCE_ALIAS "DejaVuSansMono.ttf")
+
+set(wasmfonts_resource_files
+ "${QT_SOURCE_TREE}/src/3rdparty/wasm/Vera.ttf"
+ "${QT_SOURCE_TREE}/src/3rdparty/wasm/DejaVuSans.ttf"
+ "${QT_SOURCE_TREE}/src/3rdparty/wasm/DejaVuSansMono.ttf"
+)
+
+qt_internal_add_resource(QWasmIntegrationPlugin "wasmfonts"
+ PREFIX
+ "/fonts"
+ FILES
+ ${wasmfonts_resource_files}
+)
+qt_internal_extend_target(QWasmIntegrationPlugin CONDITION QT_FEATURE_opengl
+ SOURCES
+ qwasmbackingstore.cpp qwasmbackingstore.h
+ PUBLIC_LIBRARIES
+ Qt::OpenGL
+ Qt::OpenGLPrivate
+)
+
+#### Keys ignored in scope 4:.:.:wasm.pro:NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN:
+# PLUGIN_EXTENDS = "-"
+
+qt_copy_or_install(FILES
+ wasm_shell.html
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/plugins/platforms/"
+)
+qt_copy_or_install(FILES
+ qtloader.js
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/plugins/platforms/"
+)
+qt_copy_or_install(FILES
+ qtlogo.svg
+ DESTINATION "${CMAKE_INSTALL_PREFIX}/plugins/platforms/"
+)