WASI の拡張である WASIX を使った WebAssembly を実行してみました。
実行には WASIX に対応した WebAssembly ランタイムが必要で、現状では Wasmer を使う事になります。
WASIX サンプル
wasix-abi-rust を参考にサンプルを作成しました。
step1
の文字列を標準出力した後、5秒スリープして step2
の文字列を出力するだけの処理内容となっています。
注意点として thread_sleep
のスリープ時間はナノ秒で指定する必要がありました。
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
fn main() -> Result<()> {
print_message("step1\n")?;
unsafe {
// 5秒スリープ
wasix::thread_sleep(5 * 1000000000)?;
}
print_message("step2\n")?;
Ok(())
}
fn print_message(msg: &str) -> Result<()> {
let d = [wasix::Ciovec {
buf: msg.as_ptr(),
buf_len: msg.len(),
}];
unsafe {
wasix::fd_write(wasix::FD_STDOUT, &d)?;
}
Ok(())
}
Cargo.toml の内容は以下のようになります。
[package]
name = "sample"
version = "0.1.0"
edition = "2021"
[dependencies]
wasix = "0.11"
実行
今回はビルド & 実行に下記を使用しました。
arm64 環境(Apple シリコン)や GLIBC のバージョン関係で上手くいかなかったりと、割と苦労する事になりました。
最終的に x86_64 環境で Ubuntu 23.04 をコンテナ実行して成功しました。
環境構築
Ubuntu をコンテナ実行
ubuntu:22.04 のコンテナイメージを使った場合、ビルド時にGLIBC_2.36 not found
エラーが発生して上手くいかなかったので 23.04 を実行します。
$ podman run -it --rm -v $(pwd):/work ubuntu:23.04 bash
以後の操作はこのコンテナで実行します。
build-essential インストール
このままだと cargo-wasix インストール時に error: linker `cc` not found
エラーで失敗するので、build-essential
をインストールしておきます。
$ apt install -y build-essential
また、Rust や Wasmer のインストールで使う場合は curl もインストールしておきます。
$ apt install -y curl
Rust インストール
Rust をインストールしておきます。
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ . ~/.cargo/env
cargo-wasix インストール
cargo-wasix をインストールする事で cargo wasix
コマンドを利用できるようになります。
$ cargo install cargo-wasix
Wasmer インストール
cargo wasix run
時に wasmer コマンドが見つからないと failed to find `wasmer` in $PATH
というエラーで失敗するので wasmer をインストールしておきます。
$ curl https://get.wasmer.io -sSfL | sh
$ . ~/.wasmer/wasmer.sh
サンプルの実行
これで環境が整いましたので、cargo wasix run
でビルド & 実行します。
step1 の出力後、5秒程度経ってから step2 が出力されたので、とりあえずは正常に動作したようです。
$ cd /work
$ cargo wasix run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `/root/.cargo/bin/cargo-wasix target/wasm32-wasmer-wasi/debug/sample.wasm`
info: Post-processing WebAssembly files
Running `target/wasm32-wasmer-wasi/debug/sample.wasm`
step1
step2