1. .o文件的依赖
场景:
在以上场景中分析下面代码时候有问题:
OBJS := func.o main.o
hello.out : $(OBJS)
@gcc -o $@ $^
@echo "TargetFile ==> $@"
$(OBJS):%.o : %.c
@gcc -o $@ -c $^
结果分析:当 .h 头文件发生改变时,makefile 无法感知
编译行为带来的缺陷:
- 预处理器将头文件中的代码直接插入源文件
- 编译器只通过预处理后的源文件产生目标文件
- 因此,规则中仅仅以源文件作为依赖,命令执行结果和预期不符
为解决上述问题提出的初级方案:头文件作为依赖条件出现于每个目标对应的规则中,这样做的确可以解决上述问题,但是其它问题又随之出现,当头文件改动,任何源文件都将重新被编译 ( 编译低效) ,如果当项目中源文件和头文件数量非常多,makefile 将很难维护
2. 自动生成依赖关系的预备工作
2.1 Linux 命令 sed (了解即可)
- sed 是一个流编辑器,用于流文本的修改
- sed 可用于流文本中字符串替换
- sed 的字符串替换方式为
sed 's:src:des:g'
或者sed 's,src:des,g'
- 在 sed 中可以用正则表达式匹配替换目标,并且可以使用匹配的目标生成结果
2.2 gcc 关键字编译选项
自动生成依赖关系:
-M
参数获取目标的完整依赖 ( gcc -M test.c )-MM
参数获取目标的部分依赖 ( gcc -MM test.c )
3. 拆分目标依赖
.PHONY : test a b c d
test : b
test : d
test: a c b
@echo $^
执行结果: