第十一部分 :自动生成依赖关系(上)
11.1 值得思考的问题
- 目标文件(.o )是否只依赖于源文件(.c ) ?
- 编译器如何编译源文件和头文件?
11.2 编译行为带来的缺陷
- 预处理器将头文件中的代码直接插入源文件
- 编译器只通过预处理后的源文件产生目标文件
- 因此,
- 规则中以源文件为依赖,命令可能无法执行
11.3 下面的 makefile有没有问题?
11.4 编程实验:问题的提出
当func.h发生改变,理应重新编译,但makefile只检查两个源文件,发现无改动是最新的,所以不会重新编译,导致错误。
OBJS := func.o main.o
hello.out : $(OBJS)
@gcc -o $@ $^
@echo "Target File ==> $@"
$(OBJS) : %.o : %.c func.h
@gcc -o $@ -c $<
11.5 实验中解决方案的问题
- 头文件作为依赖条出现于每个目标对应的规则中
- 当头文件改动,任何源文件都将被重新编译(编译低效)
- 当项目中头文件数量巨大时, makefile将很难维护
11.6 疯狂的想法
- 通过命令自动生成对头文件的依赖
- 将生成的依赖自动包含进makefile中
- 当头文件改动后,自动确认需要重新编译的文件
11.7 预备工作(原材料)
- Linux命令sed
- 编译器依赖生成选项gcc-MM ( gcc-M )
11.8 Linux中的sed命令
- sed是一个流编辑器,用于流文本的修改(增/删/查/改)
- sed可用于流文本的中的字符串替换
- sed的字符串替换方式为 : sed 's: src:des:g'
11.9 sed的正则表达式支持
- 在sed 中可以用正在表达式匹配替换目标
- 并且可以使用匹配的目标生成替换结果
sed 's,\(.*\)\.o[ :]*,objs/\1.o : ,g'
① 分隔符:既可以是,也可以是:
② \(.*\)\.o[ :]*
- \(.*\)\.o[ :]*