OpenCascade.js

Custom emcc flags

Link-time emscripten flags — SIMD, exceptions, BigInt, EVAL_CTORS, optimisation level, environment.

Once your YAML symbol list is right, the second knob is emccFlags. Use it to tune optimisation level, exception model, SIMD, and target environments.

mainBuild:
  emccFlags:
    - -O3
    - -fwasm-exceptions      # native wasm exceptions; faster than JS exceptions
    - -msimd128              # baseline SIMD (Safari + everyone else)
    - -sWASM_BIGINT          # i64 stays as BigInt, no legalisation glue
    - -sEVAL_CTORS=2         # static-init evaluation at build time
    - -sMODULARIZE=1         # init() returns Promise<Module>
    - -sEXPORT_ES6=1         # ESM output
    - -sENVIRONMENT=web,worker,node
    - -sALLOW_MEMORY_GROWTH=1
    - -sMAXIMUM_MEMORY=4GB   # wasm32 ceiling

Flag-by-flag rationale

FlagWhy
-O3Full LLVM optimisation. -Os is ~5% smaller, ~10% slower at runtime. -O0 for debugging only.
-fwasm-exceptionsUses Wasm try_table. ~5–10% smaller and faster than -fexceptions (JS-based) when supported (every modern engine).
-msimd128Baseline SIMD. ~15% perf win on mesh and boolean kernels. Safari-compatible.
-mrelaxed-simdChrome/Firefox-only additional SIMD ops. Adds another ~5% perf but breaks Safari — only ship if you can fall back.
-sWASM_BIGINTRemoves the i64↔i32-pair shim. Saves ~30 KB JS glue.
-sEVAL_CTORS=2Runs static initialisers at build time. Smaller payload + faster startup.
-sMODULARIZE=1 -sEXPORT_ES6=1Required for import init from '...'.
-sENVIRONMENT=web,worker,nodeStrips dead env detection. Without this the runtime probes for process/window/importScripts.
-sALLOW_MEMORY_GROWTH=1Required for any non-trivial geometry — initial 16 MB heap is not enough.
-sMAXIMUM_MEMORY=4GBwasm32 hard ceiling (2³² bytes).

Trade-offs

Wasm exceptions vs JS exceptions

-fwasm-exceptions requires that all .o files AND the linker use the flag consistently. Mixed builds produce __cpp_exception as an unresolved import at link time. The default OCJS build sets OCJS_EXCEPTIONS=1 everywhere; only override if you have a very narrow constraint (e.g. a wasm engine without try_table support).

SIMD: baseline vs relaxed

Browsers diverged. Baseline -msimd128 is universal. Relaxed-SIMD (-mrelaxed-simd) is Chrome + Firefox at the time of writing — Safari (as of 26.x) refuses to parse the relaxed opcodes and the wasm module fails to instantiate. Ship relaxed-SIMD only if you maintain a fallback baseline build.

EVAL_CTORS levels

LevelBehaviour
0Off — every static init runs at startup
1Eval ctors with safe side effects
2Recommended — full ctor evaluation, requires -O2+

EVAL_CTORS=2 is the OCJS shipped default and the right answer almost always.

The wasm bitwidth (wasm32 vs wasm64), the C++ stdlib version, the OCCT commit pin, and the libclang version are all baked in during the bindgen pipeline that produces the published Docker image. Customise via a fork of the Docker image if you need any of those.

On this page