13-自动生成依赖关系(下)

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( 无操作 ) 
发布了61 篇原创文章 · 获赞 31 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_40794602/article/details/105495116