cargo-component と wasmtime の互換性が壊れた時の対処
以下のようなエラーが出た場合の対処について:
import `wasi:io/streams` has the wrong type
Caused by:
0: instance export `write` has the wrong type
1: type mismatch with results
2: expected no `err` type
条件
- Wasm コンポーネントはcargo-component で作成した。
- WASI preview 2 を利用している。
- wasmtime を使って実行しようとした。
work around
cargo component の利用するアダプターを wasmtime のものとバージョンを揃えることで、上記のエラーは回避できる。
背景
-
cargo component build
でビルドした Rust のバイナリプロジェクトは、CLI world を実装する Wasm コンポーネントとなる。 - CLI world は Wasi preview 2 で定義された CLI 向けのインタフェース。Wasi preview 2 で定義される他のワールドに依存している。上記のエラーで参照されている
wasi:io
もその 1 つ。 - 大まかに
cargo component build
は次の2つを実行する。-
cargo build --target wasm32-wasi
を実行する。 - できあがった Wasm モジュールを再フォーマットして Wasm コンポーネントとする。
-
-
cargo build --target wasm32-wasi
でビルドした Rust のバイナリプロジェクトは、WASI preview 1 に依存する Wasm モジュールとしてビルドされる。 - WASI preiview 1 はコンポーネントモデルに非対応。cargo-component は WASI preview 1 を WASI preview 2 に変換するアダプター を挿入して、Wasm コンポーネントを作成する。
エラーの原因
cargo component の挿入するアダプターがエキスポートする関数のシグネチャーが、wasmtime の WASI preivew 2 の実装と食い違っているため。
実際の作業
wasmtime の実装を使って cargo component をカスタムビルドする。
cargo component を GitHub からダウンロード
以下のコマンドでダウンロードできる。
% git clone https://github.com/bytecodealliance/cargo-component.git
wasmtime の提供するアダプターを GitHub からダウンロード
GitHub のリリースページで配布されています。例えば、v12.0.1 のリリースページでは次の 2 つのアダプターが配布されている。
- wasi_snapshot_preview1.command.wasm
- wasi_snapshot_preview1.reactor.wasm
バイナリプロジェクトでは wasi_snapshot_preview1.command.wasm を利用します。これをダウンロードする。
wasmtime の実装するアダプターを cargo component のソースツリーへコピー
ダウンドードしたアダプターを、cargo component のソースツリーへコピーする。
cargo component は adapter フォルダー内にアダプターを格納している。adapter フォルダーは次のような構造をしている。
.
└── e250334
├── wasi_snapshot_preview1.command.wasm
└── wasi_snapshot_preview1.reactor.wasm
e250334 は、cargo conponent の参照しているアダプターのバージョンを指す。参照するバージョン番号は、build.rs に定義されている。
const WASI_ADAPTER_VERSION: &str = "e250334";
ソースコードにあるアダプターをダウンロードしたもので上書きすることが、最も安直な選択肢になるかと思う。
% cp ~/Downloads/wasi_snapshot_preview1.command.wasm cargo-component/adapters/e250334
ビルドとインストール
コピーしたら、ビルドし、インストールする。
% cd cargo-component
% cargo build -r
% cargo install
雑感
ツールを作成している Bytecode Alliance は以前、"Component Model Tooling Compatibility" という記事を公開したことがある。この記事には、互換性のあるランタイム、各種ツール、WASI preview 2 バージョンの対応表が記載されている。このページがメンテナンスされていると、助かることが多いように思う。
WASI preview 2 はひと段落してはいるようだが、ランタイムや各種ツールのアップデートは続いている。また preview 3 の議論が始まるようなので、互換性に関する情報は引き続き有用であるようにも感じる。
Discussion