第十三课:自动生成依赖关系(下)

本文介绍了如何在Makefile中组织和管理.dep依赖文件,包括自动创建、避免重复和动态判断依赖的策略。通过实例演示了如何利用ifeq进行优化,以及关于include的几种操作模式,适用于C/C++项目的构建管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自动生成依赖关系(下)


问题

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

解决思路
  • 当include发现.dep文件不存在:
    • 通过规则和命令创建deps文件
    • 将所有.dep文件创建到deps文件夹
    • .dep文件中记录目标文件的依赖关系
代码的初步设计
$(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'>$@
编程实验
解决方案
.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)
实验截图

在这里插入图片描述

不是问题的问题
  • 为什么一些.dep依赖文件会被重复创建多次?
问题本质分析
  • deps文件夹的时间属性会因为依赖文件创建而发生变化
  • make发现deps文件夹比对应的目标更新
  • 触发相应规则的重新解析和命令的执行
  • 。。。。
解决方案的优化
  • 使用ifeq动态决定.dep目标的依赖
ifeq ("$(wildcard $(DIR_DEPS))", "")
$(DIR_DEPS)/%.dep : $(DIR_DEPS) %.c
else
$(DIR_DEPS)/%.dep : %.c
endif

编程实验

解决方案的优化

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

实验截图
在这里插入图片描述
include暗黑操作一:

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

    .PHONY : all
    -include test.txt
    all:
    	@echo "this is all"
    

include暗黑操作二:

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

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

include暗黑操作三:

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

    .PHONY :all
    -include test.txt
    
    all:
    	@echo "this is all"
    test.txt:b.txt
    	@echo "this is $@...."
    

关于include的总结一

  • 当目标文件不存在

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

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

关于include的总结二

  • 当目标文件存在
    • 将目标文件包含进当前makefile
    • 以目标文件名查找是否有相应的规则
      • YES : 比较规则的依赖关系,决定是否执行规则命令
      • NO: NULL(无操作)

关于include的总结三

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

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

      • make重新包含目标文件,替换之前包含的内容
    • 目标文件未被更新

      • NULL(无操作)
参考资料:

狄泰软件教学课件

[1] GNU make
    
文章所示代码链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值