0. 流程概覽
- 編譯流程:預處理 → 編譯 → 彙編 → 鏈接
- 詳細
- → 源代碼(source code).c / .cpp
- 預處理器(processor)→ ?
- 編譯器(compiler)→ 彙編代碼(assembly code).s
- 彙編器 (assembler)→ 目標程序(object code).o /.obj
- 鏈接器(linker) → 可執行程序(executables)/ .exe
1. 預處理
經過預處理,會產生一個沒有宏定義,沒有條件編譯指令,沒有特殊符號的輸出文件;
僅僅是文件內容上的變化;
- 讀取C/C++源程序,對其中的僞指令(以#開頭的指令)進行處理
- 解決宏定義:刪除 #define ,展開所有宏定義
- 處理條件編譯指令:如 #if #ifdef #elit #else #endif 等,會過濾掉不必要的代碼
- 處理#include預編譯指令,將被包含的文件插入到預編譯指令的位置(遞歸進行,因爲被#include的文件可能還#include了其他文件)
- 刪除所有註釋:// /**/
- 添加行號和文件名標識:便於調試
- 保留所有的 #pragma 編譯器指令
2. 編譯
- 詞法分析、語法分析、語義分析、優化(分爲針對代碼的優化和針對計算機的優化)
- 產生彙編代碼;
- 針對一個編譯單元:一個.cpp文件以及其中 #include 的 .h 文件
3. 彙編
- 將編譯完的彙編代碼文件翻譯成機器指令(2進制),並生成可重定位目標程序的.o文件
- 基本一條彙編語句對應一條機器指令。(對應的是虛擬地址)
- 目標程序:
- .o / .obj文件:每個cpp文件都會被編譯成一個.o文件
4. 鏈接
- 通過鏈接器將一個個目標文件(或許還有庫文件)鏈接在一起生成一個完整的可執行程序。
- 將 .obj 文件與庫文件 .lib 等鏈接,生成可執行文件 .exe,使得這些目標文件稱爲一個能夠被OS裝入執行的統一整體。
- 比如:某個源文件中的函數引用了另一個源文件中定義的某個符號(變量或者函數調用等);或者是調用了某個庫文件中的函數等等。
- .cpp文件以分離的方式經過編譯彙編以後,再進行鏈接。(否則該 .o 文件總不一定有main函數)
參考資料: