Skip to content

Commit

Permalink
Support for the new Wasm EH proposal with exnref
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kleisauke committed Oct 19, 2024
1 parent 1de6d9e commit 23ba439
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
47 changes: 32 additions & 15 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 ;;
Expand Down Expand Up @@ -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"
Expand All @@ -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)"
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
)
Expand All @@ -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
)
Expand All @@ -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
)
Expand All @@ -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
Expand All @@ -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 \
Expand All @@ -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
)
Expand All @@ -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
)
Expand All @@ -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
)
Expand Down Expand Up @@ -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 \
Expand All @@ -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__" \
Expand All @@ -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} \
Expand All @@ -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
)
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions build/node-wasm-exnref.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[constants]
node_flags = ['--experimental-wasm-exnref']

0 comments on commit 23ba439

Please sign in to comment.