Makefile 中的 include (依赖文件) 的执行过程

1 疑问所在

博主在学习 <<“万能makefile”写法详解,一步一步写一个实用的Makefile>> 博文的时候,始终对于 Makefile include 的执行过程心存疑惑。 建议大家在看本博文之前,先看下提到的那篇博文。

有疑问的代码大致如下:

	SRCS:$(wildcard *.c)
	DEPS=$(SRCS:*.c=*.d)
	.....

	include $(DEPS)
	%.d:%.c
		gcc -MM $< > $@

疑问 : 若是首次 make,目录下不存在 xxx.d 文件,同时 xxx.d 文件并不是哪个规则的依赖文件,所以 <%.d:%.c> 这条模式规则应该不会执行,可实际上执行了,因为目录下生成了 xxx.d 文件。

结果 : 经过测试,发现首次 make 时,执行 include $(DEPS) 的时候,终端在报告了如下警告之后

makefile:6: xxx.d: No such file or dirctory

会默认在 makefile 中去找以 xxx.d 为目标的规则并执行,若该规则也没发现,便会报错并中止执行。

2 探索过程

以下是博主的测试过程,其 makefile 内容如下:

all:
	@echo "-------- $@ ---------"

include tmp.d
tmp.d:
	@echo "-------- $@ ---------"

make 执行结果如下:

makefile:6: tmp.d: No such file or directory
-------- tmp.d ---------
-------- all ---------

结果显示,执行了以 tmp.d 为目标的规则。

注释:all 目标才是首目标,可输出的结果是首先打印了tmp.d 目标,这是因为 include 语句执行于目标规则之前,好比 C 文件中的 include 指令一样。

  • 倘若目录下存在 tmp.d, 会是什么情况呢?

    先在 makefile 所在目录下执行命令 touch tmp.d 生成空文件 tmp.d
    键入 make 执行结果如下:

    -------- all ---------
    

    结果表明,当目录下存在 tmp.d 文件,则不会执行以 tmp.d 为目标的规则。

  • 倘若 makefile 文件中没有以 tmp.d 为目标的规则,makefile 所在目录下也没有 tmp.d 文件,会出现什么情况呢?

    现将 makefile 文件更新如下,屏蔽 tmp.d 规则:

    all:
    	@echo "-------- $@ ---------"
    
    include tmp.d
    #tmp.d:
    #	@echo "-------- $@ ---------"
    

    键入 make 执行结果如下:

    makefile:6: tmp.d: No such file or directory
    make: *** No rule to make target `tmp.d'.  Stop.
    

    结果表明,一旦 makefile 所在目录下,没有 tmp.d 文件,且 makefile 中也没有以 tmp.d 为目标的规则,运行就会报错并终止,其实从错误消息的提示也可以看出,在运行到 include tmp.d 的时候,有如下两个动作:

    **1. 检查 makefile 所在目录下是否有 tmp.d 文件;

    1. 查找 makefile 文件中是否有以 tmp.d 为目标的规则。**

    若有一个符合都会执行通过。

    实际开发过程中,对于使用了依赖文件的 makefile,不可能使用博文中提到的在首次 make 时,因为目录下不存在依赖文件,为了避免 include $(DEPS) 不报错或者警告而人工 touch 创建所有的依赖文件的。所以需要在 include 前面加上 ‘-’(忽略错误或警告),即如下处理:

    -include $(DEPS)
    
  • 倘若有两个连续的 include 目标,那么目标的执行顺序是怎样的了?

    现更新 makefile 内容如下:

    all:
    	@echo "-------- $@ ---------"
    
    include tmp.d
    include dep.d
    
    tmp.d:
    	@echo "-------- $@ ---------"
    	
    dep.d:
    	@echo "-------- $@ ---------"
    

    键入 make 执行结果如下:

    -------- dep.d ---------
    -------- tmp.d ---------
    -------- all ---------
    

    由此可见,include 目标时,目标规则的执行顺序是从后往前执行。

3 结语

可能大牛会觉得以上实际过程本该如此,可是在我看了 <<跟我一起写Makefile>> 之后,还是对 include 关键字的理解不够全面,导致内心出现了文章开头所描述的疑惑。所以在此写给同样有如此疑问的新手,一起学习。

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值