はじめに
日頃仕事ではWEB周りの開発をしているので、「rustで書いたコードをコンパイル→WebAssembly」を試してみたいと思います。
Emscriptenなしで、Rust単体でのwasmへのコンパイルが可能になりました。
wasm32-unknown-unknown landed & enabled
環境
- ArchLinux(Kernel 4.12.4-1)
- Intel(R) Core(TM) i7-4790T CPU @ 2.70GHz
- Memory 16GB
- Vivaldi 1.11.917.39
インストール
rustcを公式パッケージからインストールしていたのですが、「wasm32-unknown-emscripten」をターゲットに指定し、
コンパイルする必要があるので、rustupをインストールしました。
(おそらく、競合している旨のメッセージがでるかと思いますが、そのまま上書きする形でインストールを進めます)
rustをWebAssemblyにコンパイルする際、emscriptenを使用してWebAssemblyにコンパイルするので、emscriptenもインストールします(cargoでビルドした際に、emccを使用します)。
また、コンパイルの過程でcmakeを使用するので、同時にcmakeもインストールします。
$ yaourt -S rustup
$ yaourt -S emscripten
$ yaourt -S cmake
emscriptenとは?
emscriptenとは、C/C++のコードからJavaScriptを出力するコンパイラです。
超ざっくりいうと、「C/C++からLLVM-IR(中間言語)を生成し、それらをJavaScriptへ変換」、といった流れになります。
環境設定
インストールしたrustupを使用して、ターゲットを追加します。
また、WebAssembly用のプロジェクトを作成します。
$ rustup target add wasm32-unknown-emscripten
$ rustup target list
aarch64-apple-ios
aarch64-linux-android
aarch64-unknown-fuchsia
aarch64-unknown-linux-gnu
arm-linux-androideabi
arm-unknown-linux-gnueabi
arm-unknown-linux-gnueabihf
arm-unknown-linux-musleabi
arm-unknown-linux-musleabihf
armv7-apple-ios
armv7-linux-androideabi
armv7-unknown-linux-gnueabihf
armv7-unknown-linux-musleabihf
armv7s-apple-ios
asmjs-unknown-emscripten
i386-apple-ios
i586-pc-windows-msvc
i586-unknown-linux-gnu
i686-apple-darwin
i686-linux-android
i686-pc-windows-gnu
i686-pc-windows-msvc
i686-unknown-freebsd
i686-unknown-linux-gnu
i686-unknown-linux-musl
mips-unknown-linux-gnu
mips-unknown-linux-musl
mips64-unknown-linux-gnuabi64
mips64el-unknown-linux-gnuabi64
mipsel-unknown-linux-gnu
mipsel-unknown-linux-musl
powerpc-unknown-linux-gnu
powerpc64-unknown-linux-gnu
powerpc64le-unknown-linux-gnu
s390x-unknown-linux-gnu
sparc64-unknown-linux-gnu
wasm32-unknown-emscripten (installed) ※ wasm32-unknown-emscriptenがインストールされている
x86_64-apple-darwin
x86_64-apple-ios
x86_64-linux-android
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc
x86_64-rumprun-netbsd
x86_64-unknown-freebsd
x86_64-unknown-fuchsia
x86_64-unknown-linux-gnu (default)
x86_64-unknown-linux-musl
x86_64-unknown-netbsd
$ cargo new --bin web_assembly
Created binary (application) `web_assembly` project
ビルドしてみる
実際に先程作成したプロジェクトをビルドしてみます。
$ cargo build --target wasm32-unknown-emscripten
error: could not exec the linker `emcc`: No such file or directory (os error 2)
emccが存在しないというエラーが出力されました。
先程、emscriptenはインストールしましたので、「PATHが通っていないのではないか?」、ということで実際にどのディレクトリにインストールされているのか調べてみます。
$ pacman -Ql emscripten | grep emcc
(標準入力):88:emscripten /usr/lib/emscripten/emcc
「/usr/lib/emscripten」は、PATH環境変数に含まれていないので、PATHを指定してビルドしてみます。
(本来は、.zshrcなどにPATH追加すればよいかと思います)
$ PATH=$PATH:/usr/lib/emscripten cargo build --target wasm32-unknown-emscripten
Compiling web_assembly v0.1.0
Finished dev [unoptimized + debuginfo] target(s) in 1.73 secs
ビルドが完了しました。
WebAssemblyの本体は、「target/wasm32-unknown-emscripten/debug/deps/xxxx.wasm」になります(xxxxは任意)。
WebAssemblyを使用してみる
ビルドが完了したWebAssemblyファイルを使用してみます。
こちらの記事を参考にし、WebAssemblyの動作確認を行いました(有益な記事があり、ありがたいです!)。
確かに開発者ツールのConsoleに、「Hello, World!」が出力されています。
まとめ
以上の手順で、rustからWebAssemblyにコンパイルすることができました。
最初、cmakeをインストールするのを忘れていないため、ビルドエラーが発生していました。
ちゃんとマニュアルを読もう!!!
次回はWebAssemblyにすることによりパフォーマンスが向上すると言われていますが、実際に「どれくらいパフォーマンスが上がるのか?」、等を検証したいと思います。