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

目录

 

1.问题

2.解决思路

3.初步的代码设计

4.不是问题的问题

5.问题本质分析

6.解决方案优化

7.include暗黑操作一:

8.include暗黑操作二

9.include暗黑操作三

10.关于include的总结一

11.关于include的总结二

12.关于include的总结三


1.问题

如何在makefile中组织.dep文件到指定目录?

2.解决思路

  • 当include发现.dep文件不存在:

             1.通过规则和命令创建deps文件

             2.将所有.dep文件创建到deps文件夹

             3..dep文件中记录目标文件的依赖关系

3.初步的代码设计

这样就是先生成dep文件在创建,目录

打开警告,发现include时找不到DEPS目标所以报错,如果不打开-include就会执行all

完善如下,我们使用预定义函数过滤掉目录


.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))

include $(DEPS)

all : 
	@echo "all"

$(DIR_DEPS) :
	$(MKDIR) $@

$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
	@echo "Creating $@ ..."
	@set -e; \
	$(CC) -MM -E $(filter %.c, $^) | sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g' > $@
	
clean :
	$(RM) $(DIR_DEPS)
	

4.不是问题的问题

为什么有一些.dep依赖文件会被重复创建多次?

5.问题本质分析

  • deps文件夹的时间属性会依赖文件创建而发生改变
  • make发现deps文件夹比对应的目标更新
  • 触发相应规则的重新解析和命令的执行

6.解决方案优化

使用ifeq动态决定.dep目标的依赖

make clean不需要include,完善如下


.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)
	

7.include暗黑操作一:

使用减号(-)不但关闭了include发出的警告,同时关闭了错误;当错误反生时make将忽略这些错误!

8.include暗黑操作二

如果include触发规则创建了文件,之后还会发生什么?

答:先执行创建在回去执行all

.PHONY : all

-include test.txt

all : 
	@echo "this is all"
	
test.txt :
	@echo "creating $@ ..."
	@echo "other : ; @echo "this is other" " > test.txt

9.include暗黑操作三

如果include包含的文件存在,之后还会发生什么?

答:将不再执行test这条规则

.PHONY : all

-include test.txt

all : 
	@echo "this is all"
	
test.txt : 
	@echo "creating $@ ..."
	

10.关于include的总结一

  • 当目标文件不存在

                   以文件名查找规则,并执行

  • 当目标文件不存在,且查找的规则中创建了目标文件

                  将创建成功的目标文件包好进当前makefile

11.关于include的总结二

  • 当目标文件存在

            将目标文件包含进当前makefile

           以目标文件名查找是否有相应规则

12.关于include的总结三

  • 当目标文件存在,且目标名对应的规则被执行

           规则中的命令更新了目标文件

                  √make重新包含目标文件,替换之前包含的内容

           目标文件未被更新

                  √NULL(无操作)

.PHONY : all

-include test.txt

all : 
	@echo "$@ : $^"
	
test.txt : b.txt
	@echo "creating $@ ..."
	@echo "all : c.txt" > test.txt

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值