make 依據 Makefile 中定義的**目標-依賴-命令**規則,構建有向無環圖 (DAG),透過檔案修改時間戳比較決定哪些目標需要重建。本文詳細解析 make 的啟動流程、依賴遞迴解析、時間戳判斷邏輯、偽目標處理,並說明為何修改單一來源檔僅觸發最小必要重建。
target ... : prerequisites ...
command
...
make 無參數)Makefile 或 makefile。edit)。
edit : main.o kbd.o command.o display.o
cc -o edit main.o kbd.o command.o display.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
clean :
rm edit *.o
修改 command.h → kbd.o、command.o 時間戳過舊 → 重新編譯兩者 → edit 依賴更新 → 重新連結。
修改 defs.h → 所有 .o 依賴它 → 全部重編 → 重新連結。
| 行為 | 說明 |
|---|---|
| 只管依賴關係 | 命令失敗 (編譯錯誤) 由編譯器負責,make 僅檢查檔案是否存在 |
| 缺少依賴檔直接報錯退出 | 若依賴鏈末端原始碼不存在,make 停止並報錯 |
| 偽目標不在依賴鏈中 | clean 無被任何目標依賴,make 不會自動執行,需 make clean 顯式呼叫 |
| 時間戳精度 | 秒級 (部分系統支援奈秒),若複製檔案保留時間戳可能導致誤判 |
CC = gcc
CFLAGS = -Wall -O2
OBJS = main.o kbd.o command.o display.o
edit : $(OBJS)
$(CC) -o $@ $^
%.o : %.c defs.h
$(CC) $(CFLAGS) -c $< -o $@
clean :
rm -f edit $(OBJS)
$@:目標檔名;$^:所有依賴;$<:第一個依賴。%.o : %.c 自動套用所有 .c→.o 編譯。.c.o,簡單專案可無需顯式寫編譯規則。make -jN 並行建構 (N=CPU 核心數),大幅加速大型專案。.PHONY: clean install 避免與同名檔案衝突。.d (GCC -MMD -MP) 自動追蹤 #include 變動。