Emscripten 4.x removed dynCall_* WASM exports, breaking asyncify
rewind through indirect calls (modal dialogs, event handlers).
Generate JS shims that track Asyncify.exportCallStack and register
in wasmExports so doRewind can find them.
Also fixes empty callback functions ((() => {})) generated by
Emscripten 4.x + pthreads for HTML5 events, pthread entry,
sighandler, async timer, and main loop callbacks.
Build pipeline improvements:
- Stub wasm-opt/finalize in Docker (RAM limits), run on host
- Add setup-emsdk.sh for reproducible Emscripten setup
- Simplify env.sh and version management
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Emscripten with pthreads generates empty arrow functions `{}` for callback
paths it assumes won't be used. However, when registering HTML5 events from
the main browser thread, targetThread is 0 and the direct call path IS taken.
This fix post-processes the generated JS to replace empty callbacks with
actual dynCall invocations for:
- HTML5 event callbacks (dynCall_iiii) - 7 instances
- pthread entry points (dynCall_ii) - 1 instance
- Signal handlers (dynCall_vi) - 1 instance
- Async timers (dynCall_vi) - 1 instance
Also improves build logging to show completion status and exit code.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete test infrastructure for WebGL GAL visual regression testing:
- scripts/test-gal-regression.sh: Master script that builds both backends,
runs tests, and performs two-level comparison (native vs baseline,
webgl vs native)
- scripts/build-gal-webgl-test.sh: WASM build using Makefile with em++
- tests/gal-regression/wasm/: WebGL test harness (stub WEBGL_GAL)
- tests/e2e/gal-webgl.spec.ts: Playwright test for screenshot capture
Fix Homebrew Emscripten environment in scripts/common/env.sh:
- Set EMSDK_PYTHON for Python 3.10+ (em++ reads this, not $PYTHON)
- Add bundled LLVM to PATH (Emscripten needs its clang with WASM backend)
Verified: Native vs Baseline passes (28/28), WebGL generates blank
screenshots as expected (WEBGL_GAL implementation is Phase 2).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
wxwidgets submodule:
- Add m_isCreated flag to skip UpdateElementRegistry() during construction
- Prevents virtual method calls on partially constructed objects
scripts/common/logging.sh:
- Change -d to -e for .git check to support git worktrees
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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>
- Add autoreconf step for bundled PCRE in wxWidgets build script
(fixes automake version mismatch between 1.16.1 and 1.16.5)
- Fix apply-finalize.sh to use get-wasm-opt.sh for consistent tool paths
(tools moved to build-wasm/tools/ in previous commit)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Groups cached build tools (binaryen) with other build artifacts.
The build-wasm/ directory is already gitignored via build-*/ pattern.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add rsync-based source sync for Docker builds to fix macOS VirtioFS
timestamp inconsistencies that caused autoconf sanity checks to fail
- Add config.sub wrapper (SHELL/CONFIG_SHELL) to support emscripten/wasm32
targets without modifying submodule files
- Fix protobuf build to use native gcc/g++ for protoc instead of Emscripten
- Add python PATH fix for macOS (Homebrew's python3 symlink) in wxWidgets build
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build improvements:
- Change -O0 to -O1 to fix "local count too large" asyncify error
- Add wasm-emscripten-finalize to host (Docker OOMs on large WASM)
- Use -gseparate-dwarf for smaller main binary with debug info
- Build native protoc for code generation
- Add more functions to asyncify removelist
Runtime fixes:
- Add inject-dyncall-shims.sh to fix "dynCall_* is not defined" in Emscripten 4.x
- Update wxwidgets with browserInfo.name fix
New stubs and bindings:
- Add Embind bindings for JavaScript interop
- Add stubs for scripting, API plugin, PCB frame, navlib
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add source hashing to stamp system (functions.sh) for detecting
when dependencies need rebuild based on source file changes
- Update build-pcbnew.sh to use source stamps for wxWidgets
- Add global-setup.ts to clean logs before test runs
- Add maximize_test standalone test to verify wxFrame::Maximize()
works correctly in WASM (it does - window is 1280x720)
- Update Makefile.wasm with maximize test build rules
The maximize_test proves wxWidgets display detection works fine.
KiCad's 20x20 window bug is KiCad-specific, not a wxWidgets issue.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move asyncify from Docker to host to avoid memory issues
- Auto-download Binaryen v121 (v125 has regression bug)
- Use -O1 for debug builds (V8 local count limit)
- Remove asyncify flags from linker (handled by wasm-opt)
- Document two-phase build in build.md
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add build.md documentation for the WASM build system
- Default to debug builds with -gsource-map for WASM debugging
- Add --release flag to disable debug symbols
- Add --clean flag for full rebuild (deps + wxWidgets + KiCad)
- Add -j N flag for parallel compilation (default: 1 for sequential)
- Update Docker memory limit to 32GB
- Propagate DEBUG_BUILD and JOBS to all dependency scripts
Build modes:
- ./docker/build.sh --clean -j8 (full rebuild, parallel)
- ./docker/build.sh (rebuild KiCad only)
- ./docker/build.sh --no-clean (incremental)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>