RaspbianでClang 3.8を野良ビルドする

2016年3月に日本でもRaspberry Pi 3 Model Bが販売開始されました。しかし、オフィシャルから提供されているRaspbianのC/C++コンパイル環境では依然gcc 3.8または、clang 3.0までしか提供されていないようです(自分はRaspberry Pi 2 Model Bまでしか確認していませんが、OSイメージは同じなため多分状況変わらず)。そのため、C++11の正規表現C++14の利用が難しい状況です。そこで、Raspbian上にLLVM, clang, libc++ 3.8を適用し、ビルド環境と標準ライブラリをバージョンアップします。

前提

  • Raspberry Pi 2 Model B以上(多分3 Model Bでも行けると思う)
  • 空きストレージ容量4GByte以上
  • Raspbian(update, upgrade済み)
  • オフィシャル提供のclang, libc++との共存は考慮していません。

作業前に

LLVMらのコンパイル作業はクロスコンパイラではなく、Raspberry Pi実機上で行いました。 コンパイルには大量のメモリが必要になるため、作業前に使っていないサービスを停止しておいてください。 Xも起動せず、フレームバッファ・コンソールかSSHでの作業をオススメします。

<インストール先>パスについて

何も設定しない場合、デフォルトのインストール先は/usr/local以下となります。 大体の場合、そのままでOKだと思いますが、cmakeは野良ビルドしたものと既存のものが混在するため、パスを明示しています。

cmakeのコンパイル & インストール

Raspbianのaptでインストールできるcmakeではバージョン不足でコンパイルができません。 先にcmakeを用意します。

$ sudo apt-get install pkg-config automake libtool libffi-dev libatomic1 gcc-4.8 g++-4.8 zlib-bin
$ mkdir <作業ディレクトリ>
$ cd <作業ディレクトリ>
$ wget https://cmake.org/files/v3.5/cmake-3.5.0.tar.gz
$ tar vzxf cmake-3.5.0.tar.gz
$ cd cmake-3.5.0
$ ./configure --prefix=<インストール先>
$ make -j2
$ sudo make install

LLVM, clang, libc++のコンパイル & インストール

コンパイル作業はオフィシャルのマニュアルに従い進めます。一部オプションをRaspbian用にカスタマイズします。 Getting Started with the LLVM System — LLVM 3.8 documentation

LLVM, clang, libc++のコンパイル & インストールはいっぺんに行います。 libc++abiはコンパイルに失敗したので外しています。

$ cd <作業ディレクトリ>
$ wget http://llvm.org/releases/3.8.0/llvm-3.8.0.src.tar.xz  http://llvm.org/releases/3.8.0/cfe-3.8.0.src.tar.xz http://llvm.org/releases/3.8.0/compiler-rt-3.8.0.src.tar.xz http://llvm.org/releases/3.8.0/libcxx-3.8.0.src.tar.xz http://llvm.org/releases/3.8.0/openmp-3.8.0.src.tar.xz
$ tar -Jxvf llvm-3.8.0.src.tar.xz
$ tar -Jxvf cfe-3.8.0.src.tar.xz
$ tar -Jxvf compiler-rt-3.8.0.src.tar.xz
$ tar -Jxvf libcxx-3.8.0.src.tar.xz
$ tar -Jxvf openmp-3.8.0.src.tar.xz
$ $ mv cfe-3.8.0.src llvm-3.8.0.src/tools/clang
$ mv compiler-rt-3.8.0.src llvm-3.8.0.src/projects/compiler-rt
$ mv libcxx-3.8.0.src llvm-3.8.0.src/projects/libcxx
$ mv openmp-3.8.0.src llvm-3.8.0.src/projects/openmp
$ cd llvm-3.8.0.src/
$ mkdir build
$ cd build
$ <インストール先>/cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=<インストール先> -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 -DLIBCXX_CXX_ABI=libstdc++ -DLLVM_TARGETS_TO_BUILD="ARM;X86;AArch64" ..
$ make -j2
$ sudo make install

メモリ不足でmakeに失敗する場合、-j2オプションを外してください(-j2で2並列にしています。)

インストール先として/usr/local以外を指定している場合、環境変数PATH, LD_LIBRARY_PATHなどにインストール先を追加します。 .bashrcなどに以下のように追記します。

export PATH=$PATH:<インストール先>/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:<インストール先>/lib

記載内容を以下のとおり反映します。

$ source ~/.bashrc

まだ、ldconfigのパスも追加しておきます。 /etc/ld.so.conf.d/clang.confなどのファイルを作成し、以下のようにパスを追加します

<インストール先>/lib

記載内容を以下のとおり反映します。

$ sudo ldconfig

確認

最後にインストールしたclangが有効になっているか確認します。

$ clang --version