LLVM是一個Open Source Project (https://github.com/llvm/llvm-project),這個Project主要用意是可以讓所有人使用這個Framework來設計Compiler。例如C/C++的Compiler Clang就是一個LLVM所產生的compiler。
- [延伸閱讀] LLVM教學(1): 5分鐘了解LLVM架構
在這篇LLVM教學文章中,將會針對LLVM 在Github上的資料夾結構進行介紹。希望能夠讓第一次接觸到LLVM的人能夠更輕易地了解這些檔案目錄在llvm-project中所代表的意義以及了解哪些工具是被包含在這裡面的。

LLVM的資料夾結構
llvm-project內含有多的子項目或稱為專案(Project),每一個Project都存在於各自的資料夾內,且使用同樣的方式編排其檔案架構。接下來的文章將會以llvm-project作為根目錄來進行描述。在進入llvm-project的Repository時,大致可以將此目錄底下的Project分成三類
LLVM Core Libraries
LLVM最主要核心的函示庫是在llvm這個資料夾底下。
llvm
這裡面提供了許多用於程式編譯優化(Optimizers)的函式庫以及產生機器碼的函式庫(Code Generation)。這些LLVM Core Libraries都是使用C++實作完成。在llvm這個資料夾底下,也有提供相關的工具來協助程式優化以及機器碼產生。接下來簡單介紹幾個比較重要的工具。
llvm/tools
- llc: 將LLVM-IR編譯成機器碼(bitcode)、組合語言(assembler)、或是一個物件檔(Object file)。
- llvm-objdump: 可以使用此Tool去分析一個Object file。可以看到此物件檔內部有多少symbols或是有哪些sections等資訊。
- llvm-ar: 這個工具稱為LLVM Archiver。使用者可以利用這個工具去將多個Object files彙整產生一個LLVM archive file。
- llvm-mc: 這個工具可用來生成或是解析機器指令。當要新增一個指令到ISA時。
- bugpoint: 這是一個LLVM debug工具。
Compilers and Tools
clang是什麼?
clang是一個可使用在C/C++/Objective-C/Object-C++的編譯器,而它也屬於llvm-project,是一個使用LLVM製作的編譯器。這裡面提供了許多Compiler Frontend的功能,包含lexing, parsing,語意分析(semantic analysis)以及生成LLVM-IR的功能。在clang這個資料夾底下,也有提供相關的工具來協助這個編譯器的使用。這邊簡單介紹幾個我在進行軟體開發工作上比較常用的工具。
clang/tools
- clang-format: 這是一個用來統整Coding Style非常好用的工具。這個工具可以自動格式化你所輸入的C/C++程式碼轉換成符合使用者規定的 Coding Style。目前可以支援的格式有LLVM、 GNU、Google、Chromium、Microsoft、Mozilla、WebKit。也可以自行編寫.clang-format來定義Coding Style。通常在一個大型軟體開發專案中,如果參與的每個人因為個人習慣或是使用的IDE介面不同而各自有各自的Coding Style,這可能在開發過程造成一些困擾。因此,統一Coding Style在實務上對於軟體開發會是非常有幫助的。
- clang-tidy: 這是對於程式碼進行靜態分析(Lint)的工具,是clang-based C++ Linter。這個工具使用clang的函式庫來分析程式碼並且標記程式碼中可能產生問題的部分,例如Memory Leak(Allocate記憶體卻沒有歸還)或是宣告了變數卻完全沒有使用。這個工具比起編譯器本身更有機會找到潛在的Bugs。
lld
lld是LLVM Linker。用來將所以由Compiler所產生的Object Files連結在一起成為一個可執行檔(Executable)。這個資料夾中包含lld的程式碼。這個Linker支援ELF、COFF、Mach-O以及WebAssembly等格式。
lldb
lldb是LLVM的debugger。在開發一個專案時,在過程中肯定會遇到Bug。因此Debug的工具就顯得很重要。LLVM也提供了其開發時所使用的Debug Tools,也就是lldb。這個工具的使用的介面與GDB類似。
Runtime Libraries
除了編譯器以外,執行程式時所需的函示庫(Runtime Libraries)也是一個完整的程式語言所需要提供的。以下介紹各個Runtime Library,每一個Library的程式碼都位於根目錄下相對應的資料夾中。
- compiler-rt: 提供與語言本身無依賴性的支援。例如64-bit在32-bit架構上的除法功能,或是各種不同的Sanitizer Coverage等測試相關功能,以及提供一些統計數據等功能。
- libunwind: 提供Help Functions以便實作例外處理(Exception Handling)。
- libcxx: 提供C++標準函式庫。
- libc: 提供C語言函式庫。
- openmp: 支援OpenMP API。可用於設計平行程式計算。
llvm-project中Project內的資料夾結構(以clang為範例說明)
在瞭解了有哪些llvm-project包含了哪些Project後,接下來深入介紹各自Project內的資料夾結構。接下來這的文章將會以clang這一個Project作為範例說明,但由於每一個Project都是使用同樣的方式編排其檔案架構,因此同樣的規則可套用至llvm、libc、mlir…等等在llvm-project底下的其他Project。
clang/CMakeList.txt
由於都是使用CMake來build每一個專案,因此在每一個Project中都會有一個CMakeList.txt檔案來描述該Project的編譯參數。如果有其他需要的CMake Modules或是檔案也都會在cmake資料夾中定義,例如其他需要的CMake Modules會被放在cmake/modules資料夾底下。
clang/lib
llvm-project中的每個Project大多是以C++實作,且每個專案所使用的程式碼都放在個別專案內lib資料夾底下。例如,clang的程式碼就在clang/lib裏面。而其他Project也是一樣,例如llvm的程式碼就在llvm/lib裏面。
clang/include
每個專案所使用到的標頭檔(Header file)就是在個別專案裡的include資料夾裡,但是在include資料夾中會多一層來區分一些同名的Header files。
clang/tools
如文章先前提到的,使用者會使用到的工具(例如clang-format和clang-tidy)放在這個資料夾中。
clang/utils
clang在編譯與測試時所使用到相關的應用,其程式碼都會在此資料夾內。
clang/unittest
此資料夾內含有各個使用Google Test Framework的unit tests的程式碼。
clang/docs
clang這個Project的文件檔案都在這裡面。
clang/examples
屬於該專案的使用範例則是放在examples這個資料夾中。
總結
llvm-project這樣設計的好處是可以提高每一個專案中Library被重複使用的機會。假設今天想要進行編譯器設計,其Frontend就可以去clang/lib中找想要使用的Library來使用。而如果想要在這個Compiler中加入什麼現有的Optimization Pass,也可以到個別專案中去找適合的Library來直接使用。藉此縮短一個新的Compiler的開發過程。
希望透過這篇文章的介紹可以幫助讀者更快的了解LLVM這個Repository的資料夾結構,方便大家更快速的了解這個專案的內容。








