Makefile中关于depend问题
在一些驱动的Makefile中经常看到:
depend .depend dep:
$(CC) $(CFLAGS) -M *.c pridriver.o> .depend
ifeq (.depend,$(wildcard .depend))
include .depend
endif
查了一些有关Makefile的文章中也没有提到,哪位高手能给详细解释一些上面一段,感激不尽!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
C 源码的开头经常有一系列被包含的头文件,例如 stdio.h。有一些是系统级的头文件,有一些是你正在写的项目的头文件:
#include <stdio.h>#include "foo.h"int main(....
要确定在你的 foo.h 被改变之后,这个文件也会被重新编译,就要在你的 Makefile 这样写:
foo: foo.c foo.h
当你的项目变得越来越大,你自己的头文件越来越多的时候,要追踪所有这些头文件和所有依赖它的文件会是一件痛苦的事情。如果你改变了其中一个头文件,却忘了重新编译所有依赖它的源文件,结果会是很失望的。
这就是depend 的作用,如果不使用这个功能, 则当你修改一个头文件时, 必须重新把所有的源文件都编译一次, 使用depend ,就可只编译包含此头文件的源文件,可大大节省时间。
gcc 有一个选项可以分析你的源文件然后产生一个头文件的列表和它的依赖关系: -MM。
如果你把下面的内容加到你的 Makefile 里面:
depend: gcc -E -MM *.c > .depend
然后运行 make depend,就会产生一个 .depend,里面包含了目标文件,C 文件和头文件的列表:
foo.o: foo.c foo.h
如果你改变了 foo.h,下一次运行 make 的时候,所有依赖 foo.h 的文件就会被重新编译。
每一次你增加一个头文件的时候,别忘了运行一次 make depend。
一般来说,make其实是make all的省略;make后面跟的是target,即你要编译的目标,在makefile里面会列出 这个target依赖于哪几个别的target,别的target又依赖于另外的target,如此“递归”,最终会到依赖的源文件和头文件;当然,也有可能这个target后面直接就是源文件和头文件(最简单的情况)。make all和make depend没有本质区别,都是生成某个目标,只是目标名称不同而已;至于编译的结果,就取决于makefile的写法,如果makefile中目标all和目标depend的依赖一样,那么结果也将是相同的。你前面列出的make 和make depend的区别没有错,但那只是早些时候大家的约定熟成而已,你完全可以修改makefile,把他们的功能完全弄反。现阶段,很多软件已经不需要或者不支持make depend了,比如编译linux 2.6的时候,根本不需要make depend,而早期的linux 2.4,则一般需要make depend这一步。
如果没有depend,可能修改了某个文件,再执行make可能觉察不到有任何变化。
make需要查找依赖关系,把依赖于此改动过的文件的所有文件都要重新编译。
还有2个问题想问一下:
1。make 通过比较对应文件(规则的目标和依赖)的最后修改时间,来决定哪些文
件需要更新、那些文件不需要更新。对需要更新的文件 make 就执行数据库中所记录的
相应命令(在 make 读取 Makefile 以后会建立一个编译过程的描述数据库。此数据库
中记录了所有各个文件之间的相互关系,以及它们的关系描述)来重建它,对于不需要
重建的文件 make 什么也不做。————这是Makefile中文手册中的一段
.depend是否就是上面所说的“编译过程的描述数据库”?
以前看的时候比较匆忙,以为Make会自己去比较文件的修改时间以及依赖关系,只重新编译需要更新的文件。
2。ifeq (.depend,$(wildcard .depend))
include .depend
endif
.depend和$(wildcard .depend)是不是总相等,那么下面的include .depend始终会执行?
make depend就是将某些虽然从时间上并不需要重新编译的,再依据这种依赖关系,编译一下。