1. 程式人生 > >LLVM/clang & lib路徑 & 測試程式碼

LLVM/clang & lib路徑 & 測試程式碼

安裝

方法一

下載 LLVM、clang 及輔助庫原始碼:

先關掉其他應用,儘量多的系統資源留給 GCC 進行編譯 clang 原始碼

  • mkdir build
  • cd build
  • ../configure –enable-optimized CC=/usr/bin/GCC CXX=/usr/bin/g++
  • 接下來,你先洗個澡,再約個會,回來應該編譯好了(thinkpad T410I,CPU 奔騰雙核 P6000,MEM 4G DDRIII,耗時 2 小時
  • clang –version 進行確認

方法二

  • 上面的方法在無線網的環境下可能比較慢,推薦下面這種方法
下載llvm的原始碼
下載clang的原始碼
下載clang-tools-extra的原始碼
  • cd llvm/tools/clang/tools
  • tar xf clang-tools-extra-3.6.0.src.tar.xz
  • mv clang-tools-extra-3.6.0.src extra
  • cd ../../../..
下載compiler-rt的原始碼
  • cd llvm/projects
  • tar xf compiler-rt-3.6.0.src.tar.xz
  • mv compiler-rt-3.6.0.src compiler-rt
  • cd ../..

配置編譯選項

  • cd ..
  • ./configure –enable-optimized CC=gcc CXX=g++
  • 注意:3.7.0以後,不允許在原始碼樹中進行構建,我們可以在llvm原始碼目錄同級目錄中建立一個目錄build目錄,然後使用絕對路徑進行構建
  • make -j2 編譯llvm
  • 編譯成功後的提示:
  • llvm[0]: * Completed Release+Asserts Build
  • make install 安裝編譯好的llvm
  • clang –version 會安裝在/usr/local/bin中,檢查clang的版本
  • clang version 3.6.0 (tags/RELEASE_360/final)
如果還是舊版本,需要將/usr/bin/clang指向clang 3.6.0:
  • ln -s /usr/local/bin/clang /usr/bin/clang

方法三

  • 有更加簡單的方法… 預編譯包
  • 其實Ubuntu14.04安裝LLVM/clang-3.7很簡單,直接到LLVM官網(http://llvm.org/releases/download.html)下載ubuntu預編譯包(Pre-Built Binaries)——Clang for x86_64 Ubuntu 14.04 (.sig)
  • 然後解壓,進入到解壓的資料夾裡(裡面有四個資料夾bin,include,lib,share),將這四個資料夾拷到/usr/local下
  • sudo cp -r ~/放解壓檔案的目錄名/clang+llvm-3.7.0-x86_64-linux-gnu-ubuntu-14.04/* /usr/local
  • clang –v 檢視版本
  • libc++和libc++abi已經配置好,直接使用即可(以前的3.6版本的是沒有配置好的,需要自己配置)
  • 其它Linux作業系統下載對應的相關預編譯包,按照前述步驟也可使用。想要知道預編譯包是否配置了 libc++和libc++abi,可到解壓的檔案裡的lib資料夾裡看看是否有libc++.so,libc++.so.1,libc++.so.1.0,libc++abi.a,libc++abi.so,libc++abi.so.1,libc++abi.so.1.0檔案,有的話就表示支援
  • 如果下載速度慢…百度雲 神器…

測試程式碼

  • 建立一個名為main.cpp的文件,寫入
    #include <iostream>
    #include <string>
    class MyClass
    {
      public:
      std::string s ="Hello, world\n"; // Non-static data member initializer
    };
    int main()
    {
      std::cout << MyClass().s;
    }
  • 在終端輸入
  • clang++ -std=c++11 -stdlib=libc++ -Werror -Weverything -Wno-disabled-macro-expansion -Wno-float-equal -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-global-constructors -Wno-exit-time-destructors -Wno-missing-prototypes -Wno-padded -Wno-old-style-cast -lc++ -lc++abi main.cpp
  • 如果沒問題的話會生成a.out的二進位制檔案,執行它會顯示出Hello,world
  • 這一大波編譯選項很崩潰麼 @[email protected]!我來簡單說說:
  • -std=c++11:使用 C++11 新特性;
  • -stdlib=libc++:指定使用 clang 的標準庫標頭檔案 /usr/include/c++/v1/;
  • -Werror:將所有編譯警告視為編譯錯誤;
  • -Weverything:開啟所有編譯警告選項。在 GCC 中,無法通過單個選項開啟所有編譯警告,必須繁瑣的同時指定 -Wall、-Wextra、以及大量分散的其他選項,為此 clang 新增了 -Weverything。
  • 當然,有些警告意義不大,完全可忽略,如下:
  • -Wno-disabled-macro-expansion:禁止使用巨集表示式,忽略此警告;
  • -Wno-float-equal:浮點型別不應使用 != 和 == 運算子,忽略此警告;
  • -Wno-c++98-compat、-Wno-c++98-compat-pedantic:採用 C++11 新特性的程式碼無法相容 C++98,忽略此警告;
  • -Wno-global-constructors:在 main() 之前存在執行的程式碼,忽略此警告;
  • -Wno-exit-time-destructors:在 main() 之後存在執行的程式碼,忽略此警告;
  • -Wno-missing-prototypes:雖有函式定義但缺失函式原型,忽略此警告;
  • -Wno-padded:結構體大小應為 4 位元組整數倍,忽略此警告(編譯器自動調整對齊邊界);
  • -Wno-old-style-cast:C 語言的強制型別轉換,忽略此警告;
  • -lc++:指定連結 /usr/lib/libc++.so 標準庫(缺失將導致連結失敗!);
  • -lc++abi:指定連結 /usr/lib/libc++abi.so 標準庫(缺失將導致連結失敗!)。
  • 詳細的見Github的參考文章

新增庫檔案路徑

  • 第一次執行可能會報找不到庫檔案的錯誤
Find where the library is placed if you don’t know it.
  • cd /
  • sudo find ./ | grep the_name_of_the_file.so
Check for the existence of the dynamic library path environnement variable(LD_LIBRARY_PATH)
  • echoLD_LIBRARY_PATH
  • if there is nothing to be display we need to add the default path value (or not as you wich)
  • $ LD_LIBRARY_PATH=/usr/local/lib
We add the desire path and export it and try the application
  • LDLIBRARYPATH=LD_LIBRARY_PATH:/my_library/path.so.something
  • $ export LD_LIBRARY_PATH
  • $ ./my_app
或者在/etc/bash.bashrc中新增
  • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

分隔符

附錄

  • LLVM 是個很大很大的專案群,幾乎把從編譯到除錯的各個構建環節都重新實現了一遍,目的:一是儘可能地模組化現有程式碼以方便在此基礎上進行二次開發、一是提供比傳統構建工具鏈更好的使用者體驗。clang是LLVM的子專案,是一款非常優秀的C++ 編譯器,前端 clang + 後端 LLVM(後簡稱 LLVM/clang)就是一款可替代 GCC 的優秀編譯
  • GCC 配套的標準庫涉及 libstdc++ 和 libsupc++ 兩個子庫,前者是介面層(即,上層的封裝),後者是實現層(即,底層的具體實現),對應到clang,則libc++(介面層)和 libc++abi(實現層)