LLVM(1)-編譯自己的LLVM和Clang

1窄锅、引言

作為一名iOS開發(fā)芥驳,很難不從各種渠道聽說關于LLVM的消息僵腺,如早年編譯器從GCC過度到LLVM-GCC呵晚,然后由于GCC的開源協(xié)議改變瘩欺,讓Apple徹底拋棄GCC轉而投向目前正在使用的Clang必盖。比如之前微信團隊分享的編譯優(yōu)化。再如之后業(yè)內影響頗大的字節(jié)團隊分享的二進制重排提及的插裝所知的也是clang俱饿。在安全方面歌粥,對LLVM pass的開發(fā)也是主力軍等等。拍埠。失驶。

所以適當的了解LLVM對自己的知識廣度是有非常大的幫助的,最少在讀一篇有深度的文章的時候枣购,不至于摸不到門檻嬉探。

2、什么是LLVM棉圈,什么是Clang

LLVM 最早是底層虛擬機(Low Level Virtual Machine)的縮寫涩堤,但由于項目發(fā)展過快,底層虛擬機已經不足以介紹項目本身分瘾,而它已經發(fā)展成為一個包含前端胎围,優(yōu)化器和后端的完整編譯框架,并且全稱就叫LLVM德召,并非任何英文的簡稱了白魂。其主要由C++編寫而成。

一上岗、什么是LLVM

傳統(tǒng)編譯器架構

傳統(tǒng)編譯器架構(如GCC)將前端福荸,優(yōu)化器,后端耦合在一起液茎,優(yōu)化難度大逞姿,對多架構兼容的也不太友好,需要做大量重復的工作捆等。


傳統(tǒng)的編譯器架構.png
LLVM架構

LLVM架構三端(前端滞造,優(yōu)化器,后端)清晰
1栋烤、前端面向源碼谒养,將源碼轉化為同樣的LLVM Intermediate Representation (LLVM IR),
2、優(yōu)化器則針對LLVM IR進行一系列優(yōu)化买窟,如:無用代碼消除丰泊,內存優(yōu)化,甚至是代碼混淆等等始绍。瞳购。。
3亏推、后端則將IR轉化為對應的機器碼学赛。


LLVM架構.png

從兩種架構的設計可以看得出來,LLVM最大的優(yōu)勢就在于三端分離吞杭,所以如果我們想編寫一門獨立的語言盏浇,只需要編寫相應的前端就可以兼容各大終端設備。如果以后多了一種終端設備芽狗,我們也只需要編寫一次后端绢掰,就可以兼容各大語言。

二童擎、什么是Clang

Clang是LLVM項目的一個子項目滴劲,基于LLVM架構的C/C++/Objective-C編譯器前端(Swift的前端是Swift)。

Apple早年從GCC切換到LLVM的時候顾复,開始用的是基于GCC庫寫的一套LLVM前端哑芹,但由于Apple對代碼優(yōu)化的要求更高,而GCC官方又遲遲不肯對針對性的更新捕透,所以衍生出GCC的一套分支LLVM-GCC聪姿,由Apple自己維護,導致Apple使用的GCC版本遠低于官方版本乙嘀,最后由于GCC的開源協(xié)議改變末购,讓Apple徹底拋棄GCC轉而投向自研的Clang。

相比于GCC虎谢,Clang具有如下優(yōu)點:
· 編譯速度快:在某些平臺上盟榴,Clang的編譯速度顯著的快過GCC(Debug模式下編譯OC速度比GGC快3倍)
· 占用內存小:Clang生成的AST所占用的內存是GCC的五分之一左右
· 模塊化設計:Clang采用基于庫的模塊化設計,易于 IDE 集成及其他用途的重用
· 診斷信息可讀性強:在編譯過程中婴噩,Clang 創(chuàng)建并保留了大量詳細的元數據 (metadata)擎场,有利于調試和錯誤報告
· 設計清晰簡單,容易理解几莽,易于擴展增強

3迅办、編譯過程

① 下載

找到一個自己方便的目錄,直接在github上下載(耗時根據網絡情況而定章蚣,包括git文件總大小大概3G):


image.png
> mkdir llvm_all && cd llvm_all   
> git clone https://github.com/llvm/llvm-project.git

完成后你將會看到這樣一個目錄:


image.png

目前我們只需要關注其中兩個文件clangllvm分別是clang的源碼和llvm的源碼

② 編譯

cmake -S llvm -B build -G <generator> [options]

官方介紹了4種編譯工具:

  • Ninja --- for generating Ninja build files. Most llvm developers use Ninja.
  • Unix Makefiles --- for generating make-compatible parallel makefiles.
  • Visual Studio --- for generating Visual Studio projects and solutions.
  • Xcode --- for generating Xcode projects.

官方推薦使用Ninja編譯站欺,因為其速度最快,筆者也親試,整個過程只需20分鐘左右即可完成矾策。但作為一名iOS開發(fā)磷账,還是習慣使用Xcode編譯,畢竟界面看起來親切贾虽,而且可在之后我們編寫插件的或者IR Pass的時候也能或得良好的代碼提示逃糟,缺點就是慢一點。筆者使用Xcode編譯花了40分鐘左右蓬豁,這根據個人電腦配置而定履磨,配置稍微差一點,一個小時多也是正常的庆尘。

