OC是用Clang/LLVM來編譯的。接下來我將用clang來展開整個過程。main.m文件源碼以下:程序員
//main.m文件 #import <stdio.h> int main(int argc, const char * argv[]) { printf("hello ~"); return 0; } 複製代碼
平時用Xcode去Build,一鍵從源碼到程序。這個過程當中隱藏了預處理、編譯、彙編和連接4個過程以下:bash
clang -E main.m -o main.i
複製代碼
處理源代碼文件中的以"#"開頭的預編譯指令。規則以下:markdown
clang -S main.i -o main.s
複製代碼
編譯就是把上面獲得的.i文件進行:詞法分析、語法分析、靜態分析、優化生成相應的彙編代碼,獲得.s文件。函數
clang -c main.s -o main.o
複製代碼
彙編就是把上面獲得的.s文件裏的彙編指令一一翻譯成機器指令。獲得.o文件,也就是目標文件,後面會重點講的Mach-O文件。post
clang main.o -o main
複製代碼
遠古時代,一個程序只有一個源代碼文件,致使程序的維護很是困難。如今程序都是分模塊組成,好比一個App,對應有多個源代碼文件。每一個源代碼文件彙編成目標文件,根據上面流程A目標文件訪問B目標文件的函數或者變量,是不知道地址的,連接就是要解決這個問題。連接過程主要包括地址和空間分配、符號決議和重定位。優化
連接就是把目標文件(一個或多個)和須要的庫(靜態庫/動態庫)連接成可執行文件。後面會分別講靜態連接和動態連接。ui
《程序員的自我修養-連接、裝載與庫》spa