今天继续对Makefile进行研究,话不多说,进入正题:
make常用内嵌函数:
![](https://images0.cnblogs.com/i/324374/201406/252208349869790.png)
下面利用上面的知识点来实现一个多级目录的Makefile,如下:
多级目录Makefile:
这个例子的目录结构如下:
![](https://images0.cnblogs.com/i/324374/201406/291557170864910.png)
通过一个Makefile来最终生成一个可执行文件main,那该怎么编写呢?会利用make的内联函数,具体写法如下:
![](https://images0.cnblogs.com/i/324374/201406/291601332895515.png)
运行如下:
![](https://images0.cnblogs.com/i/324374/201406/291603146015934.png)
那这个Makefile到底是怎么实现的呢?下面一一对其进行理解:
![](https://images0.cnblogs.com/i/324374/201406/291605561791998.png)
下面的每句都得好好理解啦,基本就是用的Make中的内联函数,分析如下:
![](https://images0.cnblogs.com/i/324374/201406/291608491331769.png)
这时,可以在shell命令中执行一下就知道了:
![](https://images0.cnblogs.com/i/324374/201406/291611018205638.png)
另外得学会,在Makefiile中,怎么去执行shell命令,用上述方式既可,通过这句就可以得到所有子目录了,下面接着分析:
![](https://images0.cnblogs.com/i/324374/201406/291614324291382.png)
![](https://images0.cnblogs.com/i/324374/201406/291619157114191.png)
![](https://images0.cnblogs.com/i/324374/201406/291621056959358.png)
下面在shell命令中来实践一下就知道了:
![](https://images0.cnblogs.com/i/324374/201406/291623536798513.png)
![](https://images0.cnblogs.com/i/324374/201406/291625471487811.png)
![](https://images0.cnblogs.com/i/324374/201406/291629133046793.png)
![](https://images0.cnblogs.com/i/324374/201406/291630093205206.png)
通过一步步分析,掌握这种灵活的写法其实也不是很难,在实际项目中挺实用的,当然这里只支持二级目录,多级目录还不支持,但是对于Makefile的学习已经够用了。
【注意】:要想达到通用,则必须用动态的方式去写Makefile,所以在多级目录下,就必须学会用Make当中的内联函数。
接下来再来看一个例子,在实际项目中,有可能一个目录下有一个Makefile,而子目录下也希望生成自己的可执行文件,也就是说,一个Makefile文件,管理了多个目录,并生成多个可执行文件,并不是只是如上个例子的那样,将所有的目录只生成一个可执行文件,那这样的Makefile该怎么编写呢?
先看一下目录结构:
![](https://images0.cnblogs.com/i/324374/201406/291708246016128.png)
具体表现是怎么样的呢?如下:
![](https://images0.cnblogs.com/i/324374/201406/291711497427465.png)
![](https://images0.cnblogs.com/i/324374/201406/291715572116835.png)
那主目录的Makefile是怎么管理子目录的Makefile的呢,下面一一来分析,先分析一下主目录的Makefile的含义:
![](https://images0.cnblogs.com/i/324374/201406/291713335869856.png)
那下面对照着make输出语句,一句句进行理解,这种Makefile的写法是比较专业的,所以做为专业人士就得好好理解,如下:
![](https://images0.cnblogs.com/i/324374/201406/291721353366300.png)
![](https://images0.cnblogs.com/i/324374/201406/291726058835589.png)
![](https://images0.cnblogs.com/i/324374/201406/291729231179577.png)
![](https://images0.cnblogs.com/i/324374/201406/291736228679346.png)
结合make输出来看,正好是这条命令:
![](https://images0.cnblogs.com/i/324374/201406/291739319458144.png)
其中"make test1 test2 TARGET=all"进而会去找test1,test2的生成规则,如下:
![](https://images0.cnblogs.com/i/324374/201406/291741123512420.png)
所以,这时会进行这两个子目录进行生成,并将all传递进去:
![](https://images0.cnblogs.com/i/324374/201406/291744469458379.png)
其中"make -C test1 all"等价于"make all test/Makefile",这时则进入子目录分析一下生成规则
分析一下test1子目录的Makefile的含义,其它子目录的就类似了:
![](https://images0.cnblogs.com/i/324374/201406/291717049457228.png)
下面来对它进行理解:
![](https://images0.cnblogs.com/i/324374/201406/292158399925094.png)
![](https://images0.cnblogs.com/i/324374/201406/292204340868071.png)
所以输出如下:
![](https://images0.cnblogs.com/i/324374/201406/292242227586631.png)
![](https://images0.cnblogs.com/i/324374/201406/292244506643383.png)
所以输出如下:
![](https://images0.cnblogs.com/i/324374/201406/292247259455856.png)
至此整个的make传递过程就比较清楚了,如果我们make clean则会将所有子目录里生成的中间文件删除掉:
![](https://images0.cnblogs.com/i/324374/201406/292250449924132.png)
关于它的Make Clean传递过程跟Make的过程一样,这里就不分析了,总之通过这个专业的Makefile可以实现多级目录的编译,好了,关于Makefile的知识已经补完了,接下来会在实际项目中用到,下回见~