From d557b21eacae1b486c81a160ea0f2e5dafef6c84 Mon Sep 17 00:00:00 2001 From: Viktor Vaczi Date: Thu, 19 Mar 2026 12:44:26 +0100 Subject: [PATCH] fix(docker): Replace emsdk image with Ubuntu + emsdk from source The Docker build used emscripten/emsdk:4.0.2-arm64 as base image but env.sh couldn't find emsdk there, installing a second copy. The build then applied wasm-opt/finalize stubs to the wrong emsdk (hardcoded /emsdk/), so the real wasm-emscripten-finalize ran in Docker and got OOM-killed. - Use ubuntu:22.04 base with emsdk installed from source at /emsdk/ - Make stub paths dynamic via $EMSDK instead of hardcoded /emsdk/ - Skip local emsdk install in env.sh when $EMSDK is already active Co-Authored-By: Claude Opus 4.6 (1M context) --- docker/Dockerfile | 15 +++++++++++++-- scripts/common/env.sh | 28 ++++++++++++++++++---------- scripts/kicad/build-pcbnew.sh | 8 ++++++-- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index fc69fca..1cd7a4d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,7 @@ -# Use ARM64-native image for Apple Silicon (M1/M2/M3/M4) -FROM emscripten/emsdk:4.0.2-arm64 +# Plain Ubuntu base — multi-arch (ARM64/x86_64 auto-detected) +FROM ubuntu:22.04 + +ENV DEBIAN_FRONTEND=noninteractive # Install build tools required for KiCad WASM build RUN apt-get update && apt-get install -y \ @@ -19,8 +21,17 @@ RUN apt-get update && apt-get install -y \ unixodbc-dev \ ccache \ rsync \ + xz-utils \ && rm -rf /var/lib/apt/lists/* +# Install emsdk from source (same approach as scripts/setup-emsdk.sh) +# EMSCRIPTEN_VERSION must match scripts/common/versions.sh +ARG EMSCRIPTEN_VERSION=4.0.2 +RUN git clone https://github.com/emscripten-core/emsdk.git /emsdk \ + && cd /emsdk \ + && ./emsdk install ${EMSCRIPTEN_VERSION} \ + && ./emsdk activate ${EMSCRIPTEN_VERSION} + # Configure ccache for Emscripten # CCACHE_DIR in named volume persists across containers ENV CCACHE_DIR=/workspace/build-wasm/.ccache diff --git a/scripts/common/env.sh b/scripts/common/env.sh index 7916a74..90fb61a 100755 --- a/scripts/common/env.sh +++ b/scripts/common/env.sh @@ -36,18 +36,26 @@ export WX_BUILD="$BUILD_ROOT/wxwidgets-universal" # Emscripten settings export EMSDK_QUIET=1 -# Local emsdk: auto-install if missing, then source its environment -# The emsdk bundles its own Python, Node, and LLVM — no Homebrew needed -_EMSDK_DIR="$_KICAD_WASM_PROJECT_ROOT/tools/emsdk" -_EMSDK_ENV="$_EMSDK_DIR/emsdk_env.sh" +# Emscripten SDK setup +# If EMSDK is already set (e.g. Docker entrypoint sourced emsdk_env.sh), use it. +# Otherwise auto-install a local copy under tools/emsdk/. +if [ -n "$EMSDK" ] && [ -f "$EMSDK/emsdk_env.sh" ]; then + # emsdk already active (e.g., Docker entrypoint sourced it) + source "$EMSDK/emsdk_env.sh" 2>/dev/null +else + # Local emsdk: auto-install if missing, then source its environment + # The emsdk bundles its own Python, Node, and LLVM — no Homebrew needed + _EMSDK_DIR="$_KICAD_WASM_PROJECT_ROOT/tools/emsdk" + _EMSDK_ENV="$_EMSDK_DIR/emsdk_env.sh" -if [ ! -f "$_EMSDK_ENV" ]; then - echo "Emscripten SDK not found. Installing..." - "$_KICAD_WASM_SCRIPTS_DIR/setup-emsdk.sh" -fi + if [ ! -f "$_EMSDK_ENV" ]; then + echo "Emscripten SDK not found. Installing..." + "$_KICAD_WASM_SCRIPTS_DIR/setup-emsdk.sh" + fi -if [ -f "$_EMSDK_ENV" ]; then - source "$_EMSDK_ENV" 2>/dev/null + if [ -f "$_EMSDK_ENV" ]; then + source "$_EMSDK_ENV" 2>/dev/null + fi fi # Common compiler flags diff --git a/scripts/kicad/build-pcbnew.sh b/scripts/kicad/build-pcbnew.sh index 0921b2f..7b4fa99 100755 --- a/scripts/kicad/build-pcbnew.sh +++ b/scripts/kicad/build-pcbnew.sh @@ -181,7 +181,11 @@ log_info "Stub libraries built" # Step 6.2: Replace Emscripten's wasm-opt with stub to bypass asyncify transformation # This allows Emscripten to generate JS with Asyncify runtime, but we run the real # wasm-opt --asyncify on the host where more RAM is available (needs 50GB+ for KiCad) -EMSDK_WASM_OPT="/emsdk/upstream/bin/wasm-opt" +if [ -z "${EMSDK}" ]; then + log_error "EMSDK environment variable is not set." + exit 1 +fi +EMSDK_WASM_OPT="${EMSDK}/upstream/bin/wasm-opt" if [ -f "${EMSDK_WASM_OPT}" ] && [ ! -f "${EMSDK_WASM_OPT}.real" ]; then log_info "Backing up real wasm-opt..." mv "${EMSDK_WASM_OPT}" "${EMSDK_WASM_OPT}.real" @@ -193,7 +197,7 @@ log_info "wasm-opt stub installed (asyncify will run on host)" # Step 6.3: Replace wasm-emscripten-finalize with stub (same pattern as wasm-opt) # This tool also OOMs on large WASM with debug symbols, so we run it on the host -EMSDK_FINALIZE="/emsdk/upstream/bin/wasm-emscripten-finalize" +EMSDK_FINALIZE="${EMSDK}/upstream/bin/wasm-emscripten-finalize" if [ -f "${EMSDK_FINALIZE}" ] && [ ! -f "${EMSDK_FINALIZE}.real" ]; then log_info "Backing up real wasm-emscripten-finalize..." mv "${EMSDK_FINALIZE}" "${EMSDK_FINALIZE}.real"