簡介?:
?????????Makefile? 是一種用于自動化構建和管理軟件項目的工具文件,通常與
make
命令配合使用。它通過定義?規則?(rules)來指定如何從源文件生成目標文件(如可執行程序或庫),并自動處理文件之間的依賴關系。Makefile 的核心思想是“僅重新構建需要更新的部分”,從而顯著提高編譯效率。
一、基礎語法快速入門
由目標(target)、依賴(prerequisites)、命令(commands)三部分組成,如
目標:依賴命令 ?# 命令前必須以 Tab 縮進app: main.o utils.o ?gcc main.o utils.o -o app ?#將main.o和utils.o聯合編譯成app ? main.o: main.c gcc -c main.c -o main.o #將main.c編譯生成main.o ? utils.o:utils.cgcc -c utils.c -o utils.o #將utils.c編譯生成utils.o
運行 make app觸發編譯流程,此時將會生成main.o、utils.o和可執行文件app。
二、變量和自動變量的使用
簡化重復值(如編譯器路徑或 flags)和簡化命令中的重復輸入,如:
app: main.o utils.o?gcc main.o utils.o -o app?$@: 當前目標名(app)。 $^: 所有依賴(main.o utils.o)。 $<: 第一個依賴文件(main.o)。?#當然也可以替換為其他變量,類似于C語言中的變量+宏定義 CC = gcc CFLAGS = -Wall -O2 OBJS = main.o utils.o#將main.c編譯生成main.o main.o: main.cgcc -Wall -O2 -c main.c -o main.o #第一種寫法$(CC) $(CFLAGS) -c $< -o $@ #第二種寫法#將main.o和utils.o聯合編譯成app app: main.o utils.o ?gcc main.o utils.o -o app ? #第一種寫法$(CC) $(CFLAGS) $(OBJS) -o $@ #第二種寫法$(CC) $(CFLAGS) $^ -o $@ #第三種寫法?
后綴替換:通過直接替換或者替換函數(如 wildcard, patsubst)簡化操作:
# 獲取所有 .c 文件 SRC = $(wildcard *.c) # 將 .c 替換為 .o OBJ = $(patsubst %.c, %.o, $(SRC))#直接后綴替換 將 .c 文件列表轉為 .o文件列表 SRCS = main.c utils.c config.c OBJS = $(SRCS:.c=.o) ?#替換后結果:OBJS = main.o utils.o config.o
條件判斷:一般用作不同的編譯場景下,如:
ifeq ($(OS), Windows_NT)RM = del elseRM = rm -f endif或#FLAVOR = release FLAVOR = debugifeq ($(FLAVOR),debug)TARGET_LDFLAGS += -g -O2 elif ($(FLAVOR),release)TARGET_LDFLAGS += -g -O0 endif
通過編譯器生成頭文件依賴關系,避免手動維護
CFLAGS += -MMD ?# 生成 .d 依賴文件 -include $(OBJS:.o=.d) ?# 包含所有依賴描述文件
多目錄項目構建
遞歸編譯子目錄:
SUBDIRS = driver user .PHONY: $(SUBDIRS) $(SUBDIRS): $(MAKE) -C $@
????????# 進入子目錄執行 make
使用?
vpath
?指定源文件搜索路徑:vpath %.c src:lib
?????????# 在 src 和 lib 目錄中查找 .c 文件
變量與依賴調試?
打印變量值:
debug: @echo "源文件列表:$(SRCS)" # @ 抑制命令回顯
查看依賴樹:
make -d | grep "Considering target"4。
?并行編譯加速?
啟用多線程編譯(如4線程):
make -j4
固件生成規則
添加生成?
.bin
?文件的規則:firmware.bin: firmware.elfobjcopy -O binary $< $@ # 從 .elf 生成二進制固件
條件編譯支持
DEBUG ?= 1 ifeq ($(DEBUG),1)CFLAGS += -g -DDEBUG endif
三、偽目標?
定義不生成實際文件的操作(如?
clean
),需用?.PHONY
?聲明:# 清理構建文件 .PHONY: clean clean:rm -f *.o app
將生成的一些不需要的.o文件清理掉,此時并沒有生成目標文件,所以用偽目標。