第十二篇 自动生成依赖关系(中)
为了完成自动生成依赖关系的目的,我们还需要引入几个知识点,下面首先引入makefile中的关键字include。
include关键字:
makefile中的include关键字类似于C语言中的include关键字,将其它文件的内容原封不动的搬到当前文件中。具体用法如下所示:
*.mk代表当前目录下的所有mk后缀的文件,$(var)表示var变量所代表的文件。
make解释器对include关键字的处理方式如下所示:
可以通过在include前加上"-",消除文件不存在时产生的警告,如:-include filename,但这种做法也容易将一些bug隐藏。
编写makefile并执行make,结果如下:
可见,首先输出的是test.txt,然后是this is all。make解释器在解析makefile时,发现test.txt文件并不存在,于是,make以test.txt为目标查找并执行对应的规则,所以首先输出的是test.txt。如果不存在test.txt文件也不存在以test.txt为目标对应的规则,则make直接报错。
在当前目录下创建test.txt文件,内容只有一条规则,具体如下:
下面再次执行make,输出如下:
此时,并没有输出all对应规则下的信息,为什么呢?因为make通过include将test.txt的内容原封不动的搬到了makefile中,other对应的规则也成了第一条规则对应的目标,make默认情况下寻找第一个目标执行,因此,输出this is other就不足为怪了。
我们删掉test.txt文件,并修改makefile文件,内容如下:
执行make后输出结果如下:
make解释器一开始发现当前目录下没有test.txt文件,便去寻找以test.txt为目标的规则,找到之后,执行对应的命令,生成了一个test.txt文件,并向该文件中写入了other : ;@echo this is other这条规则,然后,make解释器再次将这个新生成的文件内容原封不动的加载到makefile中,other目标对应的规则成了第一条规则,make默认情况下执行这个目标下的命令,因此,最终输出了this is other。
我们来看一下通过命令生成的test.txt的内容:
下面我们学习一下makefile中命令的执行机制,具体如下:
根据以上机制的学习,我们考察下面的makefile,会得到预期的结果吗?
显然以上的makefile程序不会得到预期的结果,因为在执行mkdir test命令时,make会创建一个进程,执行完这条命令,进程终止。接着该执行下一条命令cd test了,同样是先创建一个进程,然后执行完命令,进程终止。最后,make又创建一个进程,执行mkdir subtest命令,但是这个进程的工作目录是当前目录,而没有进入到test目录,因此,在当前目录下创建了文件夹subtest。而我们希望的是subtest文件夹是建立在test目录下。
我们可以加入接续符(;),使得多个命令在同一个进程中执行,修改后的makefile如下: