對於日常的應用程序開發,咱們不多須要關注編譯
和連接
過程。咱們日常Xcode
開發就是集成的的開發環境(IDE)
,這樣的IDE通常都將編譯
和連接
的過程一步完成,一般將這種編譯
和連接
合併在一塊兒的過程稱爲構建
,即便使用命令行來編譯一個源代碼文件,簡單的一句gcc hello.c
命令就包含了很是複雜的過程!前端
正是由於集成開發環境的強大,不少系統軟件的
運行機制與機理
被掩蓋,其程序的不少莫名其妙的錯誤讓咱們無所適從,面對程序運行時種種性能瓶頸咱們一籌莫展。咱們看到的是這些問題的現象,可是卻很難看清本質,全部這些問題的本質就是軟件運行背後的機理及支撐軟件運行的各類平臺和工具
,若是能深刻了解這些機制,那麼解決這些問題就可以遊刃有餘。linux
如今咱們經過一個C語言的經典例子,來具體瞭解一下這些機制:面試
#include <stdio.h>
int main(){
printf("Hello World");
return 0;
}
複製代碼
在linux下只須要一個簡單的命令(假設源代碼文件名爲hello.c):後端
$ gcc hello.c
$ ./a.out
Hello World
複製代碼
其實上述過程能夠分解爲四步:bash
首先是源代碼文件hello.c
和相關的頭文件(如stdio.h
等)被預編譯器cpp
預編譯成一個.i
文件。第一步預編譯的過程至關於以下命令(-E 表示只進行預編譯):app
$ gcc –E hello.c –o hello.i
複製代碼
還能夠下面的表達工具
$ cpp hello.c > hello.i
複製代碼
預編譯過程主要處理源代碼文件中以」#」開頭的預編譯指令。好比#include、#define
等,主要處理規則以下:性能
#define
刪除,並展開全部的宏定義#if,#ifdef,#elif,#else,#endif
#include
預編譯指令,將被包含的文件插入到該預編譯指令的位置。//
和/**/
#2 「hello.c」 2。
#pragma
編譯器指令截圖個你們看看效果優化
通過預編譯後的文件(.i文件)
不包含任何宏定義,由於全部的宏已經被展開,而且包含的文件也已經插入到.i文件
中,因此當咱們沒法判斷宏定義是否正確或頭文件包含是否正確時,能夠查看預編譯後的文件來肯定問題。ui
編譯過程就是把預處理完的文件進行一系列的:詞法分析
、語法分析
、語義分析
及優化後生產相應的彙編代碼文件
,此過程是整個程序構建的核心部分,也是最複雜的部分之一。其編譯過程至關於以下命令:
$ gcc –S hello.i –o hello.s
複製代碼
經過上圖咱們不可貴出,經過命令獲得彙編輸出文件
hello.s
.
彙編器是將彙編代碼轉變成機器能夠執行的指令,每個彙編語句幾乎對應一條機器令。
因此彙編器的彙編過程相對於編譯器來說比較簡單,它沒複雜的語法,也沒有語義,也不須要作指令優化,只是根據彙編指令和機器指令的對照表一一翻譯就能夠了。其彙編過程至關於以下命令:
as hello.s –o hello.o
複製代碼
或者
gcc –c hello.s –o hello.o
複製代碼
或者使用gcc
命令從C源代碼文件
開始,通過預編譯、編譯和彙編直接輸出目標文件:
gcc –c hello.c –o hello.o
複製代碼
連接一般是一個讓人比較費解的過程,爲何彙編器不直接輸出可執行文件而是輸出一個目標文件呢?爲何要連接?下面讓咱們來看看怎麼樣調用ld
才能夠產生一個可以正常運行的Hello World
程序:
注意默認狀況沒有gcc / 記得 :
$ brew install gcc
複製代碼
連接相應的庫
下面在貼出咱們的寫出的源代碼是如何變成目標代碼的流程圖:
主要經過咱們的編譯器作了如下任務:掃描、語法分析、語義分析、源代碼優化、代碼生成和目標代碼優化
到這咱們就能夠獲得如下的文件,不知道你是否有和我一塊兒操做,玩得感受仍是不錯,繼續往下面看
iOS如今爲了達到更牛逼的速度和優化效果,採用了LLVM
LLVM採用三相設計,前端Clang負責解析,驗證和診斷輸入代碼中的錯誤,而後將解析的代碼轉換爲LLVM IR,後端LLVM編譯把IR經過一系列改進代碼的分析和優化過程提供,而後被髮送到代碼生成器以生成本機機器代碼。
編譯器前端的任務是進行:在這個過程當中,會進行類型檢查,若是發現錯誤或者警告會標註出來在哪一行。
以上圖解內容所作的是事情和gcc
編譯一模模同樣樣!
.app
包,後面編譯後的文件都會被放入包中;Cocoapods
會預設一些腳本,固然你也能夠本身預設一些腳原本運行。這些腳本都在 Build Phases
中能夠看到;Mach-O
,這過程 LLVM
的完整流程,前端、優化器、後端;storyboard
文件:storyboard
文件也是會被編譯的;storyboard
文件:將編譯後的 storyboard
文件連接成一個文件;Asset
文件:咱們的圖片若是使用 Assets.xcassets
來管理圖片,那麼這些圖片將會被編譯成機器碼,除了 icon
和 launchImage
;Cocoapods
腳本:將在編譯項目以前已經編譯好的依賴庫和相關資源拷貝到包中。.app
包Swift
標準庫拷貝到包中編譯過程的確是個比較複雜的過程,還有連接!並非說難就不須要掌握,我我的建議每個進階路上iOS開發人員,都是要了解一下的。不須要你多麼牛逼,可是你能在平時的交流討論,面試中能點出一個兩個相應的點,我相信絕對是逼格滿滿!