文章目录
1. 头文件依赖
1.1 头文件带来的思考
.o
文件并不仅仅依赖源文件,也有可能依赖头文件- 预处理器将头文件中的代码直接插入源文件,编译器只通过源文件通过预处理后的源文件产生目标文件,因此规则中仅仅以源文件作为依赖,当被依赖的头文件被修改后,命令可能无法执行
1.2 示例分析
思考下面的 makefile 有没有问题?
结果分析:main.c
和 func.c
都依赖于func.h
,但是这个依赖关系并没有写入makefile
中,所以当头文件修改时并不会触发相应的规则
初步解决方案:
OBJS:=func.o main.o
hello.out:4(OBJS)
@gcc -o @@ $^
$(OBJS):%.o:%.c func.h // 将.h头文件直接写入每条规则的依赖中
@gcc -o $@ -c $<
对于这种小一点的项目这种方案的确可行,但是如果项目非常大,将所有的头文件直接包含进所有的规则中,那么只要有一个头文件被修改时那么所有的规则都需要重新执行一遍
2 自动生成依赖关系
2.1 疯狂的想法
- 通过命令自动生成对头文件的依赖
- 将生成的依赖自动包含进 makefile 中
- 当头文件修改后,自动确认需要重新编译的文件
2.2 预备工作
2.2.1 Linux 中的 sed
- sed 是一个流编辑器,用于流文本的修改
- sed 可用于流文本中的字符串的替换
- sed 的字符串替换方式为 :
sed 's:src:des:g'
- sed 支持正则表达式
2.2.2 gcc 编译选项
gcc -M 源文件
,将产生这个源文件所有的依赖,包括系统级别的依赖gcc -MM 源文件
,将产生这个源文件部份依赖(不包括系统库的一些依赖)gcc -MM -E
或则gcc -M -E
只激活预处理(优化)