什麼是 clang/llvm/libc++
先說一下背景,以防有些同學對 clang/llvm/libc++ 是什麼還沒有概念:
clang 是最近幾年(在大財主蘋果的支持下)發展得非常好的 C 家族語言 (包括C/C++/Obj-C/Obj-C++) 編譯器前端,所謂前端,就是它可以認識 C/C++/Obj-C/ObjC++ 代碼,並且把它轉化成某種更接近機器指令的形式。理論上說,“某種形式”是語法樹,但作爲一個工具,clang 實際上會幫助你調用鏈接器生成可執行代碼,這跟 gcc 是一樣的。
llvm 是一個通用的編譯優化和代碼生成平臺,它定義了一箇中間語言 LLVM IR,只要前端把代碼編譯成 LLVM IR,就可以使用 llvm 豐富的優化模塊和代碼生成模塊。換句話說,llvm 讓“創造一種計算機語言”變成了一個相對容易的事情,這件事情會有深遠的影響。
libc++ 是針對 clang 特別重寫的 C++ 標準庫,也算是 clang 的“御用”庫了。這就像 libstdc++ 和 gcc 的關係,但 clang 也可以用 libstdc++,這是本文的主題之一。
使用預編譯的 clang
新鮮出爐的 clang/llvm 3.0 可以在這裏下載,它提供了 Debian/FreeBSD9/MacOS X/Ubuntu 11.04, 11.10 的預編譯二進制文件。假設你用的和我一樣是版本足夠的 Ubuntu ,那就只需要下載相應文件,展開,然後把文件拷到 /usr/local 底下就好了。例如下載的是 clang+llvm-3.0-i386-linux-Ubuntu-11_10.tar.gz ,則
tar xvf clang+llvm-3.0-i386-linux-Ubuntu-11_10.tar.gz
cd clang+llvm-3.0-i386-linux-Ubuntu-11_10
sudo cp -r * /usr/local
事實上這樣就可以用了,即便沒有 libcxx 也沒關係,clang 可以使用 libstdc++ 。譬如一個經典的 hello.c (內容就不必多說了),用
clang hello.c
./a.out
應該就可以看到結果。
加上 libc++
如果想要用 libc++ ,需要拿下它的代碼,自己編譯,不過非常容易。首先保證你有 subversion:
sudo apt-get install subversion
然後從 libc++ 代碼倉庫下載代碼:
svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
隨後進入目錄 libcxx 並編譯
cd libcxx/lib
./buildit
編譯沒問題的話,會在 lib 目錄下生成一個 libc++.so.1.0 文件,把它拷貝到 /usr/lib,並加上兩個符號鏈接:
sudo cp ./libc++.so.1.0 /usr/lib
cd /usr/lib
sudo ln -sf libc++.so libc++.so.1.0
sudo ln -sf libc++.so.1 libc++.so.1.0
然後,由於 clang 認爲 libc++ 頭文件位於 /usr/include/c++/v1 底下,只需要把 libcxx/include 這個目錄鏈接到該處就好了,換句話說,如果你
ls /usr/include/c++/v1
看到熟悉的 C++ 標準庫頭文件們,那就對了。
使用 clang++/libc++
clang 3.0 支持幾個連 gcc 4.6 都沒支持的 C++11 特性,比如初始化非靜態類成員,看看下面的代碼 (new_feature.cpp):
1 #include <iostream> 2 #include <string> 3 4 class MyClass 5 { 6 public: 7 std::string s = "Hello, world\n"; // Non-static data member initializer 8 }; 9 10 int main() 11 { 12 std::cout << MyClass().s; 13 }
第7行直接在類聲明處初始化一個 std::string 成員,這是原本只在 Java/C# 裏面才能做的事情,如今終於飛入 C++ 程序中。編譯命令:
clang++ --std=c++0x -stdlib=libc++ new_feature.cpp
./a.out
輸出熟悉的
Hello, world
我們的 clang 就算正式能用了。