Move OpenCASCADE out of the merged editor image into occ_service: a separate
emscripten module (-sASYNCIFY=0, MODULARIZE, in-container -Oz finalize, 2N+8
pre-warmed pthread pool) booted lazily in a dedicated Web Worker on the first
STEP export or STEP/IGES model parse. kicad_editor.wasm ~190 MB -> 130 MB;
sessions that never touch OCC never fetch its 57 MB. STEP export works in the
browser for the first time: the unchanged desktop dialog runs EXPORTER_STEP,
whose wasm shadow suspends into globalThis.occService and the export bytes go
straight to a browser download (never entering the editor heap). STEP/IGES 3D
models parse in the worker via the oce shadow (S3D WriteCache/ReadCache wire).
- wasm/occ-service/: service CMake target (hooked from the kicad fork's
top-level CMakeLists, wasm/editor pattern), embind entry
(occExport/occLoadModel), wxConfig pre-js.
- wasm/stubs/{exporter_step,oce_plugin}_stub.cpp: EM_ASYNC_JS worker bridges
(callee-shadowing; no caller #ifdefs).
- web/standalone: provider installed whenever the kicad_editor bundle boots
(cross-face safe); ONE shared worker-boot source occ-worker.js (vite ?raw;
the e2e stub reads the same file) — blob worker with locateFile absolutized
against the glue URL; export download-name guard.
- deps: OCC builds with RapidJSON so its glTF/GLB writer exists — pinned to
the vcpkg master snapshot 2025-02-26 (24b5e7a8b27f), the same code official
KiCad consumes via vcpkg.json's opencascade[rapidjson]; rapidjson's latest
tag (v1.1.0, 2016) is ill-formed under modern clang.
- tests: occ-export dialog e2e (lazy-fetch boundary + STEP download bytes),
occ-probe incl. a 9-format matrix (step/stpz/brep/xao/ply/stl/glb/u3d/pdf),
3d-viewer-models hard-asserts the worker parse; occ provider stub installed
ambiently by the kicad fixtures.
Validated against desktop kicad-cli 10.0.4: geometric exact equality (bbox
delta 0 um, volume delta 0.0000%) for STEP/GLB/STL/BREP/STPZ across three
boards and option sweeps — with desktop OCC 7.9 vs wasm OCC 7.8; PLY/XAO/PDF
structurally equal; U3D same-size (quantizer float LSBs differ). Full kicad
e2e green on Firefox and Chromium; standalone verified end to end (lazy fetch
only on the Export click; export.step 60,628 B ISO-10303-21; loadModel 700 KB
STEP -> 569 KB scenegraph cache).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
Build fixes:
- Enable C++ exceptions in wxWidgets (--enable-exceptions, -fexceptions)
Required for KiCad's OnExceptionInMainLoop override in debug builds
- Add -matomics -mbulk-memory to all dependency builds for shared memory
Required for pthreads support with Emscripten
- Fix docker/build.sh output copy path (pcbnew/ not bin/)
- Make workspace mount read-only in docker-compose.yml
Updated dependency scripts:
- build-freetype.sh, build-harfbuzz.sh, build-protobuf.sh
- build-zstd.sh, build-opencascade.sh, build-boost.sh
- build-pixman.sh, build-cairo.sh (meson cross-file)
- build-wxuniversal-wasm.sh, build-pcbnew.sh
🤖 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>