掌握編譯鏈路是進階 C 程序員的必修課。本文以 gcc 為例,詳細拆解預處理、編譯、匯編、鏈接四大階段,並展示每階段的中間產物與命令。
gcc -o test test.c # 實際包含四個階段
命令:gcc -E test.c -o test.i
處理對象:以 # 開頭的預處理指令
#define、#undef#ifdef/#ifndef/#else/#endif#include 展開__FILE__、__LINE__、__DATE__、__TIME__產物:test.i(無宏、無條件編譯、已展開頭文件的純 C 代碼)
命令:gcc -S test.i -o test.s
動作:詞法/語法分析 → 生成匯編語言(.s 文件)
示例輸出片段:
.file "test.c"
.section .rodata
.LC0:
.string "hello world"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
...
call puts
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
命令:gcc -c test.s -o test.o
動作:將匯編指令翻譯為機器碼,生成目標文件(.o,ELF 格式)
目標文件結構:
.text):指令,只讀可執行.data/.bss):全局/靜態變量.symtab)、字符串表(.strtab).rela.text 等)命令:gcc test.o -o test
核心任務:
.a)代碼、記錄動態庫(.so)依賴。產物:最終可執行文件(ELF Executable),可直接由加載器運行。
| 類型 | 生成命令 | 用途 |
|---|---|---|
| 可重定位文件 | gcc -c | 鏈接輸入,包含代碼/數據/符號表 |
| 共享目標文件 | gcc -shared -fPIC | 動態鏈接庫(.so),運行時加載 |
| 可執行文件 | gcc -o | 直接運行,進程映像 |
gcc -E test.c -o test.i # 只預處理
gcc -S test.c -o test.s # 只編譯到匯編
gcc -c test.c -o test.o # 編譯+匯編到目標文件
gcc test.o -o test # 只鏈接
gcc -Wall -O2 test.c -o test # 開啟警告+優化
gcc -static test.c -o test # 強制靜態鏈接
理解四階段有助於:
建議動手實驗各階段產物,配合 objdump、readelf、nm 等工具觀察目標文件結構,深化理解。