.PHONY : all clean rebuild
MKDIR := mkdir
RM := rm -rf
CC := gcc
DIR_DEPS := deps
DIR_EXES := exes
DIR_OBJS := objs
DIRS := $(DIR_DEPS) $(DIR_EXES) $(DIR_OBJS)
EXE := app.out
EXE := $(addprefix $(DIR_EXES)/, $(EXE))
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
OBJS := $(addprefix $(DIR_OBJS)/, $(OBJS))
DEPS := $(SRCS:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
all : $(DIR_OBJS) $(DIR_EXES) $(EXE)
ifeq ("$(MAKECMDGOALS)", "all")
-include $(DEPS)
endif
ifeq ("$(MAKECMDGOALS)", "")
-include $(DEPS)
endif
$(EXE) : $(OBJS)
$(CC) -o $@ $^
@echo "SUCCESS!!! Target => $(EXE)"
$(DIR_OBJS)/%.o : %.c
$(CC) -o $@ -c $(filter %.c, $^)
$(DIRS) :
$(MKDIR) $@
ifeq ("$(wildcard $(DIR_DEPS))", "")
$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
else
$(DIR_DEPS)/%.dep : %.c
endif
@echo "Creating $@ ..."
@set -e; \
$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ :]*,objs/\1.o $@ : ,g' > $@
clean :
$(RM) $(DIRS)
rebuild :
@$(MAKE) clean
@$(MAKE) all
注意事項:當.dep
文件生成后拙泽,如果動態(tài)的改變頭文件間的依賴關(guān)系戒突,那么make可能無法檢測到這個改變椭岩,進而做出錯誤的編譯決策
解決方案:
- 將依賴文件名作為目標加入自動生成的依賴關(guān)系中
- 通過
include
加載依賴文件時判斷是否執(zhí)行規(guī)則 - 在規(guī)則執(zhí)行時重新生成依賴關(guān)系文件
- 最后加載新的依賴文件
小結(jié)
- makefile中可以將目標的依賴拆分寫到不同的地方
-
include
關(guān)鍵字能夠觸發(fā)相應(yīng)的規(guī)則的執(zhí)行 - 如果規(guī)則的執(zhí)行導致依賴更新贼涩,可能導致再次解釋執(zhí)行相應(yīng)規(guī)則
- 依賴文件也需要依賴于源文件得到正確的編譯決策
- 自動生成文件間的依賴關(guān)系能夠提高makefile的移植性
聲明:此文章為本人在學習狄泰軟件學院《十二月提升計劃》所做的筆記巧涧,參考書籍《專業(yè)嵌入式軟件開發(fā)》——李云,文章中包含狄泰軟件資料內(nèi)容和《專業(yè)嵌入式軟件開發(fā)》資料內(nèi)容遥倦,一切版權(quán)歸狄泰軟件和《專業(yè)嵌入式軟件開發(fā)》所有谤绳!