LLVM與Clang

     隨着 Android P 的逐步應用,越來越多的客戶要求編譯庫時用 libc++ 來代替 libstdc++。libc++ 和 libstdc++ 這兩個庫有關係呢?它們兩個都是 C++ 標準庫,libc++ 是針對 Clang 編譯器特別重寫的 C++ 標準庫,而 libstdc++ 則是 GCC 的對應 C++ 標準庫了。從 Android 市場來說,Android NDK 已在具體應用中放棄了 GCC,全面轉向 Clang。

Android NDK 從 r11 開始建議大家切換到 Clang,並且把 GCC 標記爲 deprecated,將 GCC 版本鎖定在 GCC 4.9 不再更新;
Android NDK 從 r13 起,默認使用 Clang 進行編譯,但是暫時也沒有把 GCC 刪掉,Google 會一直等到 libc++ 足夠穩定後再刪掉 GCC;
Android NDK 在 r17 中宣稱不再支持 GCC 並在後續的 r18 中刪掉 GCC,具體可見 NDK 的版本歷史。

     接下來,簡要的介紹一下 Clang。Clang 是一個 C、C++、Objective-C 和 Objective-C++ 編程語言的編譯器前端,採用底層虛擬機(LLVM)作爲後端。至於爲什麼有了 GCC 還要開發 Clang?Clang 相比 GCC 又有什麼優勢呢?網上有很多信息可以參考,這裏只簡單提兩點:(1)Clang 採用的是 BSD 協議的許可證,而 GCC 採用的是 GPL 協議,顯然前者更爲寬鬆;(2)Clang 是一個高度模塊化開發的輕量級編譯器,編譯速度快、佔用內存小、有着友好的出錯提示。

     然後說下 Clang 背後的 LLVM(Low Level Virtual Machine)。LLVM 是以 BSD 許可來開發的開源的編譯器框架系統,基於 C++ 編寫而成,利用虛擬技術來優化以任意程序語言編寫的程序的編譯時間、鏈接時間、運行時間以及空閒時間,最早以 C/C++ 爲實現對象,對開發者保持開放,併兼容已有腳本。LLVM 計劃啓動於 2000 年,最初由 University of Illinois at Urbana-Champaign 的 Chris Lattner 主持開展,2006 年 Chris Lattner 加盟蘋果公司並致力於 LLVM 在蘋果公司開發體系中的應用,所以蘋果公司也是 LLVM 計劃的主要資助者。目前 LLVM 因其寬鬆的許可協議,更好的模塊化、更清晰的架構,成爲很多廠商或者組織的選擇,已經被蘋果 IOS 開發工具、Facebook、Google 等各大公司採用,像 Swift、Rust 等語言都選擇了以 LLVM 爲後端。

      在理解 LLVM 之前,先說下傳統編譯器的工作原理,基本上都是三段式的,可以分爲前端、優化器和後端。前端負責解析源代碼,檢查語法錯誤,並將其翻譯爲抽象的語法樹;優化器對這一中間代碼進行優化,試圖使代碼更高效;後端則負責將優化器優化後的中間代碼轉換爲目標機器的代碼,這一過程後端會最大化的利用目標機器的特殊指令,以提高代碼的性能。基於這個認知,我們可以認爲 LLVM 包括了兩個概念:一個廣義的 LLVM 和一個狹義的 LLVM 。廣義的 LLVM 指的是一個完整的 LLVM 編譯器框架系統,包括了前端、優化器、後端、衆多的庫函數以及很多的模塊;而狹義的 LLVM 則是聚焦於編譯器後端功能的一系列模塊和庫,包括代碼優化、代碼生成、JIT 等。

下面大概講一講 LLVM 和 Clang 的關係。我們將它們對應於傳統的編譯器當中的幾個獨立的部分,這樣能夠更加方便明確的表述出它們之前的關係。

Clang LLVM

對應到這個圖中,可以非常明確的找出它們的關係。整體的編譯器架構就是 LLVM 架構;Clang 大致可以對應到編譯器的前端,主要處理一些和具體機器無關的針對語言的分析操作;編譯器的優化器和後端部分就是之前提到的 LLVM 後端,即狹義的 LLVM。

此外,由於 LLVM 的命名最早源自於底層虛擬機(Low Level Virtual Machine) 的首字母縮寫,但這個項目的範圍並不侷限於創建一個虛擬機,這個縮寫導致了大量的疑惑。LLVM 成長之後已成爲衆多編譯工具及低級工具技術的統稱,使得這個名字變得更不貼切,所以開發者決定放棄這個縮寫的涵義,現在 LLVM 已獨立成爲一個品牌,適用於 LLVM 下的所有項目,包括 LLVM 中介碼、LLVM 除錯工具、LLVM C++ 標準庫等。
原文鏈接:

https://xuhehuan.com/2738.html


Clang LLVM

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