Linux下編譯clang、libcxx及其相關庫——C++11環境搭建

一、編譯llvm(同時編譯compiler-rt和clang)

1、下載llvm代碼:

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

2、進入llvm/tools目錄,下載clang編譯器代碼:

cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

3、進入llvm/projects目錄,下載Compiler-RT代碼:

cd ../.. (back to where you started)
cd llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt

4、在llvm所在目錄新建與llvm同一級的目錄build,在其中構建llvm和clang:

cd ../.. (back to where you started)
mkdir build (for building without polluting the source dir)
cd build
../llvm/configure
make

【說明】:至此,設置環境變量後,clang及clang++就可以使用了,但如果你還想使用clang++ + libcxx模式,那麼請接着下面的步驟接着編譯libcxx和libcxxabi。

 

二、使用clang++編譯libcxx和libcxxabi

1、下載libcxx和libcxxabi代碼:

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

2、進入libcxx/lib目錄進行編譯:

./buildit

【說明】:如果要用libcxx + libcxxabi的組合替換掉libstdc++,需要將buildit文件中的-lstdc++選項去掉。

3、進入libcxxabi/lib目錄進行編譯:

./buildit

【說明】:(1)如果要用libcxx + libcxxabi的組合替換掉libstdc++,需要將buildit文件中的-lstdc++選項去掉。
          (2)編譯過程中可能會報出找不到<unwind.h>頭文件的錯誤,是因爲在Mac系統下<unwind.h>是系統頭文件(libcxxabi主要還是用在Mac上,似乎Linux上更多的人推薦用libcxxrt),而在Linux中<unwind.h>在/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include/unwind.h目錄下(其中目錄名稱與處理器結構和編譯器版本有關)。可以有兩種解決方法:
                A、如果要使用libcxxabi + libunwind的方式,可以指定-I${libunwind-path}/include選項包含libunwind中的頭文件,這樣的話可能還需要安裝libunwind庫;
                B、另一種方法就是使用libcxxabi + libgcc_s的方式這就需要使用/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include目錄下的<unwind.h>,但該目錄下還有<stddef.h>、<stdarg.h>之類的頭文件,如果你使用-I選項指定了該目錄,或許是你的編譯器所不願看到事,而libcxxabi中僅僅是需要<unwind.h>中的聲明而已,因此可以簡單地將/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include/unwind.h拷貝到libcxxabi/include目錄下。可是即便是這樣,還是有關於__attribute__((__mode__(__unwind_word__)))的錯誤,對於此錯誤暫沒做深入分析,猜測次編譯器擴展中的__unwind_word__只有gcc才認識,你可以簡單地將__unwind_word__定義爲__word__(#define __unwind_word__ __word__),或將__attribute__((__mode__(__unwind_word__)))註釋起來,我就是這麼幹的,暫沒發現錯誤。

4、手動安裝libc++庫和libc++abi庫及其頭文件,如:

複製代碼
cd /usr/lib64
ln -s ${libcxx-path}/lib/libc++.so.1.0 libc++.so.1
ln -s libc++.so.1 libc++.so
ln -s ${libcxxabi-path}/lib/libc++abi.so.1.0 libc++abi.so.1
ln -s libc++abi.so.1 libc++abi.so
cd /usr/include/c++
ln -s ${libcxx-path}/include v1
複製代碼

【說明】:(1)當使用-stdlib=libc++選項後,clang++默認會從/usr/include/c++/v1目錄查找libc++頭文件;
          (2)上面沒有列出${libcxxabi-path}/include的安裝位置,此項安裝因編譯器而異,需要替換掉編譯器中的相關頭文件。

 5、使用clang++ + libcxx + libcxxabi編譯程序(如:test.cpp):

clang++ -std=c++0x -stdlib=libc++ -lc++abi test.cpp

【說明】:(1)要是最新的clang,上面的-std=c++0x選項可以改爲-std=c++11了;

          (2)-lc++abi要單獨指定顯得很累贅,clang-developers論壇中有說將libc++abi靜態鏈接到libc++中就不用顯示指定了,本人沒測試過,只在此記錄一下,以後若有必要再做測試。

 

三、STL、ABI、UNWIND層次關係

從libcxx和libcxxabi的主頁中可以看出:libc++是C++標準庫的一份新的實現,支持C++11新標準,而libc++abi是一份新的支撐(support for)C++標準庫的底層實現。這裏的libcxx就屬於STL層,而libcxxabi則屬於ABI層,而unwind暫時不瞭解,只知道ABI層得依賴於它。下圖中列出了各個層次中典型的庫:

理論上講,各個層次的組合都可以使用,但是各個庫對C++11的支持程度不一樣,因此不見得所有組合都能使用,常見的組合有:
(1) libcxx + libcxxabi + libgcc_s
(2) libcxx + libcxxabi + libunwind
(3) libcxx + libcxxrt + libunwind
(4) libstdc++(包括了libsupc++) + libgcc_s
(5) STLport + libsupc++ + libgcc_s

 

參考:
http://clang.llvm.org/get_started.html
http://libcxx.llvm.org/
http://libcxxabi.llvm.org/
http://clang-developers.42468.n3.nabble.com/libc-abi-on-linux-td4025203.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章