1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle Linux で WebAssembly(Wasm)を動かしてみた 〜Rust編〜

1
Posted at

はじめに

前回は Go で Wasm を動かしました。今回は Rust で同じことをやってみます。

Rust は WebAssembly との相性が非常に良く、公式でも積極的にサポートされています。
Go 編と比較しながら読んでいただくと、WASI の理解がより深まると思います。

環境

  • Oracle Linux 9
  • Rust(rustup でインストール)
  • Wasmtime(Wasm ランタイム)

① Rust のインストール

Rust は公式の rustup を使ってインストールします。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

インストール後、パスを通します。

source $HOME/.cargo/env

下記コマンドで確認します。

$ rustc --version
rustc 1.xx.x (xxxxxxx 20xx-xx-xx)

② Wasm ターゲットの追加

Rust で Wasm 向けバイナリを作るには、Wasm専用のビルドターゲット(どこで動かす用に作るか)という出力形式の指定を追加する必要があります。

rustup target add wasm32-wasip1

wasm32-wasip1 って・・・?

コマンド 意味
wasm32 WebAssembly(32bit)形式で出力する
wasip1 WASI Preview1 という仕様に準拠する

つまり、WASIで動くWebAssembly形式で出力するという意味になります。
Go 編での GOOS=wasip1 GOARCH=wasm と同じ意味を持ちます。

確認配下コマンドで行います。

$ rustup target list --installed
wasm32-wasip1

リストに表示されていればOKです。

③ Wasmtime のインストール

Wasmtime は .wasm ファイルを実行するためのエンジンのようなものです。

curl https://wasmtime.dev/install.sh -sSf | bash

すぐ使いたい場合はパスを手動で通します。(私は通します)

export PATH="$HOME/.wasmtime/bin:$PATH"

確認は下記コマンドでします。

$ wasmtime --version
wasmtime 42.0.0 (aa3cfe72f 2026-02-24)

④ プロジェクトを作成する

Cargo(Rust のパッケージマネージャ)でプロジェクトを作成します。

cargo new hello_wasi
cd hello_wasi

ディレクトリ構成は下記のようになっているはずです。

hello_wasi/
├── Cargo.toml
└── src/
    └── main.rs

⑤ Rust・WASI・Wasmtime の関係を理解する

コードを書く前に、登場人物の関係を整理しておきます。
ここを理解しておくと、後でエラーが出たときに原因が即座にわかります。

まとめると、それぞれの役割はこうなります。

レイヤー 役割 今回の該当
Rust ソースコード 「何をしたいか」を書く src/main.rs
WASI Wasmが外部とやり取りするためのインタフェース wasm32-wasip1
Wasm バイナリ WASI 仕様に沿って作られた実行ファイル hello_wasi.wasm
Wasmtime Wasm を受け取り、WASI の命令を OS に橋渡しするエンジン wasmtime コマンド

⑥ Hello World を動かす

src/main.rs を以下の内容にします。

fn main() {
    println!("Hello from Rust WASM!");
}

ビルドは下記コマンドで行います。

cargo build --target wasm32-wasip1 --release

実行します。

wasmtime target/wasm32-wasip1/release/hello_wasi.wasm

出力:

Hello from Rust WASM!

Rust で書いたコードが、Linux のネイティブバイナリではなく Wasm として実行されています。
cargo build--target wasm32-wasip1 を渡すだけで出力先が .wasm に切り替わる点が Rust のシンプルなところです。

Go の場合は環境変数を2つ並べる必要がありましたが、Rust はオプション1つで済みます。

⑦ ファイル読み込みを試す

次に、テキストファイルを読み込む処理を追加します。
ここから WASI のサンドボックスと向き合う場面になります。

src/main.rs を書き換えます。

use std::fs;

fn main() {
    let data = fs::read_to_string("test.txt").expect("ファイルが読めませんでした");
    println!("{}", data);
}

読み込む用のファイルを作成します。

echo "WASI is cool" > test.txt

ビルドしていきます。

cargo build --target wasm32-wasip1 --release

下記でそのまま実行してみます。

wasmtime target/wasm32-wasip1/release/hello_wasi.wasm

出力結果

thread 'main' panicked at 'ファイルが読めませんでした: ...'

エラーになります。コードに間違いはありません。

これは Wasm のセキュリティモデルとして、サンドボックスとして動くためです。
悪意のあるコードがシステム上のファイルを勝手に読み書きできないよう、 アクセスできるリソースをすべて実行者が明示的に許可する設計になっています。

--dir でディレクトリを許可する

解決方法は、実行時に --dir オプションでアクセスを許可することです:

wasmtime --dir=. target/wasm32-wasip1/release/hello_wasi.wasm

--dir=. の意味は「カレントディレクトリ(.)を Wasm に見せることを許可する」です。

出力は下記のようになります。

WASI is cool

--dir は複数指定することもできます。たとえば /data/config を別々に許可するといった細かい制御が可能です。

⑩ Go 編との比較

Go Rust
ビルドコマンド GOOS=wasip1 GOARCH=wasm go build cargo build --target wasm32-wasip1
ターゲット指定 環境変数で指定 --target オプションで指定
ファイルアクセス --dir=. が必要 --dir=. が必要
出力ファイル main.wasm target/wasm32-wasip1/release/xxx.wasm

ファイルアクセスの制限は言語に関係なく WASI の仕様なので、Go でも Rust でも同じ --dir=. が必要になります。言語が違っても同じ制限にぶつかる、これが WASI の「標準化」としての意味です。

まとめ

ステップ コマンド
Rust インストール curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Wasm ターゲット追加 rustup target add wasm32-wasip1
Wasm ビルド cargo build --target wasm32-wasip1 --release
実行(基本) wasmtime target/wasm32-wasip1/release/hello_wasi.wasm
実行(ファイルアクセスあり) wasmtime --dir=. target/wasm32-wasip1/release/hello_wasi.wasm

Rust のコードは普通の Rust のまま書けばよく、「WASI 向けに何か特別な書き方をする」必要はありません。WASI を意識するのはビルド時のターゲット指定と、実行時の --dir オプションだけです。この分離がうまく設計されているおかげで、既存の Rust コードを Wasm に移植するコストが低く抑えられています。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?