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
Replace the legacy Emscripten JS-exceptions model with native wasm-EH (legacy
encoding) across the whole build, keeping Asyncify coroutines working via a
from-source Binaryen --hoist-cpp-catches pre-pass. Net result: native-EH is the
only build mode, the 3D viewer is on by default, and pcbnew shrinks substantially.
Highlights:
- Binaryen submodule everywhere + --hoist-cpp-catches integration in apply-asyncify;
post-link Asyncify covers every app wasm (not just standalone test wasm).
- Build deps (incl. OpenCASCADE without OCC_CONVERT_SIGNALS) and all KiCad apps
with -fwasm-exceptions; emscripten_sleep added to the post-link asyncify-imports.
- libcontext fiber entry wired under native exceptions; while-loop main loop +
currData shim injected into all wx apps.
- Native-EH collab apply fixed: DEBUG-define the embind TU + match all out-of-CMake
C++ TUs' ABI flags to the core, fixing the vtable-layout skew / mis-dispatch.
- 3D viewer enabled by default (real raytracer linked, not the stub).
- Retire the EH-spike scaffolding; flip the asyncify-races ablation pins to
shim-redundancy pins (native-EH stays clean with the legacy shims ablated).
- Fix the asyncify-races quiescence check to not require Asyncify.currData==0:
under the native-EH per-frame-yield top loop the main stack is asyncify-suspended
every frame, so currData legitimately churns (a freed-but-not-yet-nulled buffer,
not a leak). Refresh the pcbnew toolbar screenshot baseline for the new kicad.
- CI: drop the obsolete binaryen_version input/env (the build uses the binaryen
submodule fork's wasm-opt, not a version download); key the wasm-output cache on
the binaryen submodule SHA instead.
Bumps the wxwidgets + binaryen submodules to their squashed feature commits.
Validated green: all 7 apps native-EH (real 3D in pcbnew); KiCad e2e 63/63
Firefox + Chromium (3D viewer renders); wx 336; coroutine 34/34 both engines;
asyncify 7/7 both engines.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The canvas (wxUniversal) mode is gone (wxwidgets submodule); remove every
piece of side-by-side plumbing so there is exactly one build and one test
flow:
- scripts/build-wxuniversal-wasm.sh -> scripts/build-wx-wasm.sh; no
--dom/--enable-universal; builds into build-wasm/wxwidgets
- build-wasm-test.sh: no DOM_BUILD / apps-dom rsync mirror / PORT=dom;
apps build straight into tests/apps (Makefile.wasm PORT conditionals
collapsed; wx.js + wx-dom.js always pre-js)
- docker/build.sh, build-kicad-target.sh, env.sh: WX_PORT / -dom /
-universal suffixes removed; kicad builds to kicad-<app>, outputs to
output/; wx.js/wx-dom.js copied from the real source path
(/workspace/wxwidgets/build/wasm — the old build-wasm path never
existed and silently failed)
- setup-kicad-wasm.sh: single target dir; the perl wx-dom.js injection is
gone — the 7 checked-in kicad pages now reference wx-dom.js directly
- playwright configs serve apps/; fixtures drop the test-results/dom and
logs/wxwidgets/dom namespacing; boot.spec asserts wxDomPort
unconditionally; pcbnew.spec uses one reference image;
appearance.spec assertions unconditional
- compare/update-baseline-screenshots.sh: --port removed
- tests/gal-regression/wasm/Makefile: links build-wasm/wxwidgets and
carries wx-dom.js as a second pre-js — the gal-webgl suite (30 specs)
now actually builds and runs here (it needed host-side boost+glm via
scripts/deps; the bundle had been missing, timing the whole spec out)
- tests: clickCanvas() dispatches via page.mouse (DOM widgets
legitimately cover the canvas; locator actionability refused the
click); the comprehensive spec drives wxChoice through its native
<select> (browser-owned popup cannot be coordinate-clicked)
- docs: README/CLAUDE.md/build.md script names and dirs;
features/wx-dom-port README reframed (DOM is THE port), visual-notes
bugs 26-28; FindwxWidgets.cmake config label drops 'wasmuniv'
- wxwidgets submodule -> 9dbacc9448 (DOM-only port, fork diff shrunk)
Gate: full wx e2e suite 292 passed / 1 skipped / 0 failed — first run
ever with the gal-webgl specs green (28 scenarios + load + sequential).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The wx test-app mirror (build-wasm-test.sh --dom, rsync --delete) wiped
the kicad bundles setup-kicad-wasm.sh syncs into apps-dom/kicad —
apps/kicad only carries the checked-in HTML. Exclude kicad/ (that dir is
owned by the setup script). Add 'npm run serve:dom' for browsing the
DOM-port apps; plain 'npm run serve' serves the canvas dir, which has no
kicad bundles in this worktree (canvas KiCad was never built here).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Build/test plumbing for the second wxWidgets mode: --dom on
build-wxuniversal-wasm.sh (build-wasm/wxwidgets-dom, no universal,
--disable-tooltips, libwx_wasmu_* stubs) and build-wasm-test.sh
(mirrors sources into tests/apps-dom, PORT=dom). Build script now
reconfigures when Makefile.in or autoconf_inc.m4 regenerate (bakefile
chain). Harness: WX_PORT=dom serves apps-dom, namespaces screenshots
into test-results/dom and logs into logs/wxwidgets/dom; compare/update
screenshot scripts take --port dom with baseline-screenshots-dom.
New port-agnostic boot.spec.ts (green on both ports).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Emscripten 4.0.22+ requires Python 3.10+ (uses match statement).
The env.sh script sets EMSDK_PYTHON to use Homebrew's Python
instead of the system Python 3.9.6.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Restore missing elementtracker.h in wxWidgets (required for E2E tests)
- Add automatic log file redirection for build scripts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- build-wxuniversal-wasm.sh: Default to incremental, add --clean flag
- build-wasm-test.sh: Remove automatic clean, add --clean flag
Performance:
- No changes: ~0.3s (was full rebuild)
- Single file change: ~5s (just that file)
- Clean rebuild: use --clean flag
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The KiCad WASM build was freezing during initialization due to a pthread
deadlock. When hardware_concurrency() > PTHREAD_POOL_SIZE, new Web Worker
creation requires the event loop, but the main thread busy-waits blocking it.
Changes:
- Use navigator.hardwareConcurrency for PTHREAD_POOL_SIZE in KiCad build
- Add threadpool test to reproduce and verify the fix
- Add single-target build support to build-wasm-test.sh
- Default docker/build.sh to -j 10 for faster builds
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The wxGrid test was crashing with "memory access out of bounds" due to
an initialization order bug in grid_test.cpp: during CreateGrid(), wxGrid
fires cell selection events which triggered the OnGridCellSelect handler
that called m_log->AppendText() before m_log was initialized.
Fix: Add null check in LogEvent() to guard against events firing before
m_log is created.
Also adds --debug flag to build-wasm-test.sh for debugging WASM crashes:
- Builds with DWARF symbols (-g) and source maps (-gsource-map)
- No optimization (-O0) preserves debugging context
- Stack traces show actual function names instead of wasm-function[N]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add tests/ directory with Playwright e2e tests
- Add minimal wxWidgets WASM test application
- Add build script for test app (scripts/build-wasm-test.sh)
- Update wxWidgets submodule with WASM build fixes
- Update .gitignore for test artifacts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>