From 11280e18d3778e20683c61ff07d285dae0bdcd71 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 9 Jun 2026 05:14:36 +0000 Subject: [PATCH] small writeup of wasm --- .ci/wasm/build.sh | 15 ++++++++++++--- .patch/openssl-cmake/0005-wasm-support.patch | 4 ++-- .patch/openssl/0002-wasm-support.patch | 10 +++++----- docs/Caveats.md | 13 +++++++++++++ docs/Deps.md | 8 ++++++++ 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/.ci/wasm/build.sh b/.ci/wasm/build.sh index 27ae9cc218..49c1123db6 100644 --- a/.ci/wasm/build.sh +++ b/.ci/wasm/build.sh @@ -54,6 +54,15 @@ done : "${DEVEL:=true}" : "${OUTDIR:=build}" +# -sMEMORY64 must be specified twice, see below +# The CMake toolchain file will match against MEMORY64 but will fail to match if: +# - it's either -sMEMORY64 +# - or it's either -sMEMORY64=1 +# The line in question: +# if (CMAKE_C_FLAGS MATCHES "MEMORY64") +# However why need to specify -sMEMORY64=1 then? Oh that's because if you didn't set +# the =1, it would assume you meant =0, which equates to not specifying it at all +# This seems to be fixed in later versions but occurs atleast on 4.0.3-git and below. emcmake cmake -B "$OUTDIR" -G "Unix Makefiles" \ -DCMAKE_BUILD_TYPE=${TYPE} \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ @@ -75,8 +84,8 @@ emcmake cmake -B "$OUTDIR" -G "Unix Makefiles" \ -DEMSCRIPTEN_SYSTEM_PROCESSOR=wasm \ -DCMAKE_C_FLAGS="-s MEMORY64 -m64 -pipe -sMEMORY64=1" \ -DCMAKE_CXX_FLAGS="-s MEMORY64 -m64 -pipe -sMEMORY64=1" \ - -DCMAKE_EXE_LINKER_FLAGS="-sMEMORY64=1 -m64 -Wl,-mwasm64 -sASYNCIFY=1" \ - -DCMAKE_C_LINK_FLAGS="-sMEMORY64=1 -m64 -Wl,-mwasm64 -sASYNCIFY=1" \ - -DCMAKE_CXX_LINK_FLAGS="-sMEMORY64=1 -m64 -Wl,-mwasm64 -sASYNCIFY=1" \ + -DCMAKE_EXE_LINKER_FLAGS="-sMEMORY64=1 -m64 -Wl,-mwasm64 -sASYNCIFY=1 -pthread" \ + -DCMAKE_C_LINK_FLAGS="-sMEMORY64=1 -m64 -Wl,-mwasm64 -sASYNCIFY=1 -pthread" \ + -DCMAKE_CXX_LINK_FLAGS="-sMEMORY64=1 -m64 -Wl,-mwasm64 -sASYNCIFY=1 -pthread" \ cmake --build "$OUTDIR" -- -j$NUM_JOBS diff --git a/.patch/openssl-cmake/0005-wasm-support.patch b/.patch/openssl-cmake/0005-wasm-support.patch index 35746a3f4b..31eafac9ad 100644 --- a/.patch/openssl-cmake/0005-wasm-support.patch +++ b/.patch/openssl-cmake/0005-wasm-support.patch @@ -1,5 +1,5 @@ diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake -index 3012e05..eda6cfb 100644 +index 3012e05..2ae23ff 100644 --- a/cmake/ConfigureOpenSSL.cmake +++ b/cmake/ConfigureOpenSSL.cmake @@ -108,7 +108,8 @@ function(configure_openssl) @@ -31,7 +31,7 @@ index 3012e05..eda6cfb 100644 + COMMAND ${EMSCRIPTEN_CMAKE_WRAPPER} ${CMAKE_COMMAND} -E env "CFLAGS=${CMAKE_C_FLAGS}" "CXXFLAGS=${CMAKE_CXX_FLAGS}" -+ "LDFLAGS=${CMAKE_CXX_LINKER_FLAGS}" ++ "LDFLAGS=${CMAKE_CXX_LINK_FLAGS}" + "CC=${CMAKE_C_COMPILER}" + "CXX=${CMAKE_CXX_COMPILER}" + "LD=${EMSCRIPTEN_LINKER}" diff --git a/.patch/openssl/0002-wasm-support.patch b/.patch/openssl/0002-wasm-support.patch index 4cf7204549..4eecec60f1 100644 --- a/.patch/openssl/0002-wasm-support.patch +++ b/.patch/openssl/0002-wasm-support.patch @@ -1,5 +1,5 @@ diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf -index e62721e..6fcea0d 100644 +index e62721e..243feb4 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -1970,6 +1970,26 @@ my %targets = ( @@ -10,8 +10,8 @@ index e62721e..6fcea0d 100644 + inherit_from => [ "BASE_unix" ], + CC => "emcc", + CXX => "emc++", -+ cflags => add("--target=wasm32-unknown-emscripten"), -+ cxxflags => add("--target=wasm32-unknown-emscripten"), ++ cflags => combine("--target=wasm32-unknown-emscripten", threads("-pthread")), ++ cxxflags => combine("--target=wasm32-unknown-emscripten", threads("-pthread")), + lib_cppflags => add("-DL_ENDIAN"), + bn_ops => "THIRTY_TWO_BIT", + }, @@ -19,8 +19,8 @@ index e62721e..6fcea0d 100644 + inherit_from => [ "BASE_unix" ], + CC => "emcc", + CXX => "emc++", -+ cflags => add("--target=wasm64-unknown-emscripten"), -+ cxxflags => add("--target=wasm64-unknown-emscripten"), ++ cflags => combine("--target=wasm64-unknown-emscripten", threads("-pthread")), ++ cxxflags => combine("--target=wasm64-unknown-emscripten", threads("-pthread")), + lib_cppflags => add("-DL_ENDIAN"), + bn_ops => "SIXTY_FOUR_BIT_LONG", + }, diff --git a/docs/Caveats.md b/docs/Caveats.md index c5b925f4cd..144ef2fd75 100644 --- a/docs/Caveats.md +++ b/docs/Caveats.md @@ -12,6 +12,7 @@ - [NetBSD](#netbsd) - [MSYS2](#msys2) - [RedoxOS](#redoxos) +- [WebAssembly](#webassembly) - [Windows](#windows) - [Windows 7, Windows 8 and Windows 8.1](#windows-7-windows-8-and-windows-81) - [Windows Vista and below](#windows-vista-and-below) @@ -245,6 +246,18 @@ The package install may randomly hang at times, in which case it has to be resta When CMake invokes certain file syscalls - it may sometimes cause crashes or corruptions on the (kernel?) address space - so reboot the system if there is a "hang" in CMake. +## WebAssembly + +**It doesn't run on a browser yet.** + +WebAssembly or "WASM" for short is a *mainly 32-bit* virtual "architecture" which we only bootstrap on 64-bit only. This means not only the program runs 2x slower than it would due to using JS BigInt, it also means we need to go out of our way to enable proper 64-bit support via `-sMEMORY64=1`, however once again, some Emscripten quirks force us to specify `-s MEMORY64` and `-sMEMORY64=1` at the same time: see the [CI build script](../.ci/wasm/build.sh). + +The WebAssembly target is very heavy on resources and requires at least 4 times the normal amount of resources that a native build would. Additionally, the only supported environment is `node.js` and `wasmtime`, with browser support being an afterthought (PRs welcome!). + +To run the binary (after building) you should be fine with `node ./eden-cli.js`. For obvious reasons no Qt frontend is available on WASM, support for Vulkan is done charily via [llvmpipe2wasm](https://github.com/Devsh-Graphics-Programming/llvmpipe2wasm). + +2026-06-09: As of writing, no Dynarmic-based JIT is possible on this target, full interpreted emulation is the only reasonable option. While there is some efforts on making a JIT like [here](https://github.com/wingo/wasm-jit) or [here](https://wingolog.org/archives/2022/08/18/just-in-time-code-generation-within-webassembly), the result is so latency expensive we're better off using an interpreter instead. + ## Windows ### Windows 7, Windows 8 and Windows 8.1 diff --git a/docs/Deps.md b/docs/Deps.md index 612e423d9f..f4a582e684 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -359,6 +359,14 @@ pkgman install git cmake patch libfmt_devel nlohmann_json lz4_devel opus_devel b [Caveats](./Caveats.md#haikuos). + +
+WebAssembly + +Emscripten: The default installation should provide enough. + +[Caveats](./Caveats.md#wasm). +
RedoxOS