feat: OCCT V8.0.0 + Emscripten 5.0.1 with native WASM exceptions#301
feat: OCCT V8.0.0 + Emscripten 5.0.1 with native WASM exceptions#301rifont wants to merge 169 commits into
Conversation
|
56a829a to
dd159fa
Compare
…xceptions Upgrade opencascade.js from OCCT V7.6.2 / Emscripten 3.1.14 to OCCT V8.0.0-RC4 / Emscripten 5.0.1 with the following changes: OCCT V8 Migration: - Port all V8 API breaking changes (TopoDS namespace, HashCode removal, BRepMesh constructor, Handle typedefs, Bnd_Box/Poly_Triangulation API) - Add C++ wrapper classes: TopoDS_Cast, OCJS_ShapeHasher, BRepMesh_IncrementalMeshWrapper, BRepToolsWrapper, GeomToolsWrapper - Update filter/binding generation for V8 toolkit reorganization - Apply patches for V8 compatibility (Standard_Dump stubbing) Native WASM Exception Handling: - Replace JS invoke trampolines (-fexceptions) with native WASM EH (-fwasm-exceptions), reducing exception build size overhead from ~80% to ~12% gzipped with zero happy-path performance cost - Support both exception and no-exception build variants Build System: - Add build-wasm.sh: unified entry point with --help, --preset, validate command, cache management, and build summary output - Add config-keyed compilation cache (build-cache.py) that skips ~30min compilation on cache hit - Add build provenance tracking (provenance.json sidecar) - Add DEPS.json pinning all dependency commits for reproducibility - Add clone-deps.sh for automated dependency setup - Add Docker E2E validation script - Support OCJS_DEFINES/OCJS_UNDEFINES env vars for compile flags Build Configs: - Add full.yml (233 symbols) and full-exceptions.yml (235 symbols) - Add optimization presets: O2-balanced, O3-maxperf, Os-minsize, O0-debug - Presets separate "what to bind" from "how to optimize" Dockerfile: - Update to emscripten/emsdk:5.0.1 with pinned digest - Clone deps at exact commit hashes from DEPS.json - Entrypoint via build-wasm.sh with env var passthrough Documentation: - V8 migration guide with 10 systemic API breaking changes - Build optimization guide (size vs speed, LTO, defines, wasm-opt) - Build configuration reference (YAML schema, handle types, presets) - Rewritten README with quick start, Docker, and customization guides Performance (vs V7.6.2): - Boolean operations: 22-31% faster - Fillets: 16-19% faster - Complex models: 23-29% faster - Gzipped size: -6.6% (single), -39.1% (exceptions) Made-with: Cursor
dd159fa to
a4af3c2
Compare
|
OCJS v8 API design discussions are underway in CodeCAD Discord server, under the replicad channel here. |
|
Oh yeah, nice, I have the same upgrade here: master...zalo:opencascade.js:cascadestudio-v2 It looks like you had to deal with the same pain with the RC4 upgrade that I did 😄 That said, I suspect my build may be smaller because I trim out a lot of unnecessary files 🤔 This guy also has an entry for OpenCascade 8.0.0: https://github.com/andymai/brepjs |
…ion, and tutorial examples
The docs-site is a standalone pnpm workspace on Vercel. These imports were only satisfied locally via the parent Tau monorepo hoisting, so production builds failed with module-not-found. Co-authored-by: Cursor <cursoragent@cursor.com>
…imit The Synthetic NCollection Generated package (877 classes) produced a 44 MB RSC fallback, exceeding Vercel's 19 MB limit. Split packages with more than 100 classes into /page-N static routes so each pre-render stays within budget. Co-authored-by: Cursor <cursoragent@cursor.com>
Paginated routes (/page-2) had no virtual Fumadocs page, so the docs shell lost tree context and root lib:npm/lib:webassembly icons expanded (size-full). Register virtual pages for each page-N segment and default brand icons to size-4. Move ApiHashHighlight outside the two-column class grid. Co-authored-by: Cursor <cursoragent@cursor.com>
Paginated routes used both b-rep-graph.mdx and b-rep-graph/page-N.mdx, so Fumadocs treated the package as a folder and humanized the slug to "B rep graph". Paginated packages now use index.mdx + meta.json with the OCCT name. Co-authored-by: Cursor <cursoragent@cursor.com>
The e2e gate used load: true with provenance/sbom enabled, which makes buildx export manifest lists the docker exporter cannot load. Disable attestations on --load steps (same as docker-smoke); keep them on push. Bump workflow actions to current releases and set FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 for the Node 20 deprecation. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove cache-to from --load build steps in branch-publish and release-build so registry cache is updated once on push, after e2e. Prevents pre-gate cache pollution and redundant GHCR cache uploads. Document GHCR Manage Actions access requirement in workflow header. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Rewrite docker-e2e-validate.sh to link build-configs/full.yml and full_multi.yml from the repo image warm cache. bindgen-base validates full configs only. Pass OCJS_E2E_STAGE and OCJS_E2E_BUILD_CONFIG per matrix job in branch-publish and release-build. Co-authored-by: Cursor <cursoragent@cursor.com>
Hardcoded --cpus 8 exceeds GHA ubuntu-latest (4 cores), causing exit 125 before the full.yml link could start. bindgen-base passed because it only runs validate, not _run_link. Co-authored-by: Cursor <cursoragent@cursor.com>
Full-build docker e2e checks nCollectionManifest structural invariants only — high linked/total on full.yml is expected. Move the ≤0.20 trim filter ratio assertion to docker-smoke after link-filter-poc.yml link. Co-authored-by: Cursor <cursoragent@cursor.com>
full.yml warm links take ~8–9 min on GHA; 520s was failing against the old 300s cap. Also fix v3 JS smoke constructors, add local preflight tooling, cap docker CPUs to the daemon limit, and checkout before release post-publish smoke. Co-authored-by: Cursor <cursoragent@cursor.com>
Phase 6 used require() on pthread ESM glue; Node 22 rejects that with ERR_REQUIRE_ASYNC_MODULE. Use import()+locateFile matching tests/docker/docker-helpers.ts loadModule(). Co-authored-by: Cursor <cursoragent@cursor.com>
branch-publish no longer waits on docker-smoke; pre-publish e2e on single/multi remains the publish gate. Cuts branch wall clock by ~smoke duration. Co-authored-by: Cursor <cursoragent@cursor.com>
Note from @rifont : this PR is still under active development and testing, it has thus far been successfully integrated into
replicad-opencascadejsbut needs further testing to validate the full build.TLDR:
.wasmassets on Apple M-series is now ~15 minutes with-O0compile and-O0linking. Includes build provenance system for easier tracking of optimization inputs to WASM benchmarking perf.Summary
Upgrades opencascade.js from OCCT V7.6.2 / Emscripten 3.1.14 to OCCT V8.0.0-RC4 / Emscripten 5.0.1, bringing substantial performance improvements, modern WASM exception handling, and a developer-friendly build system.
Key highlights:
build-wasm.shentry point with compilation caching, presets, provenance tracking, and avalidatecommandDEPS.jsonpins all dependencies to exact commit hashes;clone-deps.shautomates setupThis PR incorporates the bindings generation speedups from #292 as part of the V8 migration work.
Performance
Benchmarks comparing V7.6.2 to V8 (single-threaded, noLTO):
Size (Gzipped) (testing with replicad-opencascadejs build)
The dramatic exception size reduction comes from replacing Emscripten's JavaScript invoke trampolines (which generated a JS wrapper for every potentially-throwing call site) with native WASM
throw/catchinstructions. Browser support: 94.5%+ (Chrome 95+, Firefox 100+, Safari 15.2+).Build System
Quick Start (Native)
Docker
Presets
New Features
./build-wasm.sh --help— full usage with examples./build-wasm.sh validate <yaml>— check config without building./build-wasm.sh --preset <name>— apply optimization presetsprovenance.jsonsidecar traces exact source versionsOCCT V8 Breaking Changes
10 systemic API changes that affect downstream consumers:
TopoDS_Shape::HashCoderemoved → useOCJS_ShapeHasherwrapperTopoDSnamespace not directly bindable → useTopoDS_CastwrapperBRepMesh_IncrementalMeshconstructor changed → useBRepMesh_IncrementalMeshWrapperHandle_*types need explicit typedef inadditionalCppCodeBnd_Box::Get()removed →CornerMin()/CornerMax()Poly_Triangulationnormals API changedPoly_PolygonOnTriangulation::Nodes()removed →NbNodes()+Node(i)gp_Ax2_3→_4)SetValue→SetValue_1)Bnd_Box2d::Get()removed → individual accessorsFull migration guide:
docs/occt-v8-migration.mdNew Files
DEPS.jsonrequirements.txtbuild-wasm.shscripts/clone-deps.shscripts/docker-e2e-validate.shsrc/build-cache.pysrc/provenance.pysrc/patches/patch_standard_dump.pybuild-configs/full.ymlbuild-configs/full-exceptions.ymlbuild-configs/presets/*.ymldocs/occt-v8-migration.mddocs/optimization-guide.mddocs/build-config-reference.mdTest Plan
single-exceptionsWASM variant (tray, birdhouse, bottle, gridfinity-box, vase, wavy-vase, cycloidal-gear, projection-test)full.yml(no exceptions) andfull-exceptions.yml(WASM exceptions) produce valid WASM/JS/DTS outputclone-deps.sh→ emsdk activation → Python deps →-O0build →-O3max-perf build./build-wasm.sh validatecorrectly validates and rejects YAML configsscripts/docker-e2e-validate.sh) — script provided, requires ~1hr build timeRisks
_Nsuffixes will need to update. The.d.tsfile provides the correct suffixes.Related Issues & PRs
validatecommand and clear error messagesAI Disclosure