🍉
WasmtimeでZigのプログラムを動かしてみる
WASIでWASMを動かすのが気になってきたので。
Wasmtimeのインストール
こちらのページを見ながら
curl https://wasmtime.dev/install.sh -sSf | bash
source ~/.bashrc
$ which wasmtime
/home/koba/.wasmtime/bin/wasmtime
$ wasmtime
wasmtime-cli 9.0.3
Wasmtime WebAssembly Runtime
USAGE:
wasmtime <SUBCOMMAND>
OPTIONS:
-h, --help Print help information
-V, --version Print version information
SUBCOMMANDS:
compile Compiles a WebAssembly module
config Controls Wasmtime configuration settings
explore Explore the compilation of a WebAssembly module to native code
help Print this message or the help of the given subcommand(s)
run Runs a WebAssembly module
settings Displays available Cranelift settings for a target
wast Runs a WebAssembly test script file
If a subcommand is not provided, the `run` subcommand will be used.
Usage examples:
Running a WebAssembly module with a start function:
wasmtime example.wasm
Passing command line arguments to a WebAssembly module:
wasmtime example.wasm arg1 arg2 arg3
Invoking a specific function (e.g. `add`) in a WebAssembly module:
wasmtime example.wasm --invoke add 1 2
まずは、RustでHelloWorld
このページに書いてある通りに進めてみる。
hello.rs
fn main() {
println!("Hello, world!");
}
$ rustup target add wasm32-wasi
info: downloading component 'rust-std' for 'wasm32-wasi'
info: installing component 'rust-std' for 'wasm32-wasi'
18.9 MiB / 18.9 MiB (100 %) 13.5 MiB/s in 1s ETA: 0s
$ rustc hello.rs --target wasm32-wasi
$ wasmtime hello.wasm
Hello, world!
動いた。
$ ls -lth
total 2.1M
-rwxrwxr-x 1 koba koba 2.1M 6月 2 10:12 hello.wasm
-rw-rw-r-- 1 koba koba 46 6月 2 10:11 hello.rs
wasmファイルのサイズが2.1MBもある。
$ rustc hello.rs -O --target wasm32-wasi
$ wasmtime hello.wasm
Hello, world!
$ ls -lth
total 2.1M
-rwxrwxr-x 1 koba koba 2.0M 6月 2 10:20 hello.wasm
-rw-rw-r-- 1 koba koba 46 6月 2 10:11 hello.rs
-O
をつけてもサイズは2.0MB。
** 2023/06/03 追記
以下のようにstripするオプションをつけたら64KBくらいまで小さくなりました。
$ rustc --version
rustc 1.70.0 (90c541806 2023-05-31)
$ rustc hello.rs -O -C strip=symbols --target wasm32-wasi
$ wasmtime hello.wasm
Hello, world!
$ ls -lt *.wasm
-rwxrwxr-x 1 koba koba 63602 6月 3 09:29 hello.wasm
-rwxr--r-- 1 koba koba 5116 6月 2 12:27 hello_c.wasm
-rwxr--r-- 1 koba koba 15698 6月 2 10:49 hello_zig_release_fast.wasm
-rwxr--r-- 1 koba koba 23581 6月 2 10:49 hello_zig_release_safe.wasm
-rwxr--r-- 1 koba koba 335 6月 2 10:49 hello_zig_release_small.wasm
-rwxr--r-- 1 koba koba 79290 6月 2 10:48 hello_zig_debug.wasm
-rwxr--r-- 1 koba koba 79260 6月 2 10:42 hello_zig.wasm
** 2023/06/03 追記ここまで
同じことをZigでやってみる。
hello_zig.zig
const std = @import("std");
pub fn main() void {
std.debug.print("Hello, world!\n", .{});
}
まずはネイティブ向けにビルドして実行。
$ zig build-exe hello_zig.zig
$ ./hello_zig
Hello, world!
$ zig targets |grep wasi
"wasi",
"wasm32-wasi-musl",
ターゲットを指定してビルド。
$ zig build-exe -target wasm32-wasi-musl hello_zig.zig
$ wasmtime hello_zig.wasm
Hello, world!
$ ls -lt
total 3992
-rwxr--r-- 1 koba koba 79260 6月 2 10:33 hello_zig.wasm
-rw-rw-r-- 1 koba koba 108122 6月 2 10:33 hello_zig.wasm.o
-rwxrwxr-x 1 koba koba 730952 6月 2 10:28 hello_zig
-rw-rw-r-- 1 koba koba 1053072 6月 2 10:28 hello_zig.o
-rw-rw-r-- 1 koba koba 98 6月 2 10:24 hello_zig.zig
-rwxrwxr-x 1 koba koba 2094117 6月 2 10:20 hello.wasm
-rw-rw-r-- 1 koba koba 46 6月 2 10:11 hello.rs
optimizeレベルを変えて、wasmファイルのサイズを比べる。
zig build-exe
には -o
オプションが無くて、出力するファイル名はソースファイル名で決まってしまいます。なので、シンボリックリンクを作りました。
$ ln -s hello_zig.zig hello_zig_debug.zig
$ ln -s hello_zig.zig hello_zig_release_safe.zig
$ ln -s hello_zig.zig hello_zig_release_small.zig
$ ln -s hello_zig.zig hello_zig_release_fast.zig
4種類のモードでビルド。
$ zig build-exe -O Debug -target wasm32-wasi-musl hello_zig_debug.zig
$ zig build-exe -O ReleaseSmall -target wasm32-wasi-musl hello_zig_release_small.zig
$ zig build-exe -O ReleaseSafe -target wasm32-wasi-musl hello_zig_release_safe.zig
$ zig build-exe -O ReleaseFast -target wasm32-wasi-musl hello_zig_release_fast.zig
ファイルサイズを見てみる。
$ ls -l *.wasm
-rwxrwxr-x 1 koba koba 2094117 6月 2 10:20 hello.wasm
-rwxr--r-- 1 koba koba 79290 6月 2 10:48 hello_zig_debug.wasm
-rwxr--r-- 1 koba koba 15698 6月 2 10:49 hello_zig_release_fast.wasm
-rwxr--r-- 1 koba koba 23581 6月 2 10:49 hello_zig_release_safe.wasm
-rwxr--r-- 1 koba koba 335 6月 2 10:49 hello_zig_release_small.wasm
-rwxr--r-- 1 koba koba 79260 6月 2 10:42 hello_zig.wasm
ZigでReleaseSmallでビルドしたものは、すごく小さいですね。335バイト。
ついでにzig cc でwasm出力 (2023/06/02追記)
hello.c
#include <stdio.h>
int main() {
puts("Hello, world!");
}
-Os
(サイズが小さくなるように最適化)をつけてwasmにコンパイル
$ zig cc -o hello_c.wasm -Os -target wasm32-wasi-musl hello.c
$ wasmtime hello_c.wasm
Hello, world!
$ ls -l *.wasm
-rwxr--r-- 1 koba koba 5116 6月 2 12:27 hello_c.wasm
-rwxrwxr-x 1 koba koba 2094117 6月 2 10:20 hello.wasm
-rwxr--r-- 1 koba koba 79290 6月 2 10:48 hello_zig_debug.wasm
-rwxr--r-- 1 koba koba 15698 6月 2 10:49 hello_zig_release_fast.wasm
-rwxr--r-- 1 koba koba 23581 6月 2 10:49 hello_zig_release_safe.wasm
-rwxr--r-- 1 koba koba 335 6月 2 10:49 hello_zig_release_small.wasm
-rwxr--r-- 1 koba koba 79260 6月 2 10:42 hello_zig.wasm
Cと比べても、Zigのrelease_smallはサイズが小さい。
使用したzigのバージョン
$ zig version
0.11.0-dev.3336+6c2f37455
$ zig cc --version
clang version 16.0.1 (https://github.com/ziglang/zig-bootstrap 710c5d12660235bc4eac103a8c6677c61f0a9ded)
Target: aarch64-unknown-linux-musl
Thread model: posix
InstalledDir: /usr/bin
Discussion