2013-04-20

GNU/Linuxでlibc++をビルドする方法

"libc++" C++ Standard Library

まず、libc++をチェックアウトする。

$ svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx

libc++をビルドするにあたっては、使用するC++ABIライブラリを明示的に指定しなければならない。C++ABIライブラリは、例外やRTTIや名前マングリングといったC++の低級層のABIを提供するライブラリである。GNU/Linuxでは、デファクトスタンダードである Itanium C++ ABIが使われている。

C++ABIの実装は複数ある。そのため、どの実装を使うのか選ばなければならない。GCCによるC++ABI実装は、libsupc++だ。libsupc++を使うことの利点は、GCCとC++ABIの互換性を保てるという事だ。

LLVMでも、C++ABIの実装であるlibc++abiを提供している。これを使う手もある。

さらに、C++ABIの実装は他にもある。今回はGCCとの互換性を考え、libsupc++を利用することにする。

libsupc++を利用するには、libsupc++のヘッダーファイルがあるディレクトリを明示的に指定しなければならない。Ubuntuでは、/usr/include/c++/ と /usr/include/c++/<version>/<target-triple> だ。includeディレクトリは以下のようなコマンドを使えば確かめることができる。

$ echo | g++ -Wp,-v -x c++ - -fsyntax-only

Ubuntu 12.10では、/usr/include/c++/4.7 と /usr/include/c++/4.7/x86_64-linux-gnu になる。

libc++のビルドシステムにはcmakeが使われている。だいたい以下のような感じでビルドできる

$ svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
$ cd libcxx
$ mkdir build
$ cd build
$  CC=clang CXX=clang++ cmake -G "Unix Makefiles" -DLIBCXX_CXX_ABI=libsupc++ -DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.7/;/usr/include/c++/4.7/x86_64-linux-gnu/" -DCMAKE_BUILD_TYPE=Release ..
$ make

..はlibcxxのディレクトリへのパスだ。今回は親ディレクトリになる。ビルドが無事成功すれば、ビルドしたディレクトリの/libにlibcxx.soができる。

あとはmake installすればいいのだが、trunkを引っ張ってくるという事は、ちょくちょくビルドするだろうし、このまま使いたい。そのためには、libc++へincludeパスを指定し、libcxx.soへのライブラリのパスも追加しなければならない。

$ export LD_LIBRARY_PATH=<libcxx.soをビルドしたディレクトリへのパス>/lib
$ clang++ -std=c++11 -stdlib=libc++ -nostdinc++ -I<libcxxへのパス>/include -L<libcxx.soをビルドしたディレクトリへのパス>/lib test.cpp

とりあえず色々試してみたが、libc++のビルドさえやり遂げれば、あとは拍子抜けするほどあっさりと使える。libc++はC++11のライブラリを完全に実装している。clangもC++11のコア言語を完全に実装しているので、とうとうC++11の完全な実装が実現した。

本の虫: clangのビルドも参照のこと。

追記:

libc++をアップデートする方法であるが、単にsvn updateしてmakeすればいい。CMAKEから生成されたMakefileは、変更を検知して、自動的にcmakeを再実行してくれるので、再び空のビルド用ディレクトリでcmakeから始めてすべてをビルドする必要はない。

No comments: