pyemscripten_2025_0#
By default, all builds of the Pyodide runtime with Python 3.13 will use the
pyemscripten_2025_0 platform.
Note
Prior to PEP 783, the platform was referenced as pyodide_2025_0.
Platform Specification#
CPython and Emscripten Version#
CPython: 3.13
Emscripten: 4.0.9
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.
The flag -Z emscripten-wasm-eh must be passed to Rust. It is necessary to use
a Rust nightly after January 15th, 2025, when the -Z emscripten-wasm-eh flag
was added. All -Z flags are gated nightly-only. The -Z emscripten-wasm-eh
flag will never be stabilized but eventually it will switch to being on by
default and then be removed. See
the Rust Major Change Proposal
for more information.
The Rust sysroot#
Rust ships with an Emscripten sysroot built without the -Z emscripten-wasm-eh
flag so using the standard sysroot will lead to linker errors due to mismatched
unwinding ABIs.
Some crates can be built with
RUSTFLAGS=-Zemscripten-wasm-eh cargo build -Zbuild-std
If the crate uses panic=abort it may be possible to build with
cargo build -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort
but it won’t work with any crates that use cargo vendor and there seem to be
various bugs. Also, when building a large number of packages -Zbuild-std
inefficiently rebuilds the standard library for each crate.
If not building with -Zbuild-std, it is possible to get a compatible sysroot
from
pyodide/rust-emscripten-wasm-eh-sysroot.
This is only distributed for Rust nightly-2025-02-01. To use a different Rust
nightly, it is possible to clone the pyodide/rust-emscripten-wasm-eh-sysroot
repository and follow the instructions in the README to build a compatible
sysroot. To install the Emscripten sysroot use:
rustup toolchain install nightly-2025-02-01
TOOLCHAIN_ROOT=$(rustup run nightly-2025-02-01 rustc --print sysroot)
RUSTLIB=$TOOLCHAIN_ROOT/lib/rustlib
wget https://github.com/pyodide/rust-emscripten-wasm-eh-sysroot/releases/download/emcc-4.0.9_nightly-2025-02-01/emcc-4.0.9_nightly-2025-02-01.tar.bz2
tar -xf emcc-4.0.9_nightly-2025-02-01.tar.bz2 --directory=$RUSTLIB
Note that this is all necessary even if the crate uses -Cpanic=abort because
the Rust standard library is not built with -Cpanic=abort and so there will be
linker errors due to pulling in symbols from the standard library that use the
wrong unwinding ABI.
Rust Toolchain#
A Rust nightly after January 15th, 2025 is required, in order to use the
-Z emscripten-wasm-eh flag. The recommended toolchain is nightly-2025-02-01
if using the prebuilt sysroot from
pyodide/rust-emscripten-wasm-eh-sysroot.
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.13/site-packages/wheel_name.libs is not sufficient.
Libraries Linked to the Main Binary#
The following libraries are statically linked to the binary:
libegl.jslibeventloop.jslibGLlibhtml5_webgl.jslibhtml5.jsliblz4libsdl.jslibwebgl.jslibwebsocket.jsbzip2zlib
All of these come from Emscripten ports and the versions of these 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_2024_0#
Emscripten version#
Emscripten was upgraded from 3.1.58 to 4.0.9.
WASM_BIGINT is now the default#
In pyemscripten_2024_0, -sWASM_BIGINT had to be passed explicitly. Since
Emscripten 4.0.0, it is the default. No action is required — explicitly passing
the flag still works but is no longer necessary.
Unwinding ABI changed from JavaScript exceptions to WebAssembly exceptions#
pyemscripten_2024_0 used JavaScript-based exception handling (-fexceptions).
pyemscripten_2025_0 uses WebAssembly exception handling (-fwasm-exceptions
and -sSUPPORT_LONGJMP=wasm).
For Rust, the -Z emscripten-wasm-eh flag must now be passed to rustc, and a
compatible sysroot is required (see The Rust sysroot
above).
RPATH is now fully supported#
In pyemscripten_2024_0, RPATH was not supported and the dynamic loader used a
patched heuristic based on wheel_name.libs. In pyemscripten_2025_0, there is
full RPATH support and dependencies must be properly specified on the RPATH.