rustでwasmを実行してみた(2)

wasm単体だとできないことが多いので、wasi-libcをインストールしてみた。

まず、githubからwasi-libcをclone。中に入ってmakeするも、「diffが無い」といったエラーが出てきたので、msys2環境にdiffをインストール。
次にmsys2のbashからだとWindowsのPATHが(何故か)見えないので、コンパイラのパスを直接指定してmake

make WASM_CC=/d/Scoop/apps/llvm/current/bin/clang.exe WASM_AR=/d/Scoop/apps/llvm/current/bin/llvm-ar.exe WASM_NM=/d/Scoop/apps/llvm/current/bin/llvm-nm.exe

でビルド、libclang_rt.builtins-wasm32.aが無いと言われたので、 jedisct1/libclang_rt.builtins-wasm32.aから拾ってきてコピー。
cのプログラムでprintfで文字列を出力するように改造

#include <stdint.h>
#include <stdio.h>
__attribute__((visibility("default")))
int add(int32_t a, int32_t b) {
    printf("hello wasi\n");
    return a + b;
}
int main() {return 0;}

int main()がないとコンパイル時に怒られるので、何もしない関数を追加。

all: wasm.wasm
wasm.wasm: wasm.o
	clang --sysroot=D:/build/wasi-libc/sysroot -L D:/build/wasi-libc/sysroot/lib/wasm32-wasi -Wl,--no-entry -Wl,--export-dynamic --target=wasm32-wasi -o wasm.wasm wasm.o
wasm.o: wasm.c
	clang --sysroot=D:/build/wasi-libc/sysroot --target=wasm32-wasi -c wasm.c -o wasm.o

makefileも修正。ビルドしたwasi-libcを使うようにした。
さらにrust側も修正。wasmer-wasiをdependenciesに追加した上で

extern crate wasmer;
use wasmer::{Store, Module, Instance, Value};
use wasmer_wasi::WasiState;
fn main() {
    // wasmファイル実行準備
    let store = Store::default();
    let module = Module::from_file(&store, "wasm.wasm").unwrap();
    let mut wasi_env = WasiState::new("wasi.wasi").finalize().unwrap();
    let import_object = wasi_env.import_object(&module).unwrap();
    let instance = Instance::new(&module, &import_object).unwrap();
    wasi_env.set_memory(instance.exports.get_memory("memory").unwrap().clone());
    let add = instance.exports.get_function("add").unwrap();
    // wasmの関数実行
    let response = add.call(&[Value::I32(1), Value::I32(2)]).unwrap();
    println!("1 + 2 = {}", response[0].to_string().parse::<i32>().unwrap());
}

wasmer-wasiを使ってwasi用のimport_objectを作るように修正。あとファイルの読み込みも修正してmoduleの作り方を変更。
実行結果は

PS wasm_rt> cargo run
   Compiling wasm_rt v0.1.0 (wasm_rt)
    Finished dev [unoptimized + debuginfo] target(s) in 5.96s
     Running `target\debug\wasm_rt.exe`
hello wasi
1 + 2 = 3

どうやらwasmのprintfが動いたようだ。
これ、他のライブラリも–target指定してstaticライブラリにしたものをリンクすれば動くのかな。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です