perf(build): use all cores in host builds — wx lib, test apps, gal-webgl

env.sh exports a docker-safe JOBS=1 default, and every host build silently
inherited it (the docker kicad path dodges it by passing -j explicitly):

- build-wx-wasm.sh: the intended "${JOBS:-nproc}" fallback sat BELOW the
  env.sh source, so it was dead code — full wx builds ran make -j1 on the
  Mac and on CI. Compute the all-cores default before env.sh instead
  (explicit JOBS/PARALLEL_JOBS still wins); also -j the PCRE pre-build.
- build-wasm-test.sh: same default fix, plus fan the post-link
  hoist+asyncify loop out across JOBS with xargs -P. Per-app wasm-opt
  can't feed many cores (small modules), so serial stays ~4min even with
  BINARYEN_CORES=16; fanning across the 74 independent apps is what
  scales. Safe: apply-asyncify is in-place per wasm, injector tmp is
  per-js, HOIST_WASMOPT resolved once up front.
- build-gal-webgl-test.sh: make had no -j at all.

Measured on a 16-core M4 Max, clean test-app build: 15m36s (-j1) → 2m08s,
peak RAM 10.7 GB summed across all build processes (64 GB machine; CI
runners have 120 GB). Core counts are always derived from nproc at
runtime — nothing hardcoded, CI workers differ.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeiSRRScdaox5jBueJNcyG
This commit is contained in:
Viktor Vaczi 2026-07-02 10:54:14 +02:00
commit 348596c515
3 changed files with 38 additions and 14 deletions

View file

@ -5,6 +5,13 @@
# Redirect all output to a log file (re-execs script with redirection)
source "$(dirname "$0")/common/logging.sh"
# Default to all cores BEFORE sourcing env.sh — env.sh exports a docker-safe
# JOBS=1 when unset, which would make the "${JOBS:-nproc}" fallback below it
# dead code (this build ran make -j1 everywhere for that reason). An explicit
# JOBS/PARALLEL_JOBS from the caller still wins (e.g. the docker pipeline's -j
# via build-kicad-target.sh).
JOBS="${JOBS:-$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)}"
# Source common environment (sets up local emsdk)
source "$(dirname "$0")/common/env.sh"
# Build-progress markers (parsed by scripts/build-monitor.sh).
@ -53,9 +60,6 @@ export CONFIG_SHELL="$SCRIPT_DIR/config/config-sub-wrapper.sh"
# Disable autom4te cache to keep submodules clean
export AUTOM4TE="$SCRIPT_DIR/config/autom4te-wrapper.sh"
# Use JOBS from env.sh if set, otherwise use all available cores
JOBS="${JOBS:-$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)}"
echo "=== Building wxWidgets for WASM ==="
echo "Project root: $PROJECT_ROOT"
echo "Build dir: $BUILD_DIR"
@ -187,7 +191,8 @@ if [ $NEEDS_CONFIGURE -eq 1 ]; then
# PCRE headers (pcre2.h) must be generated before regex.cpp compiles
echo ""
echo "=== Building PCRE first (dependency) ==="
emmake make -C 3rdparty/pcre
# Serial relative to the main build (it fully completes first); parallel inside.
emmake make -j${JOBS} -C 3rdparty/pcre
fi
# Ensure the Emscripten zlib port exists before compiling. We configure with