my_app: main.o app1.o app2.o
gcc -o my_app main.o app1.o app2.o
main.o: main.c
gcc -c main.c
...
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
CC = gcc
CFLAGS = -g -Wall -O0
INCLUDES = -I/path/include
LIBS = -L/path/lib
TARGET = my_app
$(TARGET): $(OBJS)
$(CC) $^ -o $@ $(INCLUDES) $(LIBS)
%.o: %.c
$(CC) -c $< $(CFLAGS)
clean:
rm -f *.o
.PHONY: clean
| 語法 | 含義 |
|---|---|
$(wildcard *.c) | 展開當前目錄所有 .c 檔案 |
$(SRCS:.c=.o) | 替換副檔名 .c → .o |
$@ | 目標檔案名(規則冒號左側) |
$^ | 所有相依檔案(冒號右側,去重) |
$< | 第一個相依檔案 |
%.o: %.c | 模式規則:所有 .o 由同名 .c 編譯 |
.PHONY: clean | 宣告偽目標,避免同名檔案干擾 |
VPATH = src:include 或遞迴 Makegcc -MM -MT $@ -MF $(@:.o=.d) $< 產生 .d 檔,include $(wildcard *.d)make DEBUG=1 → CFLAGS += -DDEBUG -O0make -j$(nproc)= (遞迴展開) vs := (立即展開) vs ?= (條件賦值)CMake、Meson、Bazel 等建置系統提供跨平台、IDE 整合、依賴管理等進階功能,大型專案建議遷移。