全部学习汇总: ​​https://github.com/GreyZhang/g_makefile​

    先看一个简单的例子:

hello:

    echo "hello world"

    如果创建一个名称为Makefile的文件,输入上面的内容保存。之后,启动命令行切入到这个文件所在的目录输入make(或者gmake等)会出现如下效果:

1147_Makefile学习_Makefile中的目标文件以及依赖文件_时间戳

    能够看得出交互界面上打印出来了原来的命令语句,同时又打印了语句执行的结果。这个我多少倒是理解,应该前面可以加一个@符号来处理掉命令本身的回显。

1147_Makefile学习_Makefile中的目标文件以及依赖文件_makefile_02

    这是makefile的部分基本语法。按照这里的解释,目标文件可以是多个。目标文件之间,使用空格进行区分。这样,其实有一个很值得去确认的问题:如果文件的名字本身就带有空格,在这里应该如何处理?同样,类似的问题在依赖文件上也是存在的。接下来,另一个需要注意的地方是命令的开始是从TAB开始的而不是空格。

    接下来再看一个例子:

1147_Makefile学习_Makefile中的目标文件以及依赖文件_bash_03

    运行的结果:

1147_Makefile学习_Makefile中的目标文件以及依赖文件_makefile_04

    这个例子在运行的时候有一个注意点,那就是在Windows下运行的时候需要使用一个bash的模拟环境。因为Windows的命令系统中也有一个echo,但是与bash中的echo的行为并不相同。如果这一点不注意,上面的这个例子无法执行成功。

    这里有一个有趣的思考模式,也就是注释里面写的这个执行顺序。这么看,Makefile的执行推导过程有点程序设计中递归思想的感觉。

1147_Makefile学习_Makefile中的目标文件以及依赖文件_时间戳_05

    这是另外两个例子,比较容易理解。第一个每次make都会执行输出,因为目标文件一直不存在。第二个第一次执行的时候由于目标文件不存在会执行一次打印,创建文件。从第二次执行开始,不会输出而是提示文件已经更新。

    从依赖以及时间关系考虑,上面的执行过程很容理解。但是这里也可以让我们看到另一个问题点:Makefile的执行其实并不意味着目标文件就会更新到最新。

some_file: other_file

    echo "This will run second, because it depends on other_file"

    touch some_file

other_file:

    echo "This will run first"

    touch other_file

    上面的这个例子,涉及到了对于其他文件的依赖。运行的效果:

1147_Makefile学习_Makefile中的目标文件以及依赖文件_开发语言_06

    这个例子其实可以很好地展示文件依赖之间的关系,如果文件不就绪,那么更新。如果文件已经就绪,那么不再更新。如果依赖文件的时间戳发生了变化,目标文件也会更新。

1147_Makefile学习_Makefile中的目标文件以及依赖文件_makefile_07

    关于上面描述的一个更好的测试方式是这样,直接通过制定target来生成other_file,之后执行gmake处理默认的target,也就是第一个target。这样,不仅能够看出makefile对于文件时间戳的管理概念,同时还能够看到指定target处理的功能。

1147_Makefile学习_Makefile中的目标文件以及依赖文件_目标文件_08

    这样,引入了另一个关于目标文件的概念。make clean是一个常用的操作,其实也只是用来处理指定的target而已。clean并不是makefile中的一个关键词或者保留字。