文章目录
1. 组织生成的依赖文件
- 通过规则和命令创建 deps 文件
- 将所有 .dep 文件创建到 deps 文件夹
- .dep 文件中记录目标文件的依赖关系
.PHONY : all clean
MKDIR := mkdir
RM := rm -fr
CC := gcc
DIR_DEPS := deps
SRCS := $(wildcard *.c)
DEPS := $(SRCS:.c=.dep)
DEPS := $(addprefix $(DIR_DEPS)/, $(DEPS))
all :
@echo "all"
ifeq ("$(MAKECMDGOALS)", "all")
-include $(DEPS)
endif
ifeq ("$(MAKECMDGOALS)", "")
-include $(DEPS)
endif
$(DIR_DEPS) :
$(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) $(DIR_DEPS)
代码走读:
- 第17~26行,执行条件判断使得如果是清理项目则不用包含依赖关系
- 第28~32行,防止 .dep 依赖文件被重复创建
- deps 文件夹的时间属性会因为依赖文件创建而发生改变
- make 发现 deps 文件夹比对应的目标更新,则触发相应规则重新解析和执行命令,如果没有这个条件判断,在项目很庞大的情况下可能会在这里发生无限循环
2. include 关键字不为人知的秘密
2.1 include 暗黑操作一
- 使用减号
-
不仅会关闭 include 发出的警告,同时会关闭错误 ( 当错误发生时 make 将忽略这些错误! )
.PHONY : all
-include test.txt
all :
@echo "this is all"
执行结果:
2.2 include 暗黑操作二
.PHONY : all
-include test.txt
all :
@echo "this is all"
test.txt :
@echo "creating $@"
@echo "other : ; @echo "this is other"" > test.txt
执行结果:
结果分析:因为执行 test.txt 规则生成了 test.txt 文件,此时生成的 test.txt 中的内容是 other : ; @echo "this is other"
代替了 顶层规则,所以直接执行make 会输出 this is other
2.3 include 暗黑操作三
.PHONY : all
-include test.txt
all :
@echo "this is all"
test.txt : b.txt
@echo "this is $@"
#代码场景:当前目录存在 test.txt和b.txt,并且b.txt文件更新
执行结果:
结果分析:即使当前目录中存在 include 所包含的文件,如果当前 makefile 文件中存在所包含文件名相同的规则并且有更新的依赖时也会执行这个规则
3. include 总结
【include 总结一】
-当目标文件不存在
以文件名查找规则并执行
-当目标文件不存在,且查找到的规则中创建了目标文件
将创建的成功的目标文件包含进当前makefile
【include 总结二】
-当目标文件存在
将目标文件包含进当前 makefile
以目标文件查找是否有对应规则
YES:比较规则的依赖关系,决定是否执行规则的命令
NO:NULL( 无操作 )