Rustコンパイラの自前ビルド

コンパイラの動作を調べるにあたって、いちいちmasterをビルドするのは不便なので、安定版の自前ビルドを作成することにした。

$ wget https://static.rust-lang.org/dist/rustc-1.18.0-src.tar.gz
$ tar xvf rustc-1.18.0-src.tar.gz
$ cd rustc-1.18.0-src
$ cp src/bootstrap/config.toml.example config.toml

config.toml を編集する。今回変更したのは以下の点

[llvm]

[build]
# コンパイラ内部の関数等のドキュメントも生成する
compiler-docs = true
# cargo/rlsも一緒にビルドする
extended = true

[install]
prefix = "/home/username/rust-custom/1.18.0"

[rust]
# デバッグアサートを有効にする。特にdebug!()によるログを有効にする
debug-assertions = true
debuginfo = true
debuginfo-lines = true

[target.x86_64-unknown-linux-gnu]

[dist]

ビルド・インストールする。適当にYouTubeを鑑賞するなどしながら待つ

$ python2 x.py build && python2 x.py doc && python2 x.py dist --install

作成したツールチェインをrustupに登録する。

$ rustup toolchain link custom-1.18.0 ~/rust-custom/1.18.0

これで必要なときだけ自前バージョンを呼び出せるようになる。

$ rustup run custom-1.18.0 rustc --version
rustc 1.18.0-dev
$ rustc +custom-1.18.0 --version
rustc 1.18.0-dev

debug-assertions を有効にしたので、以前の記事で書いたように、デバッグ出力を見ることができるようになる

プロジェクトごとに使うバージョンを変えるには rustup override をするとよい。

$ rustup override set custom-1.18.0

pyenvはバージョン設定をローカルの .python-versionに置くが、rustup overrideの設定は ~/.rustup/settings.toml にまとめられている。

生成したドキュメントは $prefix/share/doc/rust/html/index.html にある。ここにあるAPIドキュメントは通常 corestdなどのみ掲載されているが、compiler-docsオプションを有効にしたのでコンパイラドキュメントが同梱されている。

LLVMを指定する場合

Rustの配布物にはLLVMが同梱されているが、OSに入っているLLVMを使うこともできる。思いつく利点と欠点は以下の通り

  • 利点: 初手コンパイル時間の短縮
  • 欠点: RustはLLVMのバグをよく踏んでいるので古いバージョンだと困ることがあるかも
  • 欠点: バージョン違いにより生成されるコードが微妙に異なり、codegenのテストに落ちることがある。テストを実行しないなら特に問題ない
  • 欠点: LLVM4.0は -lffi を手動で指定しないといけないので対処が必要

以下ではUbuntu 16.04.2 LTSを例にする。

まずLLVMを入れる。Ubuntuの公式リポジトリには3.7がある。 *-tools が必要なので注意

$ sudo apt install llvm-3.7-tools

LLVM側のUbuntu用リポジトリでは4.0も提供されているのでそれでもよい。

続いて、このLLVMを使うように config.toml を書き換える

[llvm]

[build]

[install]

[rust]

[target.x86_64-unknown-linux-gnu]
llvm-config = "/usr/bin/llvm-config-3.7"

[dist]

llvm-4.0を使うとリンクに失敗するかもしれない。その場合は-lffiを強制的に指定するようなパッチを当てればよい。