Rollup merge of #126967 - alexcrichton:wasm32-wasip2-tier-2, r=Mark-Simulacrum

Promote the `wasm32-wasip2` target to Tier 2

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
This commit is contained in:
Trevor Gross 2024-07-16 16:15:15 -05:00 committed by GitHub
commit 4e4fa7eb37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 264 additions and 3 deletions

View file

@ -95,7 +95,12 @@ const EXCEPTIONS: ExceptionList = &[
("self_cell", "Apache-2.0"), // rustc (fluent translations)
("snap", "BSD-3-Clause"), // rustc
("wasm-encoder", "Apache-2.0 WITH LLVM-exception"), // rustc
("wasm-metadata", "Apache-2.0 WITH LLVM-exception"), // rustc
("wasmparser", "Apache-2.0 WITH LLVM-exception"), // rustc
("wast", "Apache-2.0 WITH LLVM-exception"), // rustc
("wat", "Apache-2.0 WITH LLVM-exception"), // rustc
("wit-component", "Apache-2.0 WITH LLVM-exception"), // rustc
("wit-parser", "Apache-2.0 WITH LLVM-exception"), // rustc
// tidy-alphabetical-end
];

View file

@ -0,0 +1,13 @@
# See the `README.md` in this directory for what this tool is.
[package]
name = "wasm-component-ld-wrapper"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "wasm-component-ld"
path = "src/main.rs"
[dependencies]
wasm-component-ld = "0.5.4"

View file

@ -0,0 +1,62 @@
# `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 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/

View file

@ -0,0 +1,9 @@
// See the `README.md` in this directory for what this tool is.
// The source for this crate lives at
// https://github.com/bytecodealliance/wasm-component-ld and the binary is
// independently used in other projects such as `wasi-sdk` so the `main`
// function is just reexported here to delegate. A Cargo dependency is used to
// facilitate version management in the Rust repository and work well with
// vendored/offline builds.
use wasm_component_ld::main;