# 默認輸出 a.out
gcc test.c
# 指定輸出文件名
gcc test.c -o myapp
gcc -o myapp test.c # 順序無關
# 僅編譯不鏈接,產生目標文件 test.o
gcc -c test.c
# 顯式鏈接目標文件
gcc test.o -o myapp
# 鏈接 pthread 線程庫(-l 必須放在源文件/目標文件之後!)
gcc test.c -o myapp -lpthread
gcc -o myapp test.c -lpthread
# 指定庫搜索路徑 -L,頭文件路徑 -I
gcc -I/usr/local/include -L/usr/local/lib test.c -lmylib
鏈接順序鐵律:gcc [源文件/目標文件] -o 輸出 -L路徑 -l庫名。庫必須在依賴它的文件**之後**,否則符號解析失敗。
# 文件:main.c, one.c, two.c, one.h, two.h
gcc -c one.c # → one.o
gcc -c two.c # → two.o
gcc -c main.c # → main.o
gcc main.o one.o two.o -o main
./main
缺點:修改一個文件需重新編譯所有,無增量構建。
# 目標: 依賴文件
# 構建命令
main: main.o one.o two.o
gcc -o main main.o one.o two.o
main.o: main.c one.h two.h
gcc -c main.c
one.o: one.c one.h
gcc -c one.c
two.o: two.c two.h
gcc -c two.c
# 清理
clean:
rm -f main main.o one.o two.o
執行 make 自動比對時間戳,僅重編修改過的文件。
CC = gcc
CFLAGS = -Wall -O2
OBJS = main.o one.o two.o
main: $(OBJS)
$(CC) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f main $(OBJS)
| 自動變量 | 含義 |
|---|---|
$@ | 目標文件名 |
$< | 第一個依賴文件 |
$^ | 所有依賴文件(去重) |
$? | 比目標新的依賴文件 |
.c.o(內置規則已足夠)現代 Make 內置 .c.o 規則,無需顯式寫 %.o: %.c。只需定義 CC、CFLAGS、目標依賴即可。
CC = gcc
CFLAGS = -Wall -Wextra -O2 -std=c11
LDFLAGS = -lm -lpthread
TARGET = myapp
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS)
clean:
rm -f $(TARGET) $(OBJS)
.PHONY: all clean
特性:自動收集所有 .c、模式編譯、標準偽目標。
#include "one.h"(雙引號,搜索當前目錄優先)。#include (尖括號,搜索系統路徑)。-I. 確保當前目錄在包含路徑中。
# 臨時設置
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
# 永久設置(~/.bashrc)
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib' >> ~/.bashrc
source ~/.bashrc
# 或編譯時嵌入 rpath(推薦)
gcc -Wl,-rpath,/usr/local/lib -L/usr/local/lib test.c -lmylib
| 選項 | 作用 |
|---|---|
-Wall -Wextra | 開啟大多數警告 |
-Werror | 警告視為錯誤 |
-O2 | 優化等級 2(推薦發布) |
-g | 生成調試信息 |
-std=c11 | 指定 C 標準 |
-DDEBUG | 定義宏 |
-E | 僅預處理 |
-S | 生成匯編 |
-c | 僅編譯不鏈接 |