EmscriptenでRustをJSへコンパイルする (コンパイルできてない)
2016/3/8追記
うまくいきました。エントリ書きました。
RustでEmscriptenを使う方法を調べたのでメモ。2015年12月28日時点でなんとか動作させるための手順です。今後オフィシャルにEmscriptenサポートが入るなどすると、もっと簡単なやり方になるかと思います。
Emscripten SDK をインストール
Emscriptenのサイト から Emscripten SDK をダウンロードしてきて、インストールします。
$ wget https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz $ tar xvf emsdk-portable.tar.gz $ cd emsdk_portable $ ./emsdk update $ ./emsdk install latest $ ./emsdk activate latest
Emscripten 対応の rust をコンパイル
brson/rust の emscripten
ブランチをクローン。
$ git clone git@github.com:brson/rust.git -b emscripten
なお、12/28時点でのコミットのハッシュは c42f32e
です。
当該ブランチの src/llvm
submodule は rust-lang
のものが読み込まれていますが、ハッシュ値は emscripten の LLVM fork (emscripten-fastcomp) のものとなっていますので、以下の変更を加えます
(.gitmodules
のコミット漏れ?)
diff --git a/.gitmodules b/.gitmodules index 83be070..5f92864 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "src/llvm"] path = src/llvm - url = https://github.com/rust-lang/llvm.git + url = https://github.com/kripken/emscripten-fastcomp.git branch = master [submodule "src/compiler-rt"] path = src/compiler-rt
ここまで準備できたらいよいよ configure
& make
です。以下の作業が必要なようです。
- Emscripten SDK の環境変数の有効化
- 最適化の無効化 (releaseモードだとうまく動作しないらしい)
$ source <path to SDK>/emsdk_env.sh $ ./configure --target=asmjs-unknown-emscripten $ make -j4
なお、手元の OSX 環境では configure
に失敗するため、EmscriptenのIssueコメントを参考にし、 CC=gcc CXX=g++
の環境変数を指定して configure
したところ、うまく動作しました (デフォルトコンパイラが clang の環境でEmscripten 側の clang が使われてしまうとだめなのかもしれません)。
configure: error: C preprocessor "/lib/cpp" fails sanity check
hello world! のコンパイル
謎のエラーが出て通らず。。。
$ LD_LIBRARY_PATH=../rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/ ../rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/bin/rustc ./main.rs --target asmjs-unknown-emscripten error: linking with `emcc` failed: exit code: 1 note: "emcc" "-L" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib" "main.0.o" "-o" "main.js" "-Wl,--gc-sections" "-nodefaultlibs" "-L" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib" "-Wl,-Bstatic" "-Wl,-Bdynamic" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libstd-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libcollections-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/librustc_unicode-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/librand-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/liballoc-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/liballoc_system-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/liblibc-ca1c970e.rlib" "/home/nksm/tmp/rust-emscripten-c42f32e/x86_64-unknown-linux-gnu/stage2/lib/rustlib/asmjs-unknown-emscripten/lib/libcore-ca1c970e.rlib" "-l" "c" note: error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) error: Unknown attribute kind (45) Traceback (most recent call last): File "/home/nksm/dev/emsdk_portable/emscripten/master/emcc", line 1309, in <module> final = shared.Building.llvm_opt(final, link_opts, DEFAULT_FINAL) File "/home/nksm/dev/emsdk_portable/emscripten/master/tools/shared.py", line 1471, in llvm_opt assert os.path.exists(target), Failed to run llvm optimizations: + output AssertionError: Failed to run llvm optimizations: error: aborting due to previous error
うーん、なんでしょうこれは。