From 23ba439a2632ba5542e18ad162dc42465d9f44d8 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Sat, 19 Oct 2024 15:04:08 +0200 Subject: [PATCH] Support for the new Wasm EH proposal with exnref Requires Emscripten 3.1.60 or later and an engine that supports the new Wasm EH proposal. This requires the `--experimental-wasm-exnref` feature flag on Node.js. --- build.sh | 47 +++++++++++++------ ...n-crossfile.meson => emscripten-cross.ini} | 5 +- build/node-wasm-exnref.ini | 2 + 3 files changed, 38 insertions(+), 16 deletions(-) rename build/{emscripten-crossfile.meson => emscripten-cross.ini} (84%) create mode 100644 build/node-wasm-exnref.ini diff --git a/build.sh b/build.sh index cec23fe70..b0a2aaddb 100755 --- a/build.sh +++ b/build.sh @@ -39,6 +39,11 @@ WASM_FS=false # https://github.com/WebAssembly/exception-handling WASM_EH=false +# Emit instructions for the new Wasm EH proposal with exnref +# (adopted on Oct 2023), disabled by default +# https://github.com/WebAssembly/exception-handling/issues/280 +WASM_EXNREF=false + # Link-time optimizations (LTO), disabled by default # https://github.com/emscripten-core/emscripten/issues/10603 LTO=false @@ -71,6 +76,10 @@ while [ $# -gt 0 ]; do --enable-lto) LTO=true ;; --enable-wasm-fs) WASM_FS=true ;; --enable-wasm-eh) WASM_EH=true ;; + --enable-new-wasm-eh) + WASM_EH=true + WASM_EXNREF=true + ;; --disable-simd) SIMD=false ;; --disable-wasm-bigint) WASM_BIGINT=false ;; --disable-jxl) JXL=false ;; @@ -136,6 +145,7 @@ export CXXFLAGS="$CFLAGS" export LDFLAGS="$COMMON_FLAGS -L$TARGET/lib -sAUTO_JS_LIBRARIES=0 -sAUTO_NATIVE_LIBRARIES=0" if [ "$WASM_BIGINT" = "true" ]; then export LDFLAGS+=" -sWASM_BIGINT"; fi +if [ "$WASM_EXNREF" = "true" ]; then export LDFLAGS+=" -sWASM_EXNREF"; fi # Build paths export CPATH="$TARGET/include" @@ -144,7 +154,14 @@ export EM_PKG_CONFIG_PATH="$PKG_CONFIG_PATH" # Specific variables for cross-compilation export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten -export MESON_CROSS="$SOURCE_DIR/build/emscripten-crossfile.meson" +export CMAKE_ARGS="" +export MESON_ARGS="--cross-file=$SOURCE_DIR/build/emscripten-cross.ini" +if [ "$WASM_EXNREF" = "true" ]; then + # Requires Node >= 22 + # https://github.com/nodejs/node/pull/51362 + export CMAKE_ARGS+=" -DCMAKE_CROSSCOMPILING_EMULATOR=node;--experimental-wasm-exnref" + export MESON_ARGS+=" --cross-file=$SOURCE_DIR/build/node-wasm-exnref.ini" +fi # Run as many parallel jobs as there are available CPU cores export MAKEFLAGS="-j$(nproc)" @@ -239,7 +256,7 @@ node --version cd $DEPS/zlib-ng # SSE intrinsics needs to be checked for wasm32 sed -i 's/BASEARCH_X86_FOUND/& OR BASEARCH_WASM32_FOUND/g' CMakeLists.txt - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBUILD_SHARED_LIBS=FALSE \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS -DBUILD_SHARED_LIBS=FALSE \ ${DISABLE_SIMD:+-DWITH_OPTIM=FALSE} ${ENABLE_SIMD:+-DFORCE_SSE2=TRUE} -DWITH_RUNTIME_CPU_DETECTION=FALSE -DZLIB_COMPAT=TRUE \ -DZLIB_ENABLE_TESTS=FALSE -DZLIBNG_ENABLE_TESTS=FALSE -DWITH_GTEST=FALSE make -C _build install @@ -266,7 +283,7 @@ node --version cd $DEPS/glib # TODO(kleisauke): Discuss these patches upstream curl -Ls https://github.com/GNOME/glib/compare/$VERSION_GLIB...kleisauke:wasm-vips-$VERSION_GLIB.patch | patch -p1 - meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ + meson setup _build --prefix=$TARGET $MESON_ARGS --default-library=static --buildtype=release \ --force-fallback-for=gvdb -Dintrospection=disabled -Dselinux=disabled -Dxattr=false -Dlibmount=disabled -Dsysprof=disabled -Dnls=disabled \ -Dtests=false -Dglib_assert=false -Dglib_checks=false meson install -C _build --tag devel @@ -297,7 +314,7 @@ node --version mkdir $DEPS/lcms2 curl -Ls https://github.com/mm2/Little-CMS/releases/download/lcms$VERSION_LCMS2/lcms2-$VERSION_LCMS2.tar.gz | tar xzC $DEPS/lcms2 --strip-components=1 cd $DEPS/lcms2 - meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ + meson setup _build --prefix=$TARGET $MESON_ARGS --default-library=static --buildtype=release \ -Djpeg=disabled -Dtiff=disabled meson install -C _build --tag devel ) @@ -309,7 +326,7 @@ node --version cd $DEPS/hwy # Remove build path from binary sed -i 's/HWY_ASSERT/HWY_DASSERT/' hwy/aligned_allocator.cc - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBUILD_SHARED_LIBS=FALSE \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS -DBUILD_SHARED_LIBS=FALSE \ -DBUILD_TESTING=FALSE -DHWY_ENABLE_CONTRIB=FALSE -DHWY_ENABLE_EXAMPLES=FALSE -DHWY_ENABLE_TESTS=FALSE make -C _build install ) @@ -320,7 +337,7 @@ node --version curl -Ls https://github.com/google/brotli/archive/refs/tags/v$VERSION_BROTLI.tar.gz | tar xzC $DEPS/brotli --strip-components=1 cd $DEPS/brotli # Exclude internal dictionary, see: https://github.com/emscripten-core/emscripten/issues/9960 - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DBROTLI_DISABLE_TESTS=TRUE \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS -DBROTLI_DISABLE_TESTS=TRUE \ -DCMAKE_C_FLAGS="$CFLAGS -DBROTLI_EXTERNAL_DICTIONARY_DATA" make -C _build install ) @@ -334,7 +351,7 @@ node --version curl -Ls https://github.com/kleisauke/libjpeg-turbo/commit/a60fb467fc7601b008741d42e98268c8a7bcb5b4.patch | patch -p1 # Compile without SIMD support, see: https://github.com/libjpeg-turbo/libjpeg-turbo/issues/250 # Disable environment variables usage, see: https://github.com/libjpeg-turbo/libjpeg-turbo/issues/600 - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DENABLE_STATIC=TRUE \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS -DENABLE_STATIC=TRUE \ -DENABLE_SHARED=FALSE -DWITH_JPEG8=TRUE -DWITH_SIMD=FALSE -DWITH_TURBOJPEG=FALSE -DPNG_SUPPORTED=FALSE \ -DCMAKE_C_FLAGS="$CFLAGS -DNO_GETENV -DNO_PUTENV" make -C _build install @@ -345,7 +362,7 @@ node --version mkdir $DEPS/jxl curl -Ls https://github.com/libjxl/libjxl/archive/refs/tags/v$VERSION_JXL.tar.gz | tar xzC $DEPS/jxl --strip-components=1 cd $DEPS/jxl - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DCMAKE_FIND_ROOT_PATH=$TARGET \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH=$TARGET \ -DBUILD_SHARED_LIBS=FALSE -DBUILD_TESTING=FALSE -DJPEGXL_ENABLE_TOOLS=FALSE -DJPEGXL_ENABLE_JPEGLI=FALSE \ -DJPEGXL_ENABLE_EXAMPLES=FALSE -DJPEGXL_ENABLE_SJPEG=FALSE -DJPEGXL_ENABLE_SKCMS=FALSE -DJPEGXL_BUNDLE_LIBPNG=FALSE \ -DJPEGXL_FORCE_SYSTEM_BROTLI=TRUE -DJPEGXL_FORCE_SYSTEM_LCMS2=TRUE -DJPEGXL_FORCE_SYSTEM_HWY=TRUE \ @@ -371,7 +388,7 @@ node --version curl -Ls https://github.com/randy408/libspng/compare/v$VERSION_SPNG...kleisauke:wasm-vips.patch | patch -p1 # Switch the default zlib compression strategy to Z_RLE, as this is especially suitable for PNG images sed -i 's/Z_FILTERED/Z_RLE/g' spng/spng.c - meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ + meson setup _build --prefix=$TARGET $MESON_ARGS --default-library=static --buildtype=release \ -Dbuild_examples=false -Dstatic_zlib=true ${DISABLE_SIMD:+-Denable_opt=false} ${ENABLE_SIMD:+-Dc_args="$CFLAGS -msse4.1 -DSPNG_SSE=4"} meson install -C _build --tag devel ) @@ -381,7 +398,7 @@ node --version mkdir $DEPS/imagequant curl -Ls https://github.com/lovell/libimagequant/archive/refs/tags/v$VERSION_IMAGEQUANT.tar.gz | tar xzC $DEPS/imagequant --strip-components=1 cd $DEPS/imagequant - meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ + meson setup _build --prefix=$TARGET $MESON_ARGS --default-library=static --buildtype=release \ ${ENABLE_SIMD:+-Dc_args="$CFLAGS -msse -DUSE_SSE=1"} meson install -C _build --tag devel ) @@ -391,7 +408,7 @@ node --version mkdir $DEPS/cgif curl -Ls https://github.com/dloebl/cgif/archive/refs/tags/v$VERSION_CGIF.tar.gz | tar xzC $DEPS/cgif --strip-components=1 cd $DEPS/cgif - meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ + meson setup _build --prefix=$TARGET $MESON_ARGS --default-library=static --buildtype=release \ -Dtests=false meson install -C _build --tag devel ) @@ -452,7 +469,7 @@ EOL mkdir $DEPS/aom curl -Ls https://storage.googleapis.com/aom-releases/libaom-$VERSION_AOM.tar.gz | tar xzC $DEPS/aom --strip-components=1 cd $DEPS/aom - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS \ -DAOM_TARGET_CPU=generic ${ENABLE_PIC:+-DCONFIG_PIC=1} -DCONFIG_RUNTIME_CPU_DETECT=0 \ -DENABLE_DOCS=FALSE -DENABLE_TESTS=FALSE -DENABLE_EXAMPLES=FALSE -DENABLE_TOOLS=FALSE \ -DCONFIG_WEBM_IO=0 -DCONFIG_AV1_HIGHBITDEPTH=0 \ @@ -467,7 +484,7 @@ EOL cd $DEPS/heif # Note: without CMAKE_FIND_ROOT_PATH find_path for AOM is not working for some reason (see https://github.com/emscripten-core/emscripten/issues/10078). # Compile with -D__EMSCRIPTEN_STANDALONE_WASM__ to disable the Embind implementation. - emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET -DCMAKE_FIND_ROOT_PATH=$TARGET \ + emcmake cmake -B_build -H. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TARGET $CMAKE_ARGS -DCMAKE_FIND_ROOT_PATH=$TARGET \ -DBUILD_SHARED_LIBS=FALSE -DCMAKE_POSITION_INDEPENDENT_CODE=$PIC -DENABLE_PLUGIN_LOADING=FALSE \ -DBUILD_TESTING=FALSE -DWITH_EXAMPLES=FALSE -DWITH_LIBDE265=FALSE -DWITH_X265=FALSE \ -DCMAKE_CXX_FLAGS="$CXXFLAGS -D__EMSCRIPTEN_STANDALONE_WASM__" \ @@ -491,7 +508,7 @@ EOL curl -Ls https://github.com/libvips/libvips/compare/v$VERSION_VIPS...kleisauke:wasm-vips-8.16.patch | patch -p1 # Disable building man pages, gettext po files, tools, and (fuzz-)tests sed -i "/subdir('man')/{N;N;N;N;d;}" meson.build - meson setup _build --prefix=$TARGET --cross-file=$MESON_CROSS --default-library=static --buildtype=release \ + meson setup _build --prefix=$TARGET $MESON_ARGS --default-library=static --buildtype=release \ -Ddeprecated=false -Dexamples=false -Dcplusplus=$LIBVIPS_CPP -Dauto_features=disabled \ ${DISABLE_MODULES:+-Dmodules=disabled} -Dcgif=enabled -Dexif=enabled ${ENABLE_AVIF:+-Dheif=enabled} \ -Dheif-module=enabled -Dimagequant=enabled -Djpeg=enabled ${ENABLE_JXL:+-Djpeg-xl=enabled} \ @@ -509,7 +526,7 @@ EOL stage "Compiling JS bindings" mkdir $DEPS/wasm-vips cd $DEPS/wasm-vips - emcmake cmake $SOURCE_DIR -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY="$SOURCE_DIR/lib" \ + emcmake cmake $SOURCE_DIR -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY="$SOURCE_DIR/lib" $CMAKE_ARGS \ -DENVIRONMENT=${ENVIRONMENT//,/;} -DENABLE_MODULES=$MODULES -DENABLE_WASMFS=$WASM_FS make ) diff --git a/build/emscripten-crossfile.meson b/build/emscripten-cross.ini similarity index 84% rename from build/emscripten-crossfile.meson rename to build/emscripten-cross.ini index 2ce67970d..df1d9ee13 100644 --- a/build/emscripten-crossfile.meson +++ b/build/emscripten-cross.ini @@ -1,10 +1,13 @@ +[constants] +node_flags = [] + [binaries] c = 'emcc' cpp = 'em++' ar = 'emar' ranlib = 'emranlib' pkg-config = ['pkg-config', '--static'] -exe_wrapper = 'node' +exe_wrapper = ['node'] + node_flags [properties] needs_exe_wrapper = true diff --git a/build/node-wasm-exnref.ini b/build/node-wasm-exnref.ini new file mode 100644 index 000000000..9db5acdc3 --- /dev/null +++ b/build/node-wasm-exnref.ini @@ -0,0 +1,2 @@ +[constants] +node_flags = ['--experimental-wasm-exnref']