🐕

cargo-component と wasmtime の互換性が壊れた時の対処

2023/09/01に公開

以下のようなエラーが出た場合の対処について:

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つを実行する。
    1. cargo build --target wasm32-wasi を実行する。
    2. できあがった 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