Skip to content

Commit a4af3c2

Browse files
committed
feat: OCCT V8.0.0-RC4 + Emscripten 5.0.1 migration with native WASM exceptions
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
1 parent 5ff2b75 commit a4af3c2

36 files changed

Lines changed: 5041 additions & 603 deletions

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,12 @@ node_modules
55
build-output.log
66
pull-stages-output.log
77
/occt-src/
8+
9+
# Build artifacts (output of build-wasm.sh placed alongside YAML configs)
10+
*.wasm
11+
*.wasm.symbols
12+
*.js.symbols
13+
/cache/
14+
build-configs/*.js
15+
build-configs/*.d.ts
16+
build-configs/provenance.json

DEPS.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"$schema": "deps-lock-v1",
3+
"description": "Pinned dependency versions for reproducible opencascade.js builds. Both Dockerfile and build-wasm.sh reference this file.",
4+
"dependencies": {
5+
"occt": {
6+
"repository": "https://github.com/Open-Cascade-SAS/OCCT.git",
7+
"commit": "48ebca0f70a5e4b936548b695bc3583363898da4",
8+
"version": "V8_0_0_rc4 (master tip)",
9+
"description": "Open CASCADE Technology — the C++ CAD kernel"
10+
},
11+
"rapidjson": {
12+
"repository": "https://github.com/Tencent/rapidjson.git",
13+
"commit": "24b5e7a8b27f42fa16b96fc70aade9106cf7102f",
14+
"version": "post-1.1.0 (master)",
15+
"description": "JSON parser/generator for C++ (header-only)"
16+
},
17+
"freetype": {
18+
"repository": "https://github.com/freetype/freetype.git",
19+
"commit": "de8b92dd7ec634e9e2b25ef534c54a3537555c11",
20+
"version": "VER-2-13-0",
21+
"description": "Font rendering library"
22+
},
23+
"emscripten": {
24+
"docker_image": "emscripten/emsdk:5.0.1",
25+
"docker_digest": "sha256:c89732ef63a56de5a96395c5a8c1c7904f7420131a045406e6fedc4cbe1cc198",
26+
"emsdk_version": "5.0.1",
27+
"description": "Emscripten SDK for compiling C++ to WebAssembly"
28+
}
29+
}
30+
}

Dockerfile

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,80 @@
1-
FROM emscripten/emsdk:3.1.14 AS base-image
1+
# opencascade.js — OCCT V8 WASM build image
2+
#
3+
# Build:
4+
# docker build -t opencascade-js .
5+
#
6+
# Run (default full build with balanced preset):
7+
# docker run -v $(pwd)/output:/output opencascade-js full build-configs/full.yml
8+
#
9+
# Run with custom config:
10+
# docker run -v $(pwd)/my-config.yml:/opencascade.js/build-configs/custom.yml \
11+
# -v $(pwd)/output:/output \
12+
# opencascade-js full build-configs/custom.yml
13+
#
14+
# Environment variable overrides:
15+
# docker run -e OCJS_OPT="-Os" -e OCJS_EXCEPTIONS=1 ... opencascade-js full build-configs/full.yml
216

3-
RUN \
4-
apt update -y && \
5-
apt install -y \
6-
bash \
7-
build-essential \
8-
cmake \
9-
curl \
10-
git \
11-
libffi-dev \
12-
libgdbm-dev \
13-
libncurses5-dev \
14-
libnss3-dev \
15-
libreadline-dev \
16-
libsqlite3-dev \
17-
libssl-dev \
18-
libbz2-dev \
19-
npm \
20-
python3 \
21-
python3-pip \
22-
python3-setuptools \
23-
zlib1g-dev
17+
FROM emscripten/emsdk:5.0.1@sha256:c89732ef63a56de5a96395c5a8c1c7904f7420131a045406e6fedc4cbe1cc198 AS base-image
2418

2519
RUN \
26-
pip install \
27-
libclang==15.0.6.1 \
28-
pyyaml==6.0 \
29-
cerberus==1.3.4 \
30-
argparse==1.4.0
20+
apt-get update -y && \
21+
apt-get install -y --no-install-recommends \
22+
bash \
23+
build-essential \
24+
cmake \
25+
curl \
26+
git \
27+
python3 \
28+
python3-pip \
29+
python3-setuptools && \
30+
rm -rf /var/lib/apt/lists/*
31+
32+
COPY requirements.txt /tmp/requirements.txt
33+
RUN pip install --break-system-packages -r /tmp/requirements.txt && rm /tmp/requirements.txt
3134

35+
# Clone dependencies at pinned commits (from DEPS.json)
3236
WORKDIR /rapidjson/
3337
RUN \
34-
git clone -b v1.1.0 https://github.com/Tencent/rapidjson.git .
38+
git clone https://github.com/Tencent/rapidjson.git . && \
39+
git checkout 24b5e7a8b27f42fa16b96fc70aade9106cf7102f
3540

3641
WORKDIR /freetype/
3742
RUN \
38-
git clone -b VER-2-13-0 https://github.com/freetype/freetype.git .
43+
git clone https://github.com/freetype/freetype.git . && \
44+
git checkout de8b92dd7ec634e9e2b25ef534c54a3537555c11
3945

40-
ENV OCCT_COMMIT_HASH_FULL bb368e271e24f63078129283148ce83db6b9670a
4146
WORKDIR /occt/
4247
RUN \
43-
curl "https://git.dev.opencascade.org/gitweb/?p=occt.git;a=snapshot;h=${OCCT_COMMIT_HASH_FULL};sf=tgz" -o occt.tar.gz && \
44-
tar -xvf occt.tar.gz && \
45-
export OCCT_COMMIT_HASH=$(echo ${OCCT_COMMIT_HASH_FULL} | cut -c 1-7) && \
46-
mv occt-$OCCT_COMMIT_HASH/* . && \
47-
mv occt-$OCCT_COMMIT_HASH/.* . || true && \
48-
rm occt-$OCCT_COMMIT_HASH -r
48+
git clone https://github.com/Open-Cascade-SAS/OCCT.git . && \
49+
git checkout 48ebca0f70a5e4b936548b695bc3583363898da4
4950

51+
# Copy the build system
5052
WORKDIR /opencascade.js/
5153
COPY src ./src
52-
WORKDIR /src/
54+
COPY build-configs ./build-configs
55+
COPY build-wasm.sh ./build-wasm.sh
56+
COPY DEPS.json ./DEPS.json
57+
RUN chmod +x build-wasm.sh
5358

54-
ARG threading=single-threaded
55-
ENV threading=$threading
59+
# Set default environment
60+
ENV OCCT_ROOT=/occt
61+
ENV RAPIDJSON_ROOT=/rapidjson
62+
ENV FREETYPE_ROOT=/freetype
63+
ENV THREADING=single-threaded
64+
ENV OCJS_OPT=-O2
65+
ENV OCJS_LTO=0
66+
ENV OCJS_EXCEPTIONS=0
5667

57-
FROM base-image AS test-image
58-
59-
RUN \
60-
mkdir /opencascade.js/build/ && \
61-
mkdir /opencascade.js/dist/ && \
62-
/opencascade.js/src/applyPatches.py
68+
RUN mkdir -p build/bindings build/sources build/dist /output
6369

64-
ENTRYPOINT ["/opencascade.js/src/buildFromYaml.py"]
65-
66-
FROM test-image AS custom-build-image
67-
68-
RUN \
69-
/opencascade.js/src/generateBindings.py && \
70-
/opencascade.js/src/compileBindings.py ${threading} && \
71-
/opencascade.js/src/compileSources.py ${threading} && \
72-
chmod -R 777 /opencascade.js/ && \
73-
chmod -R 777 /occt
70+
# Apply patches and generate bindings (shared across all builds)
71+
RUN python3 src/applyPatches.py && \
72+
python3 -c "\
73+
import sys; sys.path.insert(0, 'src'); \
74+
from Common import buildFlatIncludes, buildPch; \
75+
buildFlatIncludes(); \
76+
buildPch(threading='single-threaded')" && \
77+
python3 src/generateBindings.py
7478

75-
ENTRYPOINT ["/opencascade.js/src/buildFromYaml.py"]
79+
ENTRYPOINT ["/opencascade.js/build-wasm.sh"]
80+
CMD ["full", "build-configs/full.yml"]

README.md

Lines changed: 135 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
[![Build OpenCascade.js](https://github.com/donalffons/opencascade.js/actions/workflows/buildFull.yml/badge.svg?event=workflow_dispatch)](https://github.com/donalffons/opencascade.js/actions/workflows/buildFull.yml)
2-
![OpenCascade Version](https://img.shields.io/badge/OpenCascade%20Version-7.6.2-green.svg)
3-
41
<p align="center">
52
<img src="https://github.com/donalffons/opencascade.js/raw/master/images/logo.svg" alt="Logo" width="50%">
63

@@ -20,14 +17,141 @@
2017
</p>
2118
</p>
2219

23-
# Projects & Examples:
20+
## What's New in V8
21+
22+
- **OCCT 8.0.0-RC4** — 1,085 commits of improvements, 22-31% faster boolean operations
23+
- **Emscripten 5.0.1** — LLVM 17, modern WASM features
24+
- **Native WASM Exceptions** — replaces JS invoke trampolines, 39% smaller exception builds
25+
- **Build System**`build-wasm.sh` with compilation cache, presets, and provenance tracking
26+
- **Pinned Dependencies**`DEPS.json` locks all dependency versions for reproducible builds
27+
28+
## Quick Start (Native Build)
29+
30+
Prerequisites: Python 3.10+, Git, CMake, a C++ toolchain.
31+
32+
```bash
33+
# 1. Clone opencascade.js
34+
git clone https://github.com/donalffons/opencascade.js.git
35+
cd opencascade.js
36+
37+
# 2. Install Emscripten SDK
38+
git clone https://github.com/emscripten-core/emsdk.git ../emsdk
39+
cd ../emsdk && ./emsdk install 5.0.1 && ./emsdk activate 5.0.1 && source ./emsdk_env.sh
40+
cd ../opencascade.js
41+
42+
# 3. Clone dependencies at pinned commits
43+
./scripts/clone-deps.sh
44+
45+
# 4. Install Python build dependencies
46+
pip install -r requirements.txt
47+
48+
# 5. Build WASM
49+
OCJS_LTO=0 ./build-wasm.sh full build-configs/full.yml
50+
```
51+
52+
Output files appear alongside the YAML config: `opencascade_full.wasm`, `opencascade_full.js`, `opencascade_full.d.ts`.
53+
54+
## Docker Build
55+
56+
For reproducible builds without installing dependencies locally:
57+
58+
```bash
59+
# Build the Docker image
60+
docker build -t opencascade-js .
61+
62+
# Build WASM (output mounted to ./output/)
63+
docker run --rm -v $(pwd)/output:/output opencascade-js full build-configs/full.yml
64+
65+
# Build with exceptions
66+
docker run --rm -v $(pwd)/output:/output -e OCJS_EXCEPTIONS=1 \
67+
opencascade-js full build-configs/full-exceptions.yml
68+
69+
# Build with a custom config
70+
docker run --rm \
71+
-v $(pwd)/my-config.yml:/opencascade.js/build-configs/custom.yml \
72+
-v $(pwd)/output:/output \
73+
opencascade-js full build-configs/custom.yml
74+
```
75+
76+
## Build Configuration
77+
78+
### YAML Configs
79+
80+
YAML configs define which OCCT classes are bound to JavaScript:
81+
82+
- `build-configs/full.yml` — 233 symbols, single-threaded, no exceptions
83+
- `build-configs/full-exceptions.yml` — 235 symbols, native WASM exceptions
84+
85+
See [Build Configuration Reference](docs/build-config-reference.md) for the full YAML schema.
86+
87+
### Presets
88+
89+
Presets control optimization settings separately from what to bind:
90+
91+
```bash
92+
# Balanced (recommended)
93+
./build-wasm.sh --preset O2-balanced full build-configs/full.yml
94+
95+
# Maximum performance
96+
./build-wasm.sh --preset O3-maxperf full build-configs/full.yml
97+
98+
# Minimum size
99+
./build-wasm.sh --preset Os-minsize full build-configs/full.yml
100+
101+
# Debug (fastest build)
102+
./build-wasm.sh --preset O0-debug full build-configs/full.yml
103+
```
104+
105+
### Environment Variables
106+
107+
| Variable | Default | Description |
108+
|-------------------|---------------------|-------------|
109+
| `OCJS_OPT` | `-O2` | Compile optimization level |
110+
| `OCJS_LTO` | `1` | LTO at compile time (set `0` to disable) |
111+
| `OCJS_EXCEPTIONS` | `0` | Native WASM exceptions (`1` to enable) |
112+
| `THREADING` | `single-threaded` | Threading mode |
113+
114+
## Customizing Your Build
115+
116+
Create a custom YAML config with only the symbols your application needs:
117+
118+
1. Copy `build-configs/full.yml` as a starting point
119+
2. Remove symbols you don't use from `bindings`
120+
3. Remove corresponding handle typedefs from `additionalCppCode`
121+
4. Validate: `./build-wasm.sh validate build-configs/my-config.yml`
122+
5. Build: `./build-wasm.sh link build-configs/my-config.yml`
123+
124+
Fewer symbols = smaller WASM binary. Each symbol adds ~15-25 KB.
125+
126+
## Build Commands
127+
128+
```bash
129+
./build-wasm.sh full <yaml> # Full build with cache
130+
./build-wasm.sh link <yaml> # Link only (fastest, reuses .o files)
131+
./build-wasm.sh validate <yaml> # Validate config without building
132+
./build-wasm.sh cache-list # List cached compilations
133+
./build-wasm.sh cache-gc [n] # Clean old cache entries
134+
./build-wasm.sh --help # Full usage information
135+
```
136+
137+
## Documentation
138+
139+
- [OCCT V8 Migration Guide](docs/occt-v8-migration.md) — breaking changes for upgrading from V7.6.2
140+
- [Optimization Guide](docs/optimization-guide.md) — tuning size, speed, and build time
141+
- [Build Configuration Reference](docs/build-config-reference.md) — YAML schema and customization
142+
143+
## Projects Using opencascade.js
144+
145+
- [ArchiYou](https://archiyou.com/) — Library, Code-CAD Design Tool, Community Hub
146+
- [BitByBit](https://bitbybit.dev/) — Code- & node-based CAD Design Tool
147+
- [CascadeStudio](https://github.com/zalo/CascadeStudio) — Library and Code-CAD Design Tool
148+
- [RepliCAD](https://replicad.xyz/) — Library and Code-CAD Design Tool
149+
- [Tau](https://tau.new/) — AI-native CAD platform for the web
150+
151+
## Contributing
24152

25-
* [ArchiYou](https://archiyou.com/): Library, Code-CAD Design Tool, Community Hub
26-
* [BitByBit](https://bitbybit.dev/): Code- & node-based - CAD Design Tool
27-
* [CascadeStudio](https://github.com/zalo/CascadeStudio): Library and Code-CAD Design Tool
28-
* [RepliCAD](https://replicad.xyz/): Library and Code-CAD Design Tool
29-
* [OpenCascade.js-examples](https://github.com/donalffons/opencascade.js-examples): Contains general examples on how to use the library.
153+
Contributions are welcome! See [TODO.md](TODO.md) for ideas.
30154

31-
# Contributing
155+
## License
32156

33-
Contributions are welcome! Feel free to have a look at the [todo-list](TODO.md) if you need some inspiration on what else needs to be done.
157+
See [LICENSE](LICENSE).

0 commit comments

Comments
 (0)