| # `wasm-component-ld` | |
| This wrapper is a wrapper around the [`wasm-component-ld`] crates.io 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 as `rust-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][component docs]. | |
| * **What's WASIp2?** - Not to be confused with WASIp1, WASIp0, | |
| `wasi_snapshot_preview1`, or `wasi_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-wasip2` target 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 a `string` | |
| instead of `i32 i32`, for example. This means that the raw output of LLVM and | |
| `wasm-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-ld` to do all the hard work. It invokes `wasm-ld` | |
| and 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-component`] crate, notably the `ComponentEncoder` type. 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-component` themselves?** - while possible | |
| it adds friction to the usage `wasm32-wasip2` target. More importantly though | |
| the "module only" output of the `wasm32-wasip2` target is not ready right now. | |
| The standard library still imports from `wasi_snapshot_preview1` and it will | |
| take time to migrate all usage to WASIp2. | |
| * **What exactly does this linker do?** - the `wasm-component-ld` has the same | |
| CLI interface and flags as `wasm-ld`, plus some more that are | |
| component-specific. These flags are used to forward most flags to `wasm-ld` to | |
| produce a core wasm module. After the core wasm module is produced the | |
| `wit-component` crate 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. | |
| [`wasm-component-ld`]: https://crates.io/crates/wasm-component-ld | |
| [`wit-component`]: https://crates.io/crates/wit-component | |
| [WebAssembly Component]: https://github.com/webassembly/component-model | |
| [component docs]: https://component-model.bytecodealliance.org/ |