fine, later feeling

晴れのち気分

RustからWebAssemblyにコンパイルしてみる

Rust入門者です。WebAssembly(wasm)入門者です。
今までNightlyではサポートされてたようですが、stableなv1.14でも試験的にWebAssemblyがサポートされたそうなので試してみます。
※この記事は自分の情報整理とログを残すために書いたので間違ってるかもしれません。

準備

Rustを入れる必要があるので入れてない場合はrustupでインストールします。
既にrustupでRustをインストールしてるけどバージョンが古い場合はrustup updateで最新版にできます。multirust使ってる人は知りません。

# バージョン確認
$ rustc -V
rustc 1.14.0 (e8a012324 2016-12-16)

新しいwasmにコンパイルするためのターゲットをインストールします。

$ rustup target add wasm32-unknown-emscripten

後述の処理でcmakeが必要なので先に入れておく

$ brew install cmake

Emscripten SDKをダウンロードして解凍します。(ポチポチでDLしたい場合はこちら

# DL&解凍
$ curl -O https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz
$ tar zxvf emsdk-portable.tar.gz

# インストール
$ cd emsdk_portable/
$ emsdk update
$ emsdk install sdk-incoming-64bit
$ emsdk activate sdk-incoming-64bit

emsdk install sdk-incoming-64bitを中でCのビルドする工程があるんですが、これがかなり長いです。(40分かかりました)

Emscripten環境変数を設定

$ source ./emsdk_env.sh

emccのバージョンを確認します。 1.37.0以上が必要です。

$ emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.37.1
(後略)

WebAssemblyの生成と実行

hello.rsを作ります。

fn main() {
  println!("Hello world!!");
}

以下のコマンドで最適化オプションをつけてビルドします。

$ rustc --target=wasm32-unknown-emscripten hello.rs -o hello.html

コマンドを叩いた後、2〜3分プロンプトが返って来なくてヒヤヒヤしましたが成功すると以下のファイルが生成されました。 いっぱい生成されたけど使ってるのはhello.jshello.wasmだけかな?(asm.jsはオマケで生成されてるのだろうか…)

  • hello.asm.js
  • hello.html
  • hello.js
  • hello.rs # さっき作ったファイル
  • hello.wasm
  • hello.wast

Chrome CanaryもしくはFirefox Nightlyでchrome://flags/にアクセスしてWebAssemblyを有効にします。 f:id:suzumidokoro:20170105175622p:plain

pythonでもphpでもnodeでもいいですが、今回はpythonでサクッとWebサーバを立てます。

$ python -m SimpleHTTPServer

http://localhost:8000/hello.htmlにアクセスするとコンソールに文字が出力されていると思います。 f:id:suzumidokoro:20170105175625p:plain

ということで無事WebAssemblyをブラウザで動かすことができました。

まとめ

整理するとこんな感じでしょうか。

  • WebAssemblyは簡単に言うとブラウザでの実行を想定したバイナリフォーマット。
  • EmscriptenLLVMベースにC/C++をJSやasm.jsに変換するコンパイラ
  • Rustコード→LLVM IRを生成する(RustのEmsctipten対応)
  • Emscriptenからwasmの生成
  • hello.html中の<script>内でwasmをロード、hello.jsの中でwasmをコンパイルして実行

んーややこしい。

ここらへん疎いんでよくわかってないですが、もう少し深掘りしていきたいと思います。

参考

Compiling Rust to WebAssembly Guide – Hacker Noon