Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 26 additions & 43 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@
This repository contains low-level Rust bindings to WASI APIs which are
distributed and published to crates on crates.io. Crates currently are:

* `wasi` - this is a reexport of the latest stable WASI proposal. At this time
this represents bindings to WASIp2.
* [`wasip2`](./crates/wasip2) - this crate explicitly contains bindings for the
latest stable WASIp2 release generated by the latest stable `wit-bindgen`
release.
* [`wasip1`](./crates/wasip1) - this crate explicitly contains bindings for the
WASIp1 snapshot. Development of the WASIp1 version of the standard has ceased
and this crate is in maintenance mode.
* [`wasi`](https://crates.io/crates/wasi) - this is a reexport of the latest
stable WASI proposal. At this time this represents bindings to WASIp2.
* [`wasip1`](https://crates.io/crates/wasip1) - this crate explicitly contains
bindings for the WASIp1 snapshot. Development of the WASIp1 version of the
standard has ceased and this crate is in maintenance mode.
* [`wasip2`](https://crates.io/crates/wasip2) - this crate explicitly contains
bindings for the latest stable WASIp2 release generated by the latest stable
`wit-bindgen` release.
* [`wasip3`](https://crates.io/crates/wasip3) - contains the latest snapshot of
the WASIp3 APIs using the latest `wit-bindgen`.

## The `wasi` crate

Expand All @@ -44,41 +46,22 @@ WASI standard it contains bindings for. This metadata is purely informational
and cannot be used to constrain a version requirement in Cargo. This scheme
is mirrored for the `wasip2` crate as well, for example.

## WASIp2 vs WASIp1

In January 2024 the WASI subgroup published WASI 0.2.0, colloquially known as
"WASIp2". Around the same time the subgroup additionally decided to name the
previous iteration of WASI as "WASIp1", historically known as "WASI preview1".
This now-historical snapshot of WASI was defined with an entirely different set
of primitives and worked very differently. The interface of the `wasip1` and
`wasip2` crates are entirely different and the `wasi` crate umbrella no longer
reexports `wasip1`.

## Should I use WASIp1 or WASIp2?

This is a bit of a nuanced question/answer but the short answer is to probably
use the latest release of `wasi` if you're unsure.

The longer-form answer of this is that it depends on the Rust targets that you
want to support. Rust WebAssembly targets include:

* `wasm32-unknown-unknown` - do not use this crate because this target indicates
that WASI is not desired.
* `wasm32-wasip1` - this target has been present in Rust for quite some time and
was previously known as `wasm32-wasi`. For this target you probably want the
`wasip1` crate.
* `wasm32-wasip2` - this target you can use either the `wasi` crate or the
`wasip2` crate depending on your use case. Using WASIp2 APIs on this target
is more appropriate than using WASIp1 APIs.

Note that if you use `wasm32-wasip1` it's not necessarily guaranteed you want
the `wasip1` crate. If your users are producing components then you probably
want the `wasip2` or `wasi` crates instead. If you don't know what your users
are producing then you should probably stick with `wasip1`.

Long story short, it's a bit complicated. We're in a development period from
WASIp2-and-beyond and things aren't going to be perfect every step of the way,
so understanding is appreciated!
## Which crate to use?

The most appropriate crate to use depends on the WebAssembly Rust target that
you're compiling with:

* `wasm32-unknown-unknown` - don't use any of these crates in this repository as
WASI is typically not intended to be used with this target.
* `wasm32-wasip1` - use the `wasip1` crate, as other crates are based on
component APIs which this target does not use.
* `wasm32-wasip2` - use the `wasip2` crate and update as-needed to newer
versions.
* `wasm32-wasip3` - use the `wasip3` crate.

For component-producing targets, for example `wasm32-wasip2` and
`wasm32-wasip3`, you can technically use any of `wasip2`, `wasip3`, or `wasi`.
It's recommended where possible to stick with the target, however.

# License

Expand Down
52 changes: 7 additions & 45 deletions crates/wasip2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,64 +46,26 @@ fn main() {
}
```

This crate can currently be used in two main ways.

- One is to use it and compile for the [`wasm32-wasip2` target] in Rust 1.82 and later.
this is the simplest approach, as all the tools needed are included in the
Rust tooling, however it doesn't yet support some of the features of the
other approaches.

- And the other way is to compile for the `wasm32-wasip1` target, and then adapt
the resulting modules into component using `wasm-tools component new`; see
the next section here for details.

[`wasm32-wasip2` target]: https://blog.rust-lang.org/2024/11/26/wasip2-tier-2.html

## Building with wasm32-wasip1

Steps to target `wasm32-wasip1` and then adapt to a component.

```
$ cargo build --target wasm32-wasip1
```

Next you'll want an "adapter" to convert the Rust standard library's usage of
`wasi_snapshot_preview1` to the component model. An example adapter can be found
from [Wasmtime's release page](https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.command.wasm).

```
$ curl -LO https://github.com/bytecodealliance/wasmtime/releases/download/v17.0.0/wasi_snapshot_preview1.command.wasm
```

Next to create a component you'll use the [`wasm-tools`] CLI to create a
component:

```
$ cargo install wasm-tools
$ wasm-tools component new target/wasm32-wasip1/debug/foo.wasm \
--adapt ./wasi_snapshot_preview1.command.wasm \
-o component.wasm
```

And finally the component can be run by a runtime that has Component Model
support, such as [Wasmtime]:
Next you can run this by [configuring a runner][runner] and using the
`wasm32-wasip2` target:

```
$ wasmtime run component.wasm
$ cargo run --target wasm32-wasip2 --config 'target."wasm32-wasip2".runner="wasmtime"'
...
Hello, world!
```

[Wasmtime]: https://github.com/bytecodealliance/wasmtime
[runner]: https://doc.rust-lang.org/cargo/reference/config.html#targettriplerunner

# Development

The bulk of the `wasip2` crate is generated by the [`wit-bindgen`] tool. The
`src/bindings.rs` file can be regenerated with:
various files can be regenerated from the root of this repository with:

```
$ ./ci/regenerate.sh
```

WASI definitions are located in the `wit` directory of this repository.
WASI definitions are located in the `wit` directory of this folder.
Currently they're copied from upstream repositories but are hoped to be better
managed in the future.
4 changes: 2 additions & 2 deletions crates/wasip3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ with the `wasm32-wasip2` target (the Rust compiler does not currently have a
# Development

The bulk of the `wasip3` crate is generated by the [`wit-bindgen`] tool. The
`src/bindings.rs` file can be regenerated with:
various files can be regenerated from the root of this repository with:

```
$ ./ci/regenerate.sh
```

WASI definitions are located in the `wit` directory of this repository.
WASI definitions are located in the `wit` directory of this folder.
Currently they're copied from upstream repositories but are hoped to be better
managed in the future.