iOS底層探索(二) - 寫給小白看的Clang編譯過程原理
寫在前面:
本系列為 『iOS底層探索系列』第一篇陵像,本文源自本人的學(xué)習(xí)記錄整理與理解知举,其中參考閱讀了部分優(yōu)秀的博客和書籍,盡量以通俗簡(jiǎn)單的語句轉(zhuǎn)述添坊。引用到的地方如有遺漏或未能一一列舉原文出處還望見諒與指出剿另,另,文章內(nèi)容如有不妥之處還望指教贬蛙。十分感謝雨女。
入門起步
從編譯器說起
-
為什么需要編譯?
- 大家都知道速客,我們的計(jì)算機(jī)CPU只能讀懂機(jī)器碼(machine code戚篙,也就是由一堆0和1組成的編碼);
- 但我們現(xiàn)在編寫的代碼并不是機(jī)器碼溺职,而是高級(jí)編程語言(Objective-C岔擂、Swift、Java浪耘、...)乱灵,最終也可以被計(jì)算機(jī)所執(zhí)行,
- 這就需要編譯了七冲,在編譯的過程中痛倚,編譯器的作用便是把我們的高級(jí)編程語言通過一系列的操作轉(zhuǎn)化成可被計(jì)算機(jī)執(zhí)行的機(jī)器語言。
ps:[更詳細(xì)的解析可以自行百度]
-
編譯器是如何設(shè)計(jì)的澜躺?
-
經(jīng)典的三段式設(shè)計(jì)(three phase design):
前端(Frontend)--優(yōu)化器(Optimizer)--后端(Backend)
(見下圖)
- 其中前端負(fù)責(zé)分析源代碼蝉稳,可以檢查語法級(jí)錯(cuò)誤,并構(gòu)建針對(duì)該語言的抽象語法樹(AST)
- 抽象語法樹可以進(jìn)一步轉(zhuǎn)換為優(yōu)化掘鄙,最終轉(zhuǎn)為新的表示方式耘戚, 然后再交給讓優(yōu)化器和后端處理
- 最終由后端生成可執(zhí)行的機(jī)器碼
-
為什么要使用三段式設(shè)計(jì)??jī)?yōu)勢(shì)在哪操漠?
- 首先解決了一個(gè)很大的問題:假如有N種語言(C收津、OC、C++浊伙、Swift...)的前端撞秋,同時(shí)也有M個(gè)架構(gòu)(模擬器、arm64嚣鄙、x86...)的Target吻贿,是否就需要 N × M 個(gè)編譯器?
- 三段式架構(gòu)的價(jià)值就體現(xiàn)出來了哑子,通過共享優(yōu)化器的中轉(zhuǎn)舅列,很好的解決了這個(gè)問題奉芦。
-
假如你需要增加一種語言,只需要增加一種前端剧蹂;假如你需要增加一種處理器架構(gòu),也只需要增加一種后端烦却,而其他的地方都不需要改動(dòng)宠叼。這復(fù)用思想很牛逼吧。(如下圖)
-
- 編譯源文件有哪些主要步驟其爵?
- 先列舉一些整個(gè)編譯過程的主要步驟冒冬,后面再詳細(xì)介紹每個(gè)步驟都做了哪些事情。
- 主要編譯步驟如下:
1. 源代碼(source code) -> 2. 預(yù)處理器(preprocessor) -> 3. 編譯器(compiler) -> 4. 匯編程序(assembler) -> 5. 目標(biāo)代碼(object code) -> 6. 鏈接器(Linker) -> 7. 可執(zhí)行文件(executables)
Xcode編譯器發(fā)展簡(jiǎn)史
Xcode3 以前: GCC摩渺;
Xcode3: 增加LLVM简烤,GCC(前端) + LLVM(后端);
Xcode4.2: 出現(xiàn)Clang - LLVM 3.0成為默認(rèn)編譯器摇幻;
Xcode4.6: LLVM 升級(jí)到4.2版本横侦;
Xcode5: GCC被廢棄,新的編譯器是LLVM 5.0绰姻,從GCC過渡到Clang-LLVM的時(shí)代正式完成
- 為什么蘋果的Xcode會(huì)使用Clang+LLVM取代GCC枉侧?
- 這里面有些歷史原因。畢竟GCC是第三方開源的狂芋,不屬于蘋果維護(hù)也不能完全掌控其開發(fā)進(jìn)程榨馁,Apple為Objective-C增加許多新特性,但GCC開發(fā)者對(duì)這些支持卻不友好帜矾;Apple需要做模塊化翼虫,GCC開發(fā)者卻拖著遲遲不實(shí)現(xiàn)。這能忍屡萤?
- 隨著Apple對(duì)其IDE(也就是Xcode)性能的要求越來越高珍剑,最終還是從零開發(fā)了一個(gè)Clang前端加LLVM后端的編譯器,這個(gè)編譯器的作者是大名鼎鼎的Swift之父Chris Lattner灭衷。
- Clang比GCC優(yōu)秀在哪些方面次慢?
- 傳說新的Clang編譯器編譯Objective-C代碼速度比GCC快3倍
- 并且提供了友好的代碼提示
Clang 的簡(jiǎn)介
“Clang: a C language family frontend for LLVM”
LLVM的C語言家族(C、C++翔曲、OC)前端迫像。---- Clang
- 上面是官網(wǎng)對(duì)于Clang的一句話介紹,其實(shí) Clang 就是上文所提到的編譯器前端
- 用途:輸出代碼對(duì)應(yīng)的抽象語法樹(Abstract Syntax Tree, AST)瞳遍,并將代碼編譯成LLVM Bitcode闻妓。接著在后端(back-end)使用LLVM編譯成平臺(tái)相關(guān)的機(jī)器語言。
LLVM 的簡(jiǎn)介
- LLVM :顧名思義是(Low Level Virtual Machine)底層虛擬機(jī)掠械?注意了由缆,已經(jīng)不是了注祖!
- 官網(wǎng)都說了:LLVM就是這個(gè)項(xiàng)目的全稱,包含LLVM中介碼(LLVM IR)均唉、LLVM除錯(cuò)工具是晨、LLVM C++標(biāo)準(zhǔn)庫(kù)等一套工具,和傳統(tǒng)底層虛擬機(jī)并沒什么關(guān)系舔箭。
PS:下一篇將介紹Clang與LLVM的詳細(xì)編譯過程罩缴,歡迎關(guān)注。
參考文檔
http://clang.llvm.org/
http://www.aosabook.org/en/llvm.html
http://history.programmer.com.cn/9436/
https://zh.wikipedia.org/wiki/Clang
https://zh.wikipedia.org/wiki/LLVM