wasm32-wasip1-threads
层级: 2
wasm32-wasip1-threads
目标是一个新的,并且仍然(截至 2023 年 7 月)是实验性的目标。此目标是 wasm32-wasip1
目标的扩展,最初称为 wasm32-wasi
。它通过一组标准化的系统调用扩展了原始目标,这些系统调用旨在为 WebAssembly 二进制文件提供本机多线程功能。
注意:在 2024 年 3 月之前,此目标被称为
wasm32-wasi-preview1-threads
,更早之前它被称为wasm32-wasi-threads
。
目标维护者
- Georgii Rylov,https://github.com/g0djan
- Alex Crichton,https://github.com/alexcrichton
- Andrew Brown,https://github.com/abrown
- Marcin Kolny,https://github.com/loganek
要求
此目标是交叉编译的。该目标完全支持 std
。
此处的 Rust 目标定义在几个方面很有趣。我们希望通过此目标满足两个用例。
- 首先,我们希望 Rust 使用该目标尽可能地轻松,理想情况下避免需要配置和安装本地 wasm32-wasip1-threads 工具链。
- 其次,LLVM 新的 wasm 后端和 LLD 中的 wasm 支持的主要用例之一是,任何编译语言都可以与任何其他语言互操作。
wasm32-wasip1-threads
目标是第一个具有可行的 C 标准库和 sysroot 通用定义的目标,因此我们希望 Rust 和 C/C++ 代码在编译为wasm32-unknown-unknown
时能够互操作。
但是,您会注意到,上面提到的两个目标在某种程度上是相互矛盾的。为了尝试一次性解决这两个用例,我们定义了一个目标,它(滥用)了 crt-static
目标功能来指示您处于哪种情况。
不需要与 C 互操作
默认情况下,crt-static
目标功能是启用的,启用后,这意味着将使用 liblibc.rlib
中找到的 libc.a
的捆绑版本。这实际上并非旨在用于与 C 互操作,因为 Rust 的捆绑 C 库可能与外部编译的 C 库不兼容。但是,在此用例中,我们使用 rust-lld
和一些复制的 crt 启动对象文件,以确保您可以下载 Rust 的 wasi 目标,并且您就可以开始使用,无需进一步配置。总而言之,默认情况下,不需要外部依赖项。您可以直接从盒子里编译 wasm32-wasip1-threads
二进制文件。但是,您无法在此模式下可靠地与 C 代码互操作(尚未)。
需要与 C 互操作
对于第二个目标,我们重新利用了 target-feature
标志,这意味着您需要做一些事情才能使 C/Rust 代码互操作。
- 所有 Rust 代码都需要使用
-C target-feature=-crt-static
进行编译,这表明不会使用 Rust sysroot 中捆绑的 C 标准库。 - 如果您使用 rustc 构建链接的工件,那么您需要将
-C linker
指定为支持wasm32-wasip1-threads
并且已配置了wasm32-wasip1-threads
sysroot 的clang
二进制文件。这将导致 Rust 代码与指定的clang
提供的 libc.a 链接。 - 如果您正在构建静态库并在其他地方集成 Rust 代码,那么使用
-C target-feature=-crt-static
进行编译就是您需要做的全部工作。
总而言之,默认情况下,不需要外部依赖项。您可以直接从盒子里编译 wasm32-wasip1-threads
二进制文件。但是,您无法在此模式下可靠地与 C 代码互操作(尚未)。
还要注意,目前 wasm32-wasip1-threads
目标假设存在其他合并的 wasm 提案,例如(及其 LLVM 特性标志):
- 批量内存 -
+bulk-memory
- 可变导入全局变量 -
+mutable-globals
- 原子操作 -
+atomics
此目标需要 LLVM 16。原因与链接器标志有关:在 LLVM 16 之前,不允许同时使用 --import-memory 和 --export-memory。两者都需要的原因是 WASI 当前做事方式的产物;有关更多详细信息,请参见 https://github.com/WebAssembly/WASI/issues/502。
该目标旨在与其 "C"
ABI 的相应 Clang 目标匹配。
注意:由于此目标处于相对早期的阶段,因此在使用此目标时,您可能会遇到 LLVM 错误。如果遇到断言命中或发现错误,建议您在 rust-lang/rust 或理想情况下在 LLVM 本身中打开一个问题。
平台要求
运行时应支持与任何其他支持的 wasi 目标相同的 API 集,以通过 WASI 标准与主机环境进行交互。运行时还应实现 wasi-threads 提案。
此目标不是稳定目标。这意味着有一些引擎实现了 wasi-threads
功能,如果它们确实实现了,则可能位于标志后面,例如
- Wasmtime -
--wasm-features=threads --wasi-modules=experimental-wasi-threads
- WAMR - 需要使用 WAMR_BUILD_LIB_WASI_THREADS=1 构建
构建目标
用户需要安装或构建 wasi-sdk,版本为 20.0 或更高,https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-20,并指定 wasi-root 的路径到 .cargo/config.toml
[target.wasm32-wasip1-threads]
wasi-root = ".../wasi-libc/sysroot"
之后,用户可以通过将其添加到 config.toml
中的 target
列表中,或使用 -Zbuild-std
来构建它。
构建 Rust 程序
从 Rust Nightly 1.71.1(2023-08-03)开始,工件已预编译。
rustup target add wasm32-wasip1-threads --toolchain nightly
可以为该目标构建 Rust 程序。
rustc --target wasm32-wasip1-threads your-code.rs
交叉编译
此目标可以从任何主机交叉编译。
测试
目前,wasm32-wasip1-threads
的测试支持度不高,Rust 项目没有针对此目标运行任何测试。但是,可以按照以下说明手动运行 UI 测试套件。
- 确保已安装 wamr、wasmtime 或其他支持
wasi-threads
的引擎,并且可以在$PATH
环境变量中找到它。 - 克隆主分支。
- 应用此类 更改,并使用步骤 1 中的引擎。
- 运行
./x.py test --target wasm32-wasip1-threads tests/ui
并保存失败测试的列表。 - 检出包含您更改的分支。
- 应用此类 更改,并使用步骤 1 中的引擎。
- 运行
./x.py test --target wasm32-wasip1-threads tests/ui
并保存失败测试的列表。 - 对于两个失败测试列表,运行
cat list | sort > sorted_list
并使用diff sorted_list1 sorted_list2
进行比较。