wasm32-wasip2 目标已达到二级支持

2024 年 11 月 26 日 · Yosh Wuyts

引言

今年四月,我们在 Rust 主博客上发布了关于 Rust WASI 目标 的更新。其中涵盖了将 wasm32-wasi 目标重命名为 wasm32-wasip1,以及引入新的 wasm32-wasip2 目标作为“三级”目标。这意味着虽然该目标作为 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 编译器中达到了二级平台支持。这尤其意味着它现在保证能够构建,并且可以使用以下命令通过 Rustup 安装

rustup target add wasm32-wasip2

到目前为止,编写 Wasm 组件 的 Rust 用户总是需要依赖于针对 WASI 0.1 目标 (wasm32-wasip1) 的工具(例如 cargo-component),并通过一个后续处理步骤将其打包成 WASI 0.2 组件。现在 wasm32-wasip2 通过 Rustup 对所有人可用,工具可以直接针对 WASI 0.2,而无需额外的后续处理。

这也意味着生态系统中的 crate 可以开始直接针对 WASI 0.2 编写平台特定的代码。WASI 0.1 不支持套接字。现在我们有了一个稳定的二级平台可用,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 目标达到二级平台支持在某种程度上只是一个开始。这意味着它得到了支持并且稳定。虽然平台本身现在稳定了,但 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-bindgenWASI 规范 的接口类型生成您自己的 WASI 绑定。

结论

wasm32-wasip2 目标现在可以通过 Rustup 安装。这使得 Rust 编译器能够直接编译到针对 WASI 0.2 接口的 Wasm 组件格式。现在 crate 也可以通过编写以下内容来添加 WASI 0.2 平台支持

#[cfg(all(target_os = "wasi", target_env = "p2"))]
mod wasip2 {}

我们很高兴 Wasm 组件和 WASI 0.2 在 Rust 项目中达到了这一里程碑,并且期待看到社区中的人们将用它构建出什么!