简单说, Makefile中指定目标和依赖, 然后Make运行的时候会检测文件的时间信息, 如果目标落后于依赖的修改时间则目标需要重新生成, 以此达到按需生成, 节省时间的目的.
举个简单的例子:
OBJS := foo.o bar.o
program: $(OBJS)
gcc $(OBJS) -o program
%.o: %.c
gcc -c $(CFLAGS) $< -o $@
这个Makefile表达的意思是由foo.c
和bar.c
生成program
, 中间目标文件分别依赖相应的源文件. 但是实际场景远没有这么简单, 例如每个.o
还会各自依赖很多不同的.h
头文件, 怎么办? 挨个列出来么? 太麻烦了, 而且依赖关系还可能会变化.
当然可以, 直接看代码:
OBJS := foo.o bar.o
program: $(OBJS)
gcc $(OBJS) -o program
-include $(OBJS:.o=.d)
%.o: %.c
gcc -MD -MP -c $(CFLAGS) $< -o $@
相较于之前的版本, 这次每个.o
的编译过程中都会生成一个Makefile语法的.d
文件, 里面列出了gcc分析得出的依赖关系. 所以当我们把这些.d
文件包含进来之后, Make就可以知道详细的依赖关系信息, 进而判断哪些依赖发生了变化, 哪些目标需要重新生成.
PS, 如果你不想把系统头文件也列在依赖里面, 可以把参数-MD
换成-MMD
.