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