Compiling to wasm32¶
Level: 201 · working knowledge
One line: Rust 1.98.0 lists six wasm32 targets at Tier 2, and choosing one is choosing how much of std works — all of it on wasm32-wasip2, stubs that compile and then fail on wasm32-unknown-unknown, and none at all on wasm32v1-none.
Stub — an outline, not a lesson. There is no runnable example behind this page yet, so nothing on it has been through the check that backs every other claim in this library. The bullets below are the questions the finished page has to answer.
What it has to cover¶
- The six, all Tier 2 without host tools in the 1.98.0 rustc book, with what
rustc --print cfg --target …reports for each:wasm32-unknown-unknown↗ (target_os="unknown"),wasm32-wasip1↗ andwasm32-wasip2↗ (target_os="wasi",target_envp1andp2),wasm32-wasip1-threads↗,wasm32v1-none↗ (target_os="none",coreandalloconly), andwasm32-unknown-emscripten↗ — the only one of the six whose cfg sayspanic="unwind".wasm32-wasip3also exists, at Tier 3. - What
stddoes with no host. The rustc book forwasm32-unknown-unknownsaysprintln!does nothing,std::fsalways returns errors andstd::thread::spawnpanics; in 1.98.0's source,fson that target falls through to theunsupportedmodule, whose error isErrorKind::Unsupported, "operation not supported on this platform". The probe the finished page has to run: doesstd::fs::read("data.txt")compile for that target without a warning, and what does it return when the module runs? --crate-type cdylib—crate-type = ["cdylib"]↗ in Cargo — for a module that a host calls into. What does abincrate produce instead onwasm32-wasip1, and who calls it?- Linkers: the target spec names
rust-lldwith thewasm-lldflavour forwasm32-unknown-unknownandwasm32-wasip1, andwasm-component-ldforwasm32-wasip2, which the rustc book says outputs a component as opposed to a core wasm module. What is the difference a host can see? - The heap: the rustc book names
dlmallocaswasm32-unknown-unknown's default global allocator. How much of a small module is allocator, and what does swapping it change? - Binary size, as a table the finished page measures: debug against release,
opt-level = "z",lto,strip,codegen-units = 1, and thenwasm-opt↗ from Binaryen over the result.panic = "abort"is already the default on five of the six. - Features: 1.98.0's cfg for
wasm32-unknown-unknownenablesbulk-memory,multivalue,mutable-globals,nontrapping-fptoint,reference-typesandsign-ext. What happens when an older engine loads a module that uses one — the reasonwasm32v1-noneexists, which the rustc book says enables nothing past the WebAssembly Core 1.0 spec except importing and exporting mutable globals? - Conditional code: the rustc book recommends
#[cfg(all(target_family = "wasm", target_os = "unknown"))]and warns that nocfgcan tell whether the code will run on the web.
The trap it exists for¶
Picking wasm32-unknown-unknown for a program that reads files or prints, because it is the target every browser tutorial uses. It compiles cleanly. Then println! writes nowhere and std::fs returns errors at run time — the host-shaped half of std is present as stubs, so the compiler has nothing to refuse.
Where this sits¶
Targets and triples covers what a triple is and rustup target add; core, alloc and std covers the layers these targets keep or drop. This page covers only the wasm32 family and choosing among it.
See also¶
- Targets and triples — the
wasm32-unknown-unknownbullet this page expands - rustup —
rustup target add wasm32-unknown-unknownand what it installs core,allocandstd— the three layerswasm32v1-nonestops short of- Cross-compiling — the same build-link-run sequence for a microcontroller
- What the optimizer does — the size settings are optimizer settings
- Compile times — what
ltoandcodegen-units = 1cost on the other side - TOOLCHAIN.md — where targets sit among toolchains and components
If you are coming from another language¶
- C. The rustc book is blunt that
wasm32-unknown-unknownhas no equivalent in C/C++ and points C users at Emscripten or wasi-sdk. That is the same split as in Rust:wasm32-unknown-emscriptenwhen you want a POSIX-like C library emulated for you,wasm32-wasip1when the host speaks WASI. - Go.
GOOS=js GOARCH=wasmandGOOS=wasip1 GOARCH=wasmare Go's two ports (both listed bygo tool dist list, Go 1.25.5): a JavaScript host and a WASI host. Rust has the same two, plus the host-lesswasm32-unknown-unknownandwasm32v1-none, which that list has no counterpart for. - Python. There is no "compile my script to wasm" step; Python reaches wasm by compiling the interpreter, as Pyodide does through Emscripten. The target question still exists, one level down, for whoever builds that interpreter.
Po polsku¶
Rust 1.98.0 ma sześć celów wasm32 na poziomie Tier 2 i różnią się one tym, ile z std naprawdę działa. Na wasm32-unknown-unknown kod się kompiluje, ale println! nic nie wypisuje, a std::fs zawsze zwraca błąd (ErrorKind::Unsupported) — kompilator nie ma czego odrzucić, bo funkcje istnieją jako zaślepki. wasm32-wasip1 i wasm32-wasip2 zakładają gospodarza WASI z plikami i zegarem, a wasm32v1-none nie ma std wcale, tylko core i alloc. Do modułu wywoływanego z zewnątrz służy typ skrzynki cdylib, a rozmiar pliku zmniejsza się ustawieniami profilu i narzędziem wasm-opt.
Szukaj po polsku: kompilacja Rusta do WebAssembly · rozmiar pliku wasm · rust wasm32-unknown-unknown std fs · rust cdylib wasm · wasm-opt binaryen size · wasm32-wasip2 component