2018年早々、LLVMのビルドで消耗しておりました。
なんとなくlibToolingを使ってみようとしたらソースのビルドが必要そうな感じだったので始めたのですが、LLVMには複数のプロジェクトがあり、各プロジェクトの役割とかいまいちピンと来ておらず、ビルドにあたっていろいろドキュメント読んだりする必要がありました。
ドキュメントを熟読せずに始めるといろいろと躓くようなので、LLVMのビルドに関する情報をまとめておきたいと思います。
といってもまだまとめ切れていない点が多いので恐らく後から次々と追記・訂正することになりそうな気がします。
必読ページ達
LLVMプロジェクトはドキュメントが充実しています。
この充実したドキュメントをしっかり読むことが大切のようです。
ビルドに関する情報だけでもいくつかのページで役経つ情報が書かれています。
ビルドに関しては以下3ページが役に立ちます。
- Getting Started with the LLVM System — LLVM 7 documentation
- Building LLVM with CMake — LLVM 7 documentation
- Clang - Getting Started
まずは一番上のLLVMのGettingStartedのページから読むのがお勧めのようです。
LLVM System GettingStarted
読めよ、絶対読めよ。
このGettingStartedはちょっとしたジョークから始まります。
1.Read the documentation.
2.Read the documentation.
3.Remember that you were warned twice about reading the documentation.
In particular, the relative paths specified are important.
これを訳すと、
手順
1. ドキュメント読めよ
2. ドキュメント読めよ
3.ドキュメント読めって2回忠告されたことを忘んなよ!
特に相対パスで指定しているとこ注意な!
といった感じでしょうか。
個人的には「ドキュメントは読むなよ!分かりやすいから絶対読むなよ」みたいに書かれていても面白いなと思いましたが、ああいう出川スタイルのギャグは欧米にはないのでしょうか。
開発環境のC++のツールチェインについて
GettinStartedを読み進めるとさらっと重要なことが書いてあります。
Getting Started with the LLVM System — LLVM 7 documentation
LLVM is very demanding of the host C++ compiler, and as such tends to expose bugs in the compiler. We are also planning to follow improvements and developments in the C++ language and library reasonably closely. As such, we require a modern host C++ toolchain, both compiler and standard library, in order to build LLVM.
For the most popular host toolchains we check for specific minimum versions in our build systems:
Clang 3.1
GCC 4.8
Visual Studio 2015 (Update 3)
要するに、
LLVMはC++のモダンな機能を使って開発をしていて、開発環境のC++コンパイラは厳密さが求められるので、コンパイラのバグを曝け出しがち。ということで俺らも頑張ってC++のツールチェインと標準ライブラリ作ってるから・・・
あっ、ちなみに俺らがLLVMの最低限の確認に使っている一般的な開発環境は、
- Clang 3.1
- GCC 4.8
- Visual Studio 2015 (Update 3)
だからそこんとこよろしく。
ということでしょう。
「 most popular host toolchains」という表現がありますが、これは、2018年の早々からLLVMのビルド地獄に落ちた身としては、
このリストうちのどれかでビルドしろよ!
という最後通牒として受け取ることをおすすめします。
また、ビルドに失敗するツールチェインとして、
- GNU ld 2.16.X.
- GNU binutils 2.17
- GNU Binutils 2.19.1 Gold
が挙げられています。
ツール・プロジェクトについて
LLVMはLLVM本体以外にclangなど複数のプロジェクトから構成されています。
compiler-rt
低レベルのライブラリ。どうもCPU依存部での最適なビルドイン関数とかSanitizerの機能を提供するプロジェクトのようです。
結論
ということでここまで各ページの概要について見てみましたが、私が試したLinux環境でLLVMをビルドする手順をここで書いておきたいと思います。
注意事項
以下、ビルドしていて大変だったこととか、注意点とかです。
LLVMのビルドは結構ディスク容量食います。
ソース一式展開すると500MB程度ありました。ビルドしたディレクトリで1.7GB程度。
私はVM環境上でビルドしたので、同じことをされる方は仮想マシンのディスクサイズを多めに確保されることをお勧めします。
※VMだと削除したファイルの領域が確保されっぱなしになるのであっという間にディスクサイズが膨れ上がってしまいました。
ディスクサイズの圧縮は、VMWareToolでできるようですので、こちらの記事を参考にさせて頂き試してみました。
gendosu.jp
参考にさせて頂きありがとうございます。
手元の環境では、圧縮のコマンド実行後、19GBのvmdkファイルが10GB程度に圧縮されました。
リンクがかえってこない!?
メモリ増やすのとHDDじゃなくてSSDを使うことで何とかなるっぽい。
リンカが返ってこない(ディスクアクセスしっぱなし)って初めて見ました。
やること
ざっくりと、
- clangをインストール
- 必要なパッケージ
- LLVMのソース一式をゲット
- ソース一式の展開
- cmakeの実行
- ビルド実行
- インストール
clangをインストール
ビルドするためにとりあえずclangをインストールします。
$sudo apt install clang
手元の環境だと3.8がインストールされました。
あとOpenMPやLLDBのプロジェクトをビルドする場合はいくつか依存しているパッケージのインストールが必要になるようです。
# OpenMP関係のパッケージをインストール
# OpenMPのビルドをしないのであれば不要
sudo apt install openmpi-bin openmpi-common libopenmpi-dev# LLDBで必要になるパッケージのインストール
# LLDBをビルドしないのであれば不要
sudo apt-get install build-essential subversion swig python2.7-dev libedit-dev libncurses5-dev
LLVMのソースの取得と展開
からビルドしたいバージョンのソースをダウンロードします。
LLVM本体以外のソースは既定の場所に既定のフォルダ名で配置する必要があるようです。
基本的にはtoolsディレクトリかprojectsディレクトリのどちらかのようです。
ドキュメントではビルドの手順として、svnやgitからtrunkのコードを落としてきてビルドする形で書かれていますが一応リリースされたバージョンでビルドを試したいと思います。
この記事を書いている時点だと5.0.1が最新になります。
コマンド実行例
ソースの取得・展開とか、cmakeのコマンドは長くなるので試してみたコマンド例を挙げておきます。
以下、試したコマンド実行例です。
LLDBはビルドにこけたのでとりあえず除外してみました。
LLDB以外の全部入りですが、とりあえずビルドしてみたいという方は以下のコマンドをシェルスクリプトとして保存して叩いてもらえればビルドできると思います。私の手元の環境では、32bitと64bitのMintの環境でビルドが通りました。
# ビルドに必要なパッケージをインストール
sudo apt-get install clang cmake git g++# OpenMP関係のパッケージをインストール
# OpenMPのビルドをしないのであれば不要
sudo apt install openmpi-bin openmpi-common libopenmpi-dev# LLDBで必要になるパッケージのインストール
# LLDBをビルドしないのであれば不要
sudo apt-get install build-essential subversion swig python2.7-dev libedit-dev libncurses5-dev# LLVM作業用ディレクトリの作成・移動
mkdir ~/clang-llvm
cd ~/clang-llvm# ninjaのビルド
# ninja は apt で install するバージョンが古いのでgitから最新版を使った方がよいみたい
# ninjaを使わない場合は不要(makeより早いらしいけど違いはいまいちよくわかっていない)cd ~/clang-llvm
git clone https://github.com/martine/ninja.git
cd ninja
git checkout release
./bootstrap.py
sudo cp ninja /usr/bin/
cd ~/clang-llvm
# ソースの取得 version5.01の場合
wget http://releases.llvm.org/5.0.1/llvm-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/cfe-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/compiler-rt-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/libcxx-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/libcxxabi-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/libunwind-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/lld-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/lldb-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/openmp-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/polly-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/clang-tools-extra-5.0.1.src.tar.xz
wget http://releases.llvm.org/5.0.1/test-suite-5.0.1.src.tar.xz
# 展開
tar xfv llvm-5.0.1.src.tar.xz
tar xfv cfe-5.0.1.src.tar.xz
tar xfv compiler-rt-5.0.1.src.tar.xz
tar xfv libcxx-5.0.1.src.tar.xz
tar xfv libcxxabi-5.0.1.src.tar.xz
tar xfv libunwind-5.0.1.src.tar.xz
tar xfv lld-5.0.1.src.tar.xz
tar xfv lldb-5.0.1.src.tar.xz
tar xfv openmp-5.0.1.src.tar.xz
tar xfv polly-5.0.1.src.tar.xz
tar xfv clang-tools-extra-5.0.1.src.tar.xz
tar xfv test-suite-5.0.1.src.tar.xz# 各プロジェクトをllvmソースディレクトリへ移動
# プロジェクトによってllvm以下への配置先が異なるので注意
mv cfe-5.0.1.src llvm-5.0.1.src/tools/clang
mv compiler-rt-5.0.1.src llvm-5.0.1.src/projects/compiler-rt
mv libcxx-5.0.1.src llvm-5.0.1.src/projects/libcxx
mv libcxxabi-5.0.1.src llvm-5.0.1.src/projects/libcxxabi
mv libunwind-5.0.1.src llvm-5.0.1.src/runtimes/libunwind
mv lld-5.0.1.src llvm-5.0.1.src/tools/lld# 注意 lldbはビルドに失敗するようなのでの配置は行わない
#mv lldb-5.0.1.src llvm-5.0.1.src/projects/lldb
mv openmp-5.0.1.src llvm-5.0.1.src/projects/openmp
mv polly-5.0.1.src llvm-5.0.1.src/tools/polly
mv clang-tools-extra-5.0.1.src llvm-5.0.1.src/tools/clang/tools/extra
mv test-suite-5.0.1.src llvm-5.0.1.src/projects/test-suitemkdir build
cd build# ######################################################
# cmakeコマンドの実行
# ビルドに使用するコンパイラにclangを指定
# ######################################################
# ninjaを使うビルドの場合
cmake -G "Ninja" -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_LINKER=gold -DLLVM_BUILD_TEST=ON CMAKE_INSTALL_PREFIX=/usr/local ../llvm-5.0.1.src
# makeの場合
# cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_LINKER=gold -DLLVM_BUILD_TEST=ON -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-5.0.1.src# ビルド実行
ninja# インストールするとき(ninja は make 互換なんだろうか)
#ninja install
cmakeコマンドのオプションについて
LLVMのビルドで使用するオプションはたくさんあります。
なので上記のコマンドの実行例では「とりあえずこれでいいかな!?」程度に指定しています。不要な設定とか、逆に不足したりしているオプションがあるかもしれません。
オプションの解説
cmakeを実行するときのオプションについて少し解説・補足を書いておきたいと思います。
-G "Ninja"
これはcmakeで出力するファイルの形式を指定するオプションです。LLVMではninja(ninjaってnanja!?)というビルドシステムを利用することが推奨されています。
でも別にmakeでもビルドはできるのでmakeを使いたい人はこのオプションは不要です。
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang
これはビルドで使用するコンパイラの指定です。
gccでビルドしたいという場合は不要ですが、GCCだとビルドがバグ落ちするようなのでこれは必須と考えていいでしょう。C言語で書かれているコードはなさそうですので恐らくDCMAKE_C_COMPILERは要らないと思いますが念のためつけています。
-DCMAKE_BUILD_TYPE=Release
リリースビルドの指定です。
リンクエラー(リンカがかえってこない)対応として、このオプションをつけた方がよいようです。
-DLLVM_USE_LINKER=gold
リンク時に使用するリンカの指定です。
こちらもldだとリンクエラー(リンカがかえってこない)対応としての指定です。
-DLLVM_BUILD_TEST=ON
LLVMのユニットテストを有効にする場合のオプションです。デフォルトだとOFFになっており必須ありません。
OFFにするとビルド時間が短縮できると思います。
-DCMAKE_INSTALL_PREFIX=/usr/local
インストール先のプレフィックスです。
デフォルトだと/usr/ 以下に展開されるので/usr/localに指定しています。
参考書籍
LLVMに関する参考書籍は日本語ではあまり出ていないようですが、手元にLLVM/Clang実践活用ハンドブックという書籍があります。
2014年に出版された書籍で、書籍で扱われているLLVMのバージョンは3.4になります。
ですので、今回の記事で書いたビルドに関する内容は現状と異なりますが、ビルド時のオプションなどは変わっていないものも多いので参考になりました。またLLVM IRやlibtooling等に関して丁寧に記載してくださっているので分かりやすかったです。

- 作者: 出村成和
- 出版社/メーカー: ソシム
- 発売日: 2014/06/23
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
感想
libLTO.so というお化けライブラリ
リンカが返ってこなくなってシグナルにビルドプロセスが殺されるのを初めてみた・・・
libLTO.soはリリースビルドしたモジュールで45MB程度ありました。
やたらといろんなアーカイブファイルをまとめているのがこのlibLTO.soというファイルのようですが、なんでこんなでかいのか・・
とりあえずこいつのリンクエラーのせいでビルドが止まる場合は、ビルドマシンのメモリサイズを増やしたり、あとHDDじゃなくてSDD使うのが効果的のようです。
まとめ
LLVMプロジェクトは巨大すぎてどっから手をつけていいのかよく分からんというのが正直なところです。
いろいろ試してみましたが、とりあえず遊ぶ分にはビルドせず、パッケージインストールして使うのが正解かもしれません。
そもそもやりたかったことはlibToolingとか使ってみたかっただけなのになんでこんなことしているんだろう・・・