cargo-componentから脱却するには
Rust 1.82.0からwasm32-wasip2
がtier 2のターゲットとなり、rustup target add
コマンドでビルドターゲットに追加できるようになりました。
これによりcargo-component
を利用しなくても、Wasmコンポーネントを作成できるようになりました。この記事では、cargo-component
を利用してビルドしていたライブラリークレートを、cargo
コマンドだけでビルドできるようにするための変更点を述べます。
cargo-component
がビルド時にやっていたことの置き換え
cargo-component
がビルド時にやっていたのは、次の作業です:
- 必要なWITファイルの取得
- WITファイルからのコード生成
-
cargo build
の実行
cargo-component
から脱却するためには、最初の2つを手動で行う必要があります。
必要なWITファイルの取得
プロジェクトがwasi:http/proxy
のようにWargレジストリーに登録されているインターフェース定義を参照している場合、参照しているインターフェース定義を全てダウンロードする必要があります。これは、コード生成に利用するwit-bindgen
がwit
フォルダー内のWITファイルからのみコード生成を行うためです。
そのプロジェクトが参照しているインターフェース定義は、Cargo.toml
のpackage.metadata.component
セクションのtarget
属性に記述されています。次の例では、wasi:http/proxy@0.2.0
を参照しています。
この定義をwkg
コマンドを利用してダウンロードします:
# プロジェクトフォルダー直下にwitフォルダーを作成します
% mkdir wit
# WITファイルをダウンロードします
% wkg get wasi:http@0.2.0 -o wit/
# -o オプションで出力するフォルダーを指定します
# フォルダーであることを示すため、末尾に必ず/をつけます
wasi:http@0.2.0
はさまざまなWITパッケージに依存しています。コード生成には依存しているパッケージも必要なため、これらも全てwit
フォルダーにダウンロードします。
ダウンロードにはwkg wit fetch
コマンドを利用します。このコマンドはwit
フォルダーにあるWITファイルを読み、それらが依存するWITパッケージをまとめてダウンロードします:
% wkg wit fetch
wit-bindgen
を利用したコード生成
WITファイルが用意できたので、wit-bindgen
を利用してコード生成を行います。まずは依存関係にwit-bindgen
を追加します。wit-bindgen-rt
は必要なので、残しておきます:
次にsrc/lib.rs
の先頭にコード生成のためのマクロ呼び出しを追加します:
world
属性で実装するワールドを指定します。上記の例ではwasi:http/proxy@0.2.0
を指定しています。また、指定したワールドが依存する他のインターフェースのコードも併せて生成するために、generate_all
フラグを追加しています。
bindings::export
マクロの置き換え
コード生成をwit_bindgen::generate
マクロで行うように変更したため、bindings
モジュールが生成されなくなりました。その結果、コンポーネントの実装を指定してたbindings::export
マクロが利用できなくなりました。
これを置き換えるのが、export
マクロです。これはwit_bindgen::generate
マクロによって生成されるため、use
句でネームスペースにシンボルを追加しなくても利用できます。コンポーネントの実装の指定は、次のように行います:
ビルド
次のようにcargo build
コマンドでビルドできます:
% cargo component build --target wasm32-wasip2
# 依存するクレートをビルドするメッセージが表示されますが、省略します
Finished `dev` profile [unoptimized + debuginfo] target(s) in 20.36s
ビルドにはwasm32-wasip2
がビルドターゲットに追加されている必要があります。rustup target add
コマンドで追加できます:
% rustup target add wasm32-wasip2
Cargo.toml
から不要な記述を削除
cargo-component
はCargo.toml
にいくつかの記述を追加します。前述した実装するワールドの指定もそのひとつです。これらの記述を残したままでも問題はありませんが、わかりやすさのため削除しても良いでしょう。
package.metadata.compoent
セクションを削除することで、Cargo.toml
からcargo-component
特有の記述を削除できます。
まとめと感想
cargo-component
の脱却には、次の2つの作業とそれに伴う細かな修正が必要でした:
- 必要なWITファイルの取得
-
wit_bindgen::generate
マクロへの置き換え
WITファイルの取得を自動化しているcargo-component
便利だなというのが、実際にやってみての感想です。上記は1度やってしまえば、インターフェースの変更がない限りする必要のない作業です。インターフェースが固まっている場合は、手動でやったとしても手間が少ないように感じました。
一方で、インターフェースが固まっていない時は手間が多いかもしれません。また作業自体を忘れてしまった結果、インターフェース定義と実装が食い違うといったことも起きそうです。
またWASIのバージョンアップに追随するときにも、作業忘れによる問題もおきるように思いました。インターフェースの変更は頻繁に起こるものではありません。だからこそ、より一層自動化が必要なようにも思いました。
Discussion