第十二篇 自动生成依赖关系(中)

为了完成自动生成依赖关系的目的,我们还需要引入几个知识点,下面首先引入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如下:
为了格式上的优雅,还可以加入续行符,如下所示:
续行符只是告诉make,这些命令逻辑上是在同一行的,只是我们现在把它写成了多行。命令写在了多行,而没有用续行符,这时即使使用了接续符(;),make也不会把它们当作同一个命令,而依然是当作多个命令,然后再不同进程执行。使用接续符(;)将多个命令组合成一个命令,这些命令在逻辑上必须是在同一行的。
 
有了以上的知识基础,我们可以给出自动生成依赖关系的初步解决方案了,如下所示:
初步的makefile如下所示:
 
执行make all,输出结果如下:
成功创建了依赖文件,且内容符合预期。
下一篇中,我们继续完善自动生成依赖关系的知识。
posted @ 2018-12-30 21:14  lemaden  阅读(125)  评论(0编辑  收藏  举报