Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
#!/bin/bash
# Build OpenCASCADE Technology (OCCT) for WebAssembly
# OCCT provides 3D geometry kernel for STEP file import/export
set -e
SCRIPT_DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) " && pwd ) "
source " ${ SCRIPT_DIR } /../common/env.sh "
source " ${ SCRIPT_DIR } /../common/versions.sh "
source " ${ SCRIPT_DIR } /../common/functions.sh "
OCC_DIR = " ${ DEPS_ROOT } /opencascade- ${ OCC_VERSION } "
OCC_BUILD = " ${ BUILD_ROOT } /deps/opencascade "
OCC_STAMP = " ${ BUILD_ROOT } /stamps/opencascade.stamp "
# Parse arguments
CLEAN = 0
for arg in " $@ " ; do
case $arg in
--clean)
CLEAN = 1
shift
; ;
esac
done
if [ $CLEAN -eq 1 ] ; then
log_info "Cleaning OpenCASCADE build..."
rm -rf " ${ OCC_BUILD } " " ${ OCC_STAMP } "
fi
# Check if already built
if check_stamp " ${ OCC_STAMP } " ; then
log_info "OpenCASCADE already built, skipping..."
exit 0
fi
# Download if needed
if [ ! -d " ${ OCC_DIR } " ] ; then
log_info " Downloading OpenCASCADE ${ OCC_VERSION } ... "
mkdir -p " ${ DEPS_ROOT } "
cd " ${ DEPS_ROOT } "
# OpenCASCADE releases are on GitHub
OCC_URL = " https://github.com/Open-Cascade-SAS/OCCT/archive/refs/tags/V ${ OCC_VERSION //./_ } .tar.gz "
2026-08-28 20:34:16 +02:00
download_file " ${ OCC_URL } " " opencascade- ${ OCC_VERSION } .tar.gz " " ${ OCC_SHA256 } "
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
tar -xzf " opencascade- ${ OCC_VERSION } .tar.gz "
2025-12-08 11:37:14 +01:00
# Directory name in tarball is OCCT-7_8_0 (without V prefix)
mv " OCCT- ${ OCC_VERSION //./_ } " " opencascade- ${ OCC_VERSION } "
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
rm " opencascade- ${ OCC_VERSION } .tar.gz "
fi
feat(wasm): occ-split — lazy occ_service worker; kicad_editor drops OCC (−31%)
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>
2026-07-03 12:39:58 +02:00
# RapidJSON (header-only): required by OCC's glTF/GLB writer — without it the
# writer compiles out (HAVE_RAPIDJSON undefined) and GLB export fails at
# runtime with "glTF writer is unavailable". Pinned to the vcpkg master
# snapshot (see versions.sh) — a commit archive extracts as rapidjson-<sha>,
# so rename to the dated version dir.
RAPIDJSON_DIR = " ${ DEPS_ROOT } /rapidjson- ${ RAPIDJSON_VERSION } "
if [ ! -d " ${ RAPIDJSON_DIR } " ] ; then
log_info " Downloading RapidJSON ${ RAPIDJSON_VERSION } (master snapshot ${ RAPIDJSON_COMMIT : 0 : 12 } )... "
mkdir -p " ${ DEPS_ROOT } "
cd " ${ DEPS_ROOT } "
2026-08-28 20:34:16 +02:00
download_file " ${ RAPIDJSON_URL } " " rapidjson- ${ RAPIDJSON_VERSION } .tar.gz " " ${ RAPIDJSON_SHA256 } "
feat(wasm): occ-split — lazy occ_service worker; kicad_editor drops OCC (−31%)
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>
2026-07-03 12:39:58 +02:00
tar -xzf " rapidjson- ${ RAPIDJSON_VERSION } .tar.gz "
mv " rapidjson- ${ RAPIDJSON_COMMIT } " " rapidjson- ${ RAPIDJSON_VERSION } "
rm " rapidjson- ${ RAPIDJSON_VERSION } .tar.gz "
fi
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
log_info " Building OpenCASCADE ${ OCC_VERSION } for WASM... "
log_warn "This is a large library and may take a while..."
mkdir -p " ${ OCC_BUILD } "
cd " ${ OCC_BUILD } "
# OpenCASCADE build configuration for WASM
# Disable GUI, visualization that needs X11/OpenGL native
# Enable core geometry and data exchange modules only
2026-06-29 19:50:18 +02:00
#
# OCC's CMake unconditionally adds -DOCC_CONVERT_SIGNALS (occt_defs_flags.cmake), which turns the
# OCC_CATCH_SIGNALS macro into setjmp(handler.Label()). The STEP read/write code
# (STEPControl_Reader/ActorRead, ...) uses OCC_CATCH_SIGNALS pervasively. Under -fwasm-exceptions that
# setjmp is lowered (emscripten's LowerEmscriptenEHSjLj) into a wasm-SjLj state-machine br_table whose
# branch targets are inconsistently typed -> INVALID wasm that V8, wabt AND Binaryen all reject (this
# is the "popping from empty stack" / br_table type-mismatch that blocks pcbnew's OCC link). WASM has
# no POSIX signals, so OCC_CONVERT_SIGNALS (signal->exception conversion) is meaningless here anyway;
# OCC's normal C++ Standard_Failure throw/catch is unaffected. Disabling it means OCC_CATCH_SIGNALS
# expands to nothing (clang) -> no setjmp -> no wasm-SjLj -> valid native-EH wasm.
_occ_defs = " ${ OCC_DIR } /adm/cmake/occt_defs_flags.cmake "
if grep -q '^[[:space:]]*add_definitions(-DOCC_CONVERT_SIGNALS)' " ${ _occ_defs } " 2>/dev/null; then
sed -i 's|add_definitions(-DOCC_CONVERT_SIGNALS)|# add_definitions(-DOCC_CONVERT_SIGNALS) # disabled for native wasm-EH by build-opencascade.sh (no POSIX signals in WASM; setjmp breaks -fwasm-exceptions)|' " ${ _occ_defs } "
log_info "Disabled OCC_CONVERT_SIGNALS for native wasm-EH (avoids invalid wasm-SjLj br_table)"
fi
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
emcmake cmake " ${ OCC_DIR } " \
2025-12-08 11:37:14 +01:00
-DCMAKE_POLICY_VERSION_MINIMUM= 3.5 \
2025-12-12 14:51:38 +01:00
-DCMAKE_BUILD_TYPE= ${ BUILD_TYPE :- Debug } \
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
-DCMAKE_INSTALL_PREFIX= " ${ SYSROOT } " \
2026-06-29 19:50:18 +02:00
-DCMAKE_CXX_FLAGS= " ${ DEBUG_CFLAGS :- -g -O0 } -pthread -matomics -mbulk-memory ${ DEPS_EH_FLAGS } " \
-DCMAKE_C_FLAGS= " ${ DEBUG_CFLAGS :- -g -O0 } -pthread -matomics -mbulk-memory ${ DEPS_EH_FLAGS } " \
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
-DBUILD_LIBRARY_TYPE= Static \
-DBUILD_MODULE_ApplicationFramework= OFF \
-DBUILD_MODULE_Draw= OFF \
-DBUILD_MODULE_Visualization= OFF \
-DBUILD_MODULE_DETools= OFF \
-DBUILD_MODULE_FoundationClasses= ON \
-DBUILD_MODULE_ModelingData= ON \
-DBUILD_MODULE_ModelingAlgorithms= ON \
-DBUILD_MODULE_DataExchange= ON \
-DUSE_FREETYPE= OFF \
-DUSE_FREEIMAGE= OFF \
-DUSE_OPENVR= OFF \
-DUSE_FFMPEG= OFF \
-DUSE_TBB= OFF \
-DUSE_VTK= OFF \
-DUSE_TCL= OFF \
-DUSE_TK= OFF \
-DUSE_GLES2= OFF \
-DUSE_OPENGL= OFF \
-DUSE_D3D= OFF \
feat(wasm): occ-split — lazy occ_service worker; kicad_editor drops OCC (−31%)
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>
2026-07-03 12:39:58 +02:00
-DUSE_RAPIDJSON= ON \
-D3RDPARTY_RAPIDJSON_DIR= " ${ RAPIDJSON_DIR } " \
Add KiCad WASM build infrastructure and dependency scripts
- Add build environment setup (scripts/common/env.sh, versions.sh, functions.sh)
- Add dependency build scripts for Zstd, GLM, FreeType, HarfBuzz, Pixman, Cairo
- Add placeholder scripts for OpenCASCADE, ngspice, protobuf
- Add WASM compatibility layer (wasm/kiplatform/, wasm/libcontext/)
- Add CMake modules for KiCad WASM cross-compilation
- Add PCBnew test infrastructure (tests/kicad/)
- Add build plan documentation
Successfully tested builds: Zstd 1.5.5, GLM 0.9.9.8, FreeType 2.13.2,
HarfBuzz 8.3.0, Pixman 0.42.2, Cairo 1.18.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:04 +01:00
-DUSE_DRACO= OFF \
-DBUILD_DOC_Overview= OFF \
-DINSTALL_SAMPLES= OFF \
-DINSTALL_TEST_CASES= OFF
emmake make -j${ JOBS }
emmake make install
create_stamp " ${ OCC_STAMP } "
log_info "OpenCASCADE build complete!"