一条获、歷史
? ? LLVM 是一個模塊化和可重用的編譯器和工具鏈技術(shù)的集合疆栏,Clang 是 LLVM 的子項目贬媒,是 C洋魂,C++ 和 Objective-C 編譯器绷旗,因為多模塊的復(fù)用,所以提供了驚人的快速編譯副砍,據(jù)說比 GCC 快3倍衔肢。
解釋一下上圖:
1)Frontend(編譯器前端):編譯器前端的任務(wù)是解析源代碼。它會進(jìn)行:詞法分析豁翎,語法分析角骤,語義分析, 檢查源代碼是否存在錯誤,然后構(gòu)建抽象語法樹(Abstract Syntax Tree,AST) ,LLVM的前端還會生成中間代碼(intermediate representation , IR)心剥。
2)Optimizer(優(yōu)化器):優(yōu)化器負(fù)責(zé)進(jìn)行各種優(yōu)化邦尊。改善代碼的運(yùn)行時間,例如消除冗余計算等优烧。
3)Backend(后端):將代碼映射到目標(biāo)指令集胳赌。生成機(jī)器語言,并且進(jìn)行機(jī)器相關(guān)的代碼優(yōu)化
二匙隔、編譯過程
我們通過終端中輸入clang -ccc-print-phases main.m,得到如下打友妗:
? ? ? ? ? ? ? ? +- 0: input, "main.m", objective-c? //輸入
? ? ? ? ? ? +- 1: preprocessor, {0}, objective-c-cpp-output //預(yù)處理
? ? ? ? +- 2: compiler, {1}, ir //編譯
? ? ? +- 3: backend, {2}, assembler //后端
? +- 4: assembler, {3}, object //匯編
+- 5: linker, {4}, image //鏈接
6: bind-arch, "x86_64", {5}, image //綁定
得到了7步操作的簡要說明纷责,分別是:
0:導(dǎo)入文件:是為了找到源文件。
1:預(yù)處理階段:這個過程處理包括宏的替換撼短,頭文件的導(dǎo)入再膳,會生成 main.i 文件,其中 objective-c-cpp-output 中的 cpp 不是指 C++ 語言曲横,而是 c preprocessor 的縮寫喂柒。
2:編譯階段:進(jìn)行詞法分析不瓶、語法分析、檢測語法是否正確灾杰,最終生成IR蚊丐。
3:后端:這里L(fēng)LVM會通過一個一個的Pass去優(yōu)化,每個Pass做一些事情艳吠,最終生成匯編代碼麦备,生成一個 main.s 文件。
4:匯編:生成目標(biāo)文件昭娩,即為 main.o凛篙。
5:鏈接:鏈接需要的動態(tài)庫和靜態(tài)庫,生成可執(zhí)行文件栏渺,最終生成 image呛梆。
6:綁定:通過不同的架構(gòu),生成對應(yīng)的可執(zhí)行文件磕诊,默認(rèn)生成x86_64平臺填物。
具體每步驟的詳解請看參考教程4.?LLVM系列(二)Clang編譯過程詳解
三、常用命令
1. 無選項編譯鏈接
用法:#clang hello.c
作用:將hello.c預(yù)處理秀仲、匯編融痛、編譯并鏈接形成可執(zhí)行文件。這里未指定輸出文件神僵,默認(rèn)輸出為a.out雁刷。編譯成功后可以看到生成了一個a.out的文件。在命令行輸入./a.out 執(zhí)行程序保礼。./表示在當(dāng)前目錄沛励,a.out為可執(zhí)行程序文件名。
2. 選項 -o
用法:#clang hello.c -o hello
作用:將hello.c預(yù)處理炮障、匯編目派、編譯并鏈接形成可執(zhí)行文件hello.c。-o選項用來指定輸出文件的文件名胁赢。輸入./hello執(zhí)行程序企蹭。
3. 選項 -E
用法:#clang -E hello.c -o hello.i
作用:將hello.c預(yù)處理輸出hello.i文件。
4. 選項 -S
用法:#clang -S hello.i
作用:將預(yù)處理輸出文件hello.i匯編成hello.s文件智末。
5. 選項 -c
用法:#clang -c hello.s
作用:將匯編輸出文件hello.s編譯輸出hello.o文件谅摄。
6. 無選項鏈接
用法:#clang hello.o -o hello
作用:將編譯輸出文件hello.o鏈接成最終可執(zhí)行文件hello。輸入./hello執(zhí)行程序系馆。
如果想直接輸入hello就運(yùn)行送漠,需要把hello復(fù)制到目錄/usr/bin下
7. 選項-O
用法:#clang -O1 hello.c -o hello
作用:使用編譯優(yōu)化級別1編譯程序。級別為1~3由蘑,級別越大優(yōu)化效果越好闽寡,但編譯時間越長代兵。輸入./hello執(zhí)行程序。
8.編譯使用C++ std庫的程序
用法:#clang hello.cpp -o hello -l std c++ 作用:將hello.cpp編譯鏈接成test可執(zhí)行文件爷狈。-l? std? c++指定鏈接std c++庫植影。
9. 分別編譯各個源文件,之后對編譯后輸出的目標(biāo)文件鏈接淆院。 用法:
#clang -c hi.c? ? ? ? // 將hi.c編譯成hi.o
#clang -c hello.c? ? // 將hello.c編譯成hello.o
參考教程:
2.?clang&llvm簡介
3.?LLVM系列(一)致敬