# pyemscripten_2026_5

By default, all builds of the Pyodide runtime with Python 3.15 use the
`pyemscripten_2026_5` platform.

This section reflects the planned definition for the `pyemscripten_2026_5`
platform.

## Platform Specification

### CPython and Emscripten Version

- **CPython**: 3.15
- **Emscripten**: 6.0.5

### Unwinding ABIs

C++ libraries are built with WebAssembly exception handling (`-fwasm-exceptions`)
and WebAssembly-based `setjmp`/`longjmp` (`-sSUPPORT_LONGJMP=wasm`). To enable
exceptions and `setjmp`/`longjmp`, `-fwasm-exceptions` must be passed at compile
time and link time.

### Rust Toolchain

When building Rust packages to target the `pyemscripten_2026_5` platform, use
Rust version 1.93.0 or later. As of writing this, we default to Rust 1.97.1.

### Runtime Library Loading Path

There is full support for `RPATH`. The dynamic loader will only load
dependencies that are properly specified on the `RPATH`, just being in
`/lib/python3.15/site-packages/wheel_name.libs` is not sufficient.

### Libraries Linked to the Main Binary

The following libraries are statically linked to the binary:

- `libegl.js`
- `libeventloop.js`
- `libGL`
- `libhtml5_webgl.js`
- `libhtml5.js`
- `liblz4`
- `libsdl.js`
- `libwebgl.js`
- `libwebsocket.js`
- `bzip2`
- `zlib`
- `sqlite3` version 3.39.0
- `lzma` (xz) version 5.2.2

Aside from `sqlite3` and `lzma`, these libraries come from Emscripten ports and
the versions of the libraries are determined by the version of Emscripten we
build with. Any symbols from these static libraries may be used by shared
libraries.

## Changes from pyemscripten_2026_0

The only change from `pyemscripten_2026_0` to `pyemscripten_2026_5` is that
Emscripten was upgraded from **5.0.3** to **6.0.5**.

## Migration Notes

There are three changes in Emscripten 6.0.5 that may cause trouble building Python packages.

### `-shared` links a real dynamic library instead of a static library

Until Emscripten 6.0.0, the `-shared` flag was not really respected, and passing it would
generate a `.so` file that was actually a static archive. This difference in behavior can
lead to differences in linking behavior. Generally this shows up when running `configure`.
Pass `-sFAKE_DYLIBS` as an ldflag to opt into the old behavior of ignoring `-shared`.

### OpenMP Supported by Emscripten 6.0.5 but not by Pyodide

OpenMP is supported by Emscripten 6.0.5 but it requires pthreads. (On the other
hand, `-fopenmp-simd` works fine.) Pyodide's compiler and linker wrapper will
exit with a nonzero status code if `-fopenmp` or related flags are passed, but
if emcc is invoked directly it will successfully link a shared library that can
only be loaded by a pthreads-enabled binary.

### Bug involving C++ exceptions in optimizing builds with dwarf symbols

A program with C++ exceptions and dwarf symbols may crash in wasm-opt with a message like:
```
wasm-opt: wasm-debug.cpp:439: void wasm::Debug::AddrExprMap::add(Expression *, const BinaryLocations::Span): Assertion `!endMap.contains(span.end)' failed.
```
To work around this, disable dwarf.

https://github.com/emscripten-core/emscripten/issues/27449
