脫離 IDE,在 Linux 終端機掌握 GCC 編譯鏈全貌,是深入理解 C 程式建構過程的最佳途徑。本文以實戰範例拆解 GCC 四大階段、核心參數與分步編譯技巧。
| 工具 | 角色 | 常見選擇 |
|---|---|---|
| 編輯器 | 撰寫原始碼 | Vim, Emacs, VS Code, Sublime Text |
| 編譯器 | 原始碼 → 機器碼 | GCC (GNU Compiler Collection) |
| 除錯器 | 運行時檢查 | GDB (GNU Debugger) |
| 建構工具 | 自動化依賴與編譯 | Make / CMake |
IDE 只是將上述四者整合圖形化;掌握命令列操作能讓你在無圖形介面的伺服器/嵌入式環境也能自如開發。
.i 檔。.i → 組合語言 .s。.s → 目的檔 .o(機器碼,含符號表、重定位資訊)。.o + 函式庫 → 執行檔(ELF 格式)。| 參數 | 作用 | 範例 |
|---|---|---|
-E | 僅預處理,輸出 .i | gcc -E test.c -o test.i |
-S | 編譯至組語,輸出 .s | gcc -S test.i -o test.s |
-c | 編譯+組譯至 .o,不連結 | gcc -c test.c -o test.o |
-o file | 指定輸出檔名 | gcc test.c -o test |
-g | 嵌入除錯資訊(給 GDB 用) | gcc -g test.c -o test |
-O0/-O1/-O2/-O3 | 最佳化等級(預設 O2) | gcc -O2 test.c -o test |
-static | 靜態連結 | gcc -static test.c -o test |
-shared | 產生動態庫 | gcc -shared -fPIC lib.c -o lib.so |
-Wall -Wextra | 開啟常見警告 | gcc -Wall -Wextra test.c |
-std=c11 | 指定 C 標準 | gcc -std=c11 test.c |
gcctest.c#include
int main(void) {
printf("This is a gcc test!\n");
return 0;
}
$ gcc gcctest.c -o gcctest
$ ./gcctest
This is a gcc test!
# 1. 預處理
$ gcc -E gcctest.c -o gcctest.i
# 2. 編譯為組語
$ gcc -S gcctest.i -o gcctest.s
# 3. 組譯為目的檔
$ gcc -c gcctest.s -o gcctest.o
# 或直接從 .c
$ gcc -c gcctest.c -o gcctest.o
# 4. 連結生成執行檔
$ gcc gcctest.o -o gcctest
# 或用 ld 手動連結(需指定啟動檔、libc 路徑)
$ ld gcctest.o -o gcctest
.i:展開後的完整原始碼(含 stdio.h 內容),龐大。.s:x86-64 組語,可見 main:、call puts、堆疊框架建立/銷毀指令。.o:ELF 目的檔,objdump -d gcctest.o 可反組譯檢視。gcc -save-temps test.c 自動留存 .i/.s/.o。gcc -dM -E - < /dev/null。gcc -fanalyzer test.c(GCC 10+)。aarch64-linux-gnu-gcc test.c -o test_arm64。