RubyがWebAssemblyのWASI対応へ前進。ブラウザでもサーバでもエッジでもどこでもWebAssembly版Rubyが動くように - Publickey という記事で紹介されている WASI 対応がマージされたので試してみました。

動作確認環境

  • Ubuntu 21.10 (amd64)
  • wasi-sdk-14.0-linux.tar.gz
  • binaryen-version_91-x86_64-linux.tar.gz
  • wasmtime 0.33.0

wasm/README.md に従って WASI SDK の 14.0 と Binaryen version 91 をダウンロードしました。 WASI SDK や Binaryen のバイナリリリースが Linux は x86-64 しかないので、 aarch64 で試すのは自前でビルドが必要そうで大変そうなので避けました。

準備

WASI SDK をダウンロードして展開して、 export WASI_SDK_PATH=$HOME/wasi-sdk-14.0.bashrc に設定しました。 WASI SDK は PATH には追加しません。

Binaryen もダウンロードして展開して、 export PATH="$HOME/binaryen-version_91:$PATH".bashrc に設定しました。

Configure

クロスコンパイルには同じバージョンの host ruby を使う必要があるので、README の例に --with-baseruby を追加して configure を実行しました。 コマンドライン全体は /path/to/github.com/ruby/ruby/configure LDFLAGS="-Xlinker -zstack-size=16777216" --host wasm32-unknown-wasi --with-destdir=./ruby-wasm32-wasi --with-static-linked-ext --with-ext=ripper,monitor --with-baseruby=$(RBENV_VERSION=master rbenv which ruby) のように指定しました。

Make

make install を実行すると --with-destdir で指定した ./ruby-wasm32-wasi にインストールされました。

wasmtime のインストール

実行環境として wasmtime をインストールしました。

curl https://wasmtime.dev/install.sh -sSLO
bash ./install.sh

.bashrc に以下の内容が追加されていました。

export WASMTIME_HOME="$HOME/.wasmtime"

export PATH="$WASMTIME_HOME/bin:$PATH"

実行確認

README に書いてある例などが実行できることを確認できました。

$ wasmtime ruby-wasm32-wasi/usr/local/bin/ruby --mapdir /::./ruby-wasm32-wasi/ -- -e 'puts RUBY_DESCRIPTION'
ruby 3.2.0dev (2022-01-19T21:45:28Z master 2b7025e680) [wasm32-wasi]

昨日の時点は wasmtime ruby-wasm32-wasi/usr/local/bin/ruby --mapdir /::./ruby-wasm32-wasi/ -- --disable-gems -e 'puts RUBY_DESCRIPTION' のように --disable-gems を付ける必要がありましたが、 2b7025e680eb29f936538c07f057f590003e45bf がマージされて不要になりました。

irb は wasmtime ruby-wasm32-wasi/usr/local/bin/ruby --mapdir /::./ruby-wasm32-wasi/ -- -e binding.irb で試そうとしても io-console がなくて使えなかったので、手軽に色々試すのに sample/eval.rb を使ってみました。ファイルの読み書きも問題なくできるようです。

$ cp ..../sample/eval.rb ruby-wasm32-wasi/
$ wasmtime ruby-wasm32-wasi/usr/local/bin/ruby --mapdir /::./ruby-wasm32-wasi/ -- /eval.rb
ruby> RUBY_DESCRIPTION
"ruby 3.2.0dev (2022-01-19T21:45:28Z master 2b7025e680) [wasm32-wasi]"
ruby> 2**128
340282366920938463463374607431768211456
ruby> Dir.children '.'
["eval.rb", "usr"]
ruby> File.write 'foo', 'bar'
3
ruby> File.read 'foo'
"bar"
ruby> Dir.children '.'
["foo", "eval.rb", "usr"]
ruby> File.unlink 'foo'
1
ruby> Dir.children '.'
["eval.rb", "usr"]

感想

バイナリリリースのアーキテクチャ依存が想定外でしたが、そこ以外は比較的スムーズに試すことができました。 まだ制限も色々ありますが、 3.2 の preview1 がリリースされたり、色々な使い方がされたりすると、広く使われるようになるかもしれません。

Disqus Comments

Kazuhiro NISHIYAMA

Ruby のコミッターとかやってます。 フルスタックエンジニア(って何?)かもしれません。 About znzに主なアカウントをまとめました。

znz znz


Published