#!/usr/bin/env bash # Builds the wasm32 static-library dependency set vpinball needs: # SDL3, SDL3_image, SDL3_ttf (+freetype), FreeImage, libwinevbs. # # Modeled on vendor/vpinball/platforms/linux-x64/external.sh's own build # sections, with `cmake` swapped for `emcmake cmake` and shared libs swapped # for static (a single wasm binary has no runtime dynamic loader). Codec/font # backends are scoped down from vpinball's native default to what's realistic # for browser-loaded .vpx textures (PNG/JPEG/BMP/etc. via SDL3_image's # built-in decoders + stb, no libpng/libjpeg/libwebp/libtiff/libjxl/libavif # needed at all; SDL3_ttf uses vendored freetype only, no harfbuzz/plutosvg) # - this avoids pulling in several hundred MB of vendored codec submodules # (AV1/AVIF in particular) that real VPX tables don't exercise. # # Requires: scripts/setup.sh has already run (vendor/ populated+patched, # emsdk installed). set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" source "$ROOT_DIR/scripts/versions.sh" VENDOR_DIR="$ROOT_DIR/vendor" DEPS_DIR="$ROOT_DIR/build/deps-wasm32" WORK_DIR="$ROOT_DIR/build/deps-src" NUM_PROCS="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)" if [ ! -d "$VENDOR_DIR/vpinball" ] || [ ! -d "$VENDOR_DIR/libwinevbs" ]; then echo "ERROR: vendor/ not populated. Run scripts/setup.sh first." >&2 exit 1 fi if ! command -v emcc >/dev/null 2>&1; then echo "ERROR: emcc not on PATH. Run: source $ROOT_DIR/emsdk/emsdk_env.sh" >&2 exit 1 fi mkdir -p "$DEPS_DIR/lib" "$DEPS_DIR/include" "$WORK_DIR" cache_check() { [ "$(cat "$1/.cache-sha" 2>/dev/null || true)" = "$2" ]; } # --- SDL3 core ------------------------------------------------------------- if ! cache_check "$WORK_DIR/SDL3/SDL" "$SDL_SHA"; then echo "== Building SDL3 core for wasm32 ==" rm -rf "$WORK_DIR/SDL3/SDL" mkdir -p "$WORK_DIR/SDL3" cd "$WORK_DIR/SDL3" curl -sL "https://github.com/libsdl-org/SDL/archive/${SDL_SHA}.tar.gz" | tar xz mv "SDL-${SDL_SHA}" SDL ( cd SDL && emcmake cmake -DSDL_SHARED=OFF -DSDL_STATIC=ON -DSDL_TEST_LIBRARY=OFF \ -DCMAKE_BUILD_TYPE=Release -B build && cmake --build build -- -j"$NUM_PROCS" ) echo "$SDL_SHA" > "$WORK_DIR/SDL3/SDL/.cache-sha" cd "$ROOT_DIR" fi # --- SDL3_image (built-in decoders + stb only, no vendored codec libs) ---- if ! cache_check "$WORK_DIR/SDL3/SDL_image" "$SDL_IMAGE_SHA"; then echo "== Building SDL3_image for wasm32 ==" rm -rf "$WORK_DIR/SDL3/SDL_image" cd "$WORK_DIR/SDL3" curl -sL "https://github.com/libsdl-org/SDL_image/archive/${SDL_IMAGE_SHA}.tar.gz" | tar xz mv "SDL_image-${SDL_IMAGE_SHA}" SDL_image ( cd SDL_image && emcmake cmake \ -DBUILD_SHARED_LIBS=OFF -DSDLIMAGE_SAMPLES=OFF -DSDLIMAGE_VENDORED=OFF \ -DSDLIMAGE_AVIF=OFF -DSDLIMAGE_WEBP=OFF -DSDLIMAGE_JXL=OFF -DSDLIMAGE_TIF=OFF \ -DSDLIMAGE_PNG_LIBPNG=OFF \ -DSDL3_DIR=../SDL/build -DCMAKE_BUILD_TYPE=Release -B build \ && cmake --build build -- -j"$NUM_PROCS" ) echo "$SDL_IMAGE_SHA" > "$WORK_DIR/SDL3/SDL_image/.cache-sha" cd "$ROOT_DIR" fi # --- SDL3_ttf (vendored freetype only, no harfbuzz/plutosvg) -------------- if ! cache_check "$WORK_DIR/SDL3/SDL_ttf" "$SDL_TTF_SHA"; then echo "== Building SDL3_ttf for wasm32 ==" rm -rf "$WORK_DIR/SDL3/SDL_ttf" cd "$WORK_DIR/SDL3" curl -sL "https://github.com/libsdl-org/SDL_ttf/archive/${SDL_TTF_SHA}.tar.gz" | tar xz mv "SDL_ttf-${SDL_TTF_SHA}" SDL_ttf ( cd SDL_ttf && git clone --filter=blob:none --depth 1 \ https://github.com/libsdl-org/freetype.git external/freetype \ && emcmake cmake \ -DBUILD_SHARED_LIBS=OFF -DSDLTTF_SAMPLES=OFF -DSDLTTF_VENDORED=ON \ -DSDLTTF_HARFBUZZ=OFF -DSDLTTF_PLUTOSVG=OFF \ -DSDL3_DIR=../SDL/build -DCMAKE_BUILD_TYPE=Release -B build \ && cmake --build build -- -j"$NUM_PROCS" ) echo "$SDL_TTF_SHA" > "$WORK_DIR/SDL3/SDL_ttf/.cache-sha" cd "$ROOT_DIR" fi cp "$WORK_DIR"/SDL3/SDL/build/libSDL3.a "$DEPS_DIR/lib/" cp "$WORK_DIR"/SDL3/SDL_image/build/libSDL3_image.a "$DEPS_DIR/lib/" cp "$WORK_DIR"/SDL3/SDL_ttf/build/libSDL3_ttf.a "$DEPS_DIR/lib/" cp "$WORK_DIR"/SDL3/SDL_ttf/build/external/freetype/libfreetype.a "$DEPS_DIR/lib/" cp -r "$WORK_DIR/SDL3/SDL/include/SDL3" "$DEPS_DIR/include/" cp -r "$WORK_DIR/SDL3/SDL_image/include/SDL3_image" "$DEPS_DIR/include/" cp -r "$WORK_DIR/SDL3/SDL_ttf/include/SDL3_ttf" "$DEPS_DIR/include/" # --- FreeImage (bundles all its codecs as vendored source, no submodules) - if ! cache_check "$WORK_DIR/freeimage" "$FREEIMAGE_SHA"; then echo "== Building FreeImage for wasm32 ==" rm -rf "$WORK_DIR/freeimage" mkdir -p "$WORK_DIR/freeimage" cd "$WORK_DIR/freeimage" curl -sL "https://github.com/toxieainc/freeimage/archive/${FREEIMAGE_SHA}.tar.gz" | tar xz mv "freeimage-${FREEIMAGE_SHA}" freeimage # PLATFORM/ARCH here are freeimage's own bookkeeping vars (like # libwinevbs's), not a toolchain gate - emcmake supplies the real wasm32 # toolchain, so any placeholder PLATFORM value that isn't specially # branched on (macos/ios/tvos/android) works unmodified. ( cd freeimage && emcmake cmake -DPLATFORM=linux -DARCH=wasm32 -DBUILD_STATIC=ON \ -DBUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -B build && cmake --build build -- -j"$NUM_PROCS" ) echo "$FREEIMAGE_SHA" > "$WORK_DIR/freeimage/.cache-sha" cd "$ROOT_DIR" fi cp "$WORK_DIR"/freeimage/freeimage/build/libfreeimage.a "$DEPS_DIR/lib/" cp "$WORK_DIR/freeimage/freeimage/Source/FreeImage.h" "$DEPS_DIR/include/" # --- libwinevbs (its own CMakeLists.txt needs no patch beyond the winnt.h -- # --- CONTEXT stub already applied by setup.sh; PLATFORM/ARCH are likewise -- # --- just its own bookkeeping, same as FreeImage above) -------------------- if ! cache_check "$VENDOR_DIR/libwinevbs" "built-${LIBWINEVBS_SHA}"; then echo "== Building libwinevbs for wasm32 ==" ( cd "$VENDOR_DIR/libwinevbs" && emcmake cmake -DPLATFORM=emscripten -DARCH=wasm32 \ -DBUILD_STATIC=ON -DBUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release -B build \ && cmake --build build -- -j"$NUM_PROCS" ) echo "built-${LIBWINEVBS_SHA}" > "$VENDOR_DIR/libwinevbs/.cache-sha" fi cp "$VENDOR_DIR"/libwinevbs/build/libwinevbs.a "$DEPS_DIR/lib/" mkdir -p "$DEPS_DIR/include/libwinevbs/wine/include" "$DEPS_DIR/include/libwinevbs/atl/include" "$DEPS_DIR/include/libwinevbs/atlmfc/include" cp "$VENDOR_DIR/libwinevbs/include/libwinevbs.h" "$DEPS_DIR/include/libwinevbs/" cp -r "$VENDOR_DIR/libwinevbs/wine/include/"* "$DEPS_DIR/include/libwinevbs/wine/include/" cp -r "$VENDOR_DIR/libwinevbs/atl/include/"* "$DEPS_DIR/include/libwinevbs/atl/include/" cp -r "$VENDOR_DIR/libwinevbs/atlmfc/include/"* "$DEPS_DIR/include/libwinevbs/atlmfc/include/" echo "" echo "== build-deps.sh complete: $DEPS_DIR ==" ls -la "$DEPS_DIR/lib"