This commit promotes the `wasm32-wasip2` Rust target to tier 2 as proposed in rust-lang/compiler-team#760. There are two major changes in this PR: 1. The `dist-various-2` container, which already produces the other WASI targets, now has an extra target added for `wasm32-wasip2`. 2. A new `wasm-component-ld` binary is added to all host toolchains when LLD is enabled. This is the linker used for the `wasm32-wasip2` target. This new linker is added for all host toolchains to ensure that all host toolchains can produce the `wasm32-wasip2` target. This is similar to how `rust-lld` was originally included for all host toolchains to be able to produce WebAssembly output when the targets were first added. The new linker is developed [here][wasm-component-ld] and is pulled in via a crates.io-based dependency to the tree here. [wasm-component-ld]: https://github.com/bytecodealliance/wasm-component-ld |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
wasm-component-ld
This wrapper is a wrapper around the wasm-component-ld crates.io crate. That
crate. That crate is itself a thin wrapper around two pieces:
wasm-ld- the LLVM-based linker distributed as part of LLD and packaged in Rust asrust-lld.wit-component- a Rust crate for creating a WebAssembly Component from a core wasm module.
This linker is used for Rust's wasm32-wasip2 target to natively output a
component instead of a core WebAssembly module, unlike other WebAssembly
targets. If you're confused about any of this here's an FAQ-style explanation of
what's going on here:
-
What's a component? - It's a proposal to the WebAssembly standard primarily developed at this time by out-of-browser use cases of WebAssembly. You can find high-level documentation here.
-
What's WASIp2? - Not to be confused with WASIp1, WASIp0,
wasi_snapshot_preview1, orwasi_unstable, it's a version of WASI. Released in January 2024 it's the first version of WASI defined in terms of the component model. -
Why does this need its own linker? - like any target that Rust has the
wasm32-wasip2target needs a linker. What makes this different from other WebAssembly targets is that WASIp2 is defined at the component level, not core WebAssembly level. This means that filesystem functions take astringinstead ofi32 i32, for example. This means that the raw output of LLVM andwasm-ld, a core WebAssembly module, is not suitable. -
Isn't writing a linker really hard? - Generally, yes, but this linker works by first asking
wasm-ldto do all the hard work. It invokeswasm-ldand then uses the output core WebAssembly module to create a component. -
How do you create a component from a core module? - this is the purpose of the
wit-componentcrate, notably theComponentEncodertype. This uses component type information embedded in the core module and a general set of conventions/guidelines with what the core module imports/exports. A component is then hooked up to codify all of these conventions in a component itself. -
Why not require users to run
wit-componentthemselves? - while possible it adds friction to the usagewasm32-wasip2target. More importantly though the "module only" output of thewasm32-wasip2target is not ready right now. The standard library still imports fromwasi_snapshot_preview1and it will take time to migrate all usage to WASIp2. -
What exactly does this linker do? - the
wasm-component-ldhas the same CLI interface and flags aswasm-ld, plus some more that are component-specific. These flags are used to forward most flags towasm-ldto produce a core wasm module. After the core wasm module is produced thewit-componentcrate will read custom sections in the final binary which contain component type information. After merging all this type information together a component is produced which wraps the core module.
If you've got any other questions about this linker or its operation don't
hesitate to reach out to the maintainers of the wasm32-wasip2 target.