简介
今年四月,我们在 Rust 的主博客上发布了关于 Rust WASI 目标 的更新。其中我们介绍了将 wasm32-wasi
目标重命名为 wasm32-wasip1
,以及引入新的 wasm32-wasip2
目标作为“tier 3”目标。这意味着虽然该目标作为 rust-lang/rustc
的一部分可用,但不能保证构建成功。我们很高兴地宣布,这种情况在 Rust 1.82 中发生了改变。
对于那些不熟悉 WebAssembly (Wasm) 组件和 WASI 0.2 的人,这里有一个快速、简化的入门介绍
- Wasm 是用于将程序编译成(类似于 x86)的(虚拟)指令格式。
- Wasm 组件 是容器格式和类型系统,它将核心 Wasm 指令包装成类型化的、封闭的二进制文件和库(类似于 ELF)。
- WASI 是为一组标准化的 Wasm 组件接口保留的命名空间(类似于 POSIX 头文件)。
有关更详细的解释,请参阅 Bytecode Alliance 博客上的 WASI 0.2 公告帖子。
新特性?
从 Rust 1.82 (2024-10-17) 开始,wasm32-wasip2
(WASI 0.2) 目标在 Rust 编译器中已达到 tier-2 平台支持。 除此之外,这意味着现在保证可以构建成功,并且现在可以使用以下命令通过 Rustup 安装
rustup target add wasm32-wasip2
到目前为止,编写 Wasm 组件 的 Rust 用户始终必须依赖于工具(例如 cargo-component),这些工具以 WASI 0.1 目标 (wasm32-wasip1
) 为目标,并通过调用的后处理步骤将其打包到 WASI 0.2 组件中。 既然 wasm32-wasip2
可以通过 Rustup 提供给所有人,工具可以开始直接以 WASI 0.2 为目标,而无需额外的后处理。
这也意味着生态系统 crates 可以开始直接以 WASI 0.2 为目标编写特定于平台的代码。WASI 0.1 不支持套接字。 既然我们现在拥有稳定的 tier 2 平台,crate 作者应该终于可以开始编写与 WASI 兼容的网络代码了。 要从 Rust 以 WASI 0.2 为目标,作者可以使用以下 cfg
属性
#[cfg(all(target_os = "wasi", target_env = "p2"))]
mod wasip2 {
// items go here
}
要以较旧的 WASI 0.1 目标为目标,Rust 也接受 target_env = "p1"
。
标准库支持
WASI 0.2 Rust 目标达到 tier 2 平台支持在某种程度上只是一个开始。这意味着它受到支持并且是稳定的。 虽然平台本身现在是稳定的,但 stdlib 对 WASI 0.2 API 的支持仍然有限。 虽然 WASI 0.2 规范指定了定时器、文件和套接字等 API,但如果您今天尝试使用这些 stdlib API,您会发现它们还不起作用。
我们希望在今年剩余时间和明年逐步扩展 Rust stdlib,以支持 WASI 0.2 API。 这项工作已经开始,rust-lang/rust#129638 在 Rust 1.83 中增加了对 std::net
的原生支持。 我们预计今年剩余时间将会有更多此类 PR 落地。
但这并不需要阻止用户今天使用 WASI 0.2。 stdlib 非常棒,因为它提供了可移植的抽象,通常建立在操作系统的 libc
或等效之上。 如果您今天想直接使用 WASI 0.2 API,您可以直接使用 wasi crate。 或者使用 wit-bindgen 从 WASI 规范的接口类型生成您自己的 WASI 绑定。
结论
wasm32-wasip2
目标现在可以通过 Rustup 安装。 这使得 Rust 编译器可以直接编译到以 WASI 0.2 接口为目标的 Wasm 组件格式。 现在还可以通过编写以下代码,让 crates 编译添加 WASI 0.2 平台支持
#[cfg(all(target_os = "wasi", target_env = "p2"))]
mod wasip2 {}
我们很高兴 Wasm 组件和 WASI 0.2 在 Rust 项目中达到了这一里程碑,并且很高兴看到社区中的人们将用它构建什么!