5.2.2 Makefile中的依赖关系
依赖关系是Makefile在执行过程中的核心内容。在应用中Makefile不仅可以用于编译,也可用于处理其他的逻辑,本节以一个Makefile为例,说明在执行make工作中处理依赖关系的过程。
Makefile文件如下所示:
all:rule0 file.o rule0:rule1 rule1:rule2 clean: |
$ make |
+++++++ rule3 +++++++ |
由于make没有指定选项和目标,将默认使用Makefile文件,并执行其中的all目标。在执行的过程中,首先发现all目标依赖于rule0和file.o两个目标,因此需要完成这两个目标的处理。对于rule0目标,依次寻找它的依赖关系,直到找到rule3目标,然后再从rule3目标执行,依次执行rule3,rule2,rule1,rule0。对于file.o目标,将生成file.o文件,它由file.o目标生成,内容为"1234567890",变量@D表示目标的所在目录的路径,@F表示目标的文件名。
在规则rule0:rule1中,使用了变量$^和$@,前者表示依赖的所有文件,后者表示目标的名称。事实上,Makefile的执行顺序不是按照每条规则书写的先后顺序,而是由规则之间的依赖关系确定的。
在Makefile中,将目标clean rule0 rule1 rule2 rule3定义为伪目标(.PHONY),这是由于它们不是需要生成的内容的名称;file.o是实际生成的结果,因此它是真实的目标,而不是伪目标。
在执行过一次make之后,再次执行make命令,得到的结果如下所示:
+++++++ rule3 +++++++ |
从执行结果中可见,这次只执行了rule0及其依赖的目标,没有执行目标file.o。这是由于目标file.o依赖的内容没有变化,所以这条目标不需要被执行,这说明了Makefile条件编译的特性。
执行make clean的结果如下所示:
$ make clean |
这次执行删除了file.o文件,状态已经退回到make执行之前。因此再次执行make的时候,将和首次执行是一致的。
在make命令的使用中,可以使用-n选项显示执行的序列:
$ make -n |
echo "+++++++ rule3 +++++++" |
由此可见,在本次的执行中,只显示了需要执行的命令,而不是真正地执行这些命令。在这个过程中,寻找依赖关系的过程和直接的make过程是一致的,但是只显示要执行命令而不执行命令。
在使用make的过程中,也可以指定一条单独的目标来执行,例如:
$ make rule2 |