另外還有一些可選參數:

  • -DLLVM_ENABLE_PROJECTS='...' --- 可選一些LLVM的子項目共同編譯,如 clang, clang-tools-extra, libcxx, libcxxabi, libunwind, lldb, compiler-rt, lld, polly, 或者 cross-project-tests
    例如巷送,如果要編譯包括 Clang, libcxx, 和 libcxxabiLLVM, 可以增加 -DLLVM_ENABLE_PROJECTS="clang;libcxx;libcxxabi"
  • -DCMAKE_INSTALL_PREFIX=directory --- 指定一個絕對地址來存放編譯的結果驶忌,默認存放在/usr/local.
  • -DCMAKE_BUILD_TYPE=type --- 這是編譯的類型,如Debug, Release, RelWithDebInfo, 和 MinSizeRel. 默認的是Debug.
  • -DLLVM_ENABLE_ASSERTIONS=On --- 在啟用斷言檢查的情況下編譯(對于Debug構建笑跛,默認值為Yes付魔,對于所有其他構建類型,默認值為No).
Ninja編譯

所以如果需要使用Ninja編譯的話命令飞蹂,需要先創(chuàng)建Ninja模板(大概5分鐘)几苍,然后再編譯:

// 創(chuàng)建ninja的目錄,并且進入其中
mkdir llvm_ninja && cd llvm_ninja   
// 指定llvm源碼目錄陈哑,新建build目錄妻坝,創(chuàng)建ninja模板,增加子項目clang惊窖,并且模板之后編譯的結果放在llvm_release目錄下
cmake -S ../llvm-project/llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS="clang" -DCMAKE_INSTALL_PREFIX=/Volumes/ExDisk/LLVM/llvm_all/llvm_release
image.png

從上圖中可以看到刽宪,我們增加的clang參與了編譯,而clang-tools-extra沒有參與編譯界酒。

如果你看到下面這樣的結果圣拄,那么恭喜ninja模板已經建好

image.png

image.png

然后進入模板目錄,輸入命令開始編譯

cd build
ninja && ninja install
image.png

完成后可以在指定的release目錄下看到所有的命令了


image.png
Xcode編譯

同樣的先在對應的目錄下毁欣,生成Xcode模板庇谆,但xcode就不指定對應的release目錄了,因為做iOS開發(fā)的應該都知道凭疮,Xcode的編譯產物有對應的product文件(大概10分鐘)

mkdir llvm_xcode && cd llvm_xcode
cmake -S ../llvm-project/llvm -B build -G Xcode -DLLVM_ENABLE_PROJECTS="clang" 
image.png

同樣饭耳,結束后可以看到這樣的目錄


image.png
image.png

打開LLVM工程,回到了熟悉的畫面


image.png

選中Automatically Creat Schemes后执解,在選擇al_build哥攘,cmd+b即可開始編譯(大概40分鐘)。


image.png

在熟悉的地方可以看到對應的編譯產物


image.png

在同級目錄下,可以看到對應的命令行工具逝淹,比如我們下章需要講到的clang耕姊。


image.png

4、總結

為什么編譯單獨拿出來栅葡?LLVM就想一個含羞的蒙面女子茉兰,大多數人都是只可遠觀,而不敢褻玩欣簇,其實蒙面女子本身也是及其渴望有個勇士來揭開其面紗规脸,而編譯自己的LLVM就像是這么一步,只要自己邁出了這一步熊咽,那么就是個嶄新的世界莫鸭。

下一章,就會開始聊一些好玩的事情横殴,比如如何編譯自己的插件被因,如何開發(fā)自己混淆器,如何開發(fā)自己的一門開發(fā)語言衫仑。

參考

1梨与、 GCC,LLVM文狱,Clang編譯器對比
2粥鞋、 微信團隊分享的編譯優(yōu)化
3、 深入剖析 iOS 編譯 Clang LLVM
4瞄崇、 LLVM Github地址

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末呻粹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子苏研,更是在濱河造成了極大的恐慌尚猿,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件楣富,死亡現(xiàn)場離奇詭異凿掂,居然都是意外死亡,警方通過查閱死者的電腦和手機纹蝴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門庄萎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人塘安,你說我怎么就攤上這事糠涛。” “怎么了兼犯?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵忍捡,是天一觀的道長集漾。 經常有香客問我,道長砸脊,這世上最難降的妖魔是什么具篇? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮凌埂,結果婚禮上驱显,老公的妹妹穿的比我還像新娘。我一直安慰自己瞳抓,他們只是感情好埃疫,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著孩哑,像睡著了一般栓霜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上横蜒,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天胳蛮,我揣著相機與錄音,去河邊找鬼愁铺。 笑死,一個胖子當著我的面吹牛闻鉴,可吹牛的內容都是我干的茵乱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼孟岛,長吁一口氣:“原來是場噩夢啊……” “哼瓶竭!你這毒婦竟也來了?” 一聲冷哼從身側響起渠羞,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤斤贰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后次询,有當地人在樹林里發(fā)現(xiàn)了一具尸體荧恍,經...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年屯吊,在試婚紗的時候發(fā)現(xiàn)自己被綠了送巡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡盒卸,死狀恐怖骗爆,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情蔽介,我是刑警寧澤摘投,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布煮寡,位于F島的核電站,受9級特大地震影響犀呼,放射性物質發(fā)生泄漏幸撕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一圆凰、第九天 我趴在偏房一處隱蔽的房頂上張望杈帐。 院中可真熱鬧,春花似錦专钉、人聲如沸挑童。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽站叼。三九已至,卻和暖如春菇民,著一層夾襖步出監(jiān)牢的瞬間尽楔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工第练, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阔馋,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓娇掏,卻偏偏與公主長得像呕寝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子婴梧,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內容