Makefile学习之路2————规则

target:规则的目标。可以是 Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。 

prerequisites:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。(.c文件 .h文件 所有的.o文件既是依赖(相对于可执行程序edit)又是目标(相对于.c和.h文件)。)

 

command:规则的命令行。是规则所要执行的动作(任意的 shell 命令或者是可在shell 下执行的程序)。它限定了 make 执行这条规则时所需要的动作。
一个规则可以有多个命令行,每一条命令占一行。 注意:每一个命令行必须以[Tab]字符开始,[Tab] 字符告诉 make 此行是一个命令行。make 按照命令完成相应的动作。这也是书写 Makefile中容易产生,而且比较隐蔽的错误。
命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。

 

说白一点就是说,prerequisites中如果有一个以上的文件比 target 文件要新的话,command 所定义的命令就会被执行。这就是 Makefile 的规则。也就是Makefile 中最核心的内容

 例如:

 

如上图所示的Makefile中,all就是一个目标,目标名是放在“:”前面的,名字可以由字母和下划线组成。这里的all目标是一个抽象的概念,在此应将其理解为“在终端上打印‘Hello World’”这一行为。

注明:

 1)一个Makefile中可以定义多个目标。

2)调用make命令时,得告诉它我们希望它构建的目标是什么,即要它干什么。当没有指明具体的目标时,make将以文件中定义的第一个目标作为这次运行的目标。“第一个”目标,也被称为默认目标。

3)当make得到目标后,先找到构建目标的对应规则,然后运行规则中的命令来达到构建目标的目的。目前的Makefile中每个规则中都只有一条命令,实际上,一个规则中可以根据需要存在多条命令。

 

例如:

当不带参数运行make时,输出为:

Just  for  test !

Hello  World

命令行输入make  test,输出为:

Just  for  test !

从输出结果可以发现,当不带参数运行make时,构建all目标之前test目标也被构建了。

所以现在引入Makefile中的依赖关系这一概念。

上例中all目标后面的test是告诉make,all目标依赖于test目标,这个依赖目标又被称为(all目标的)先决条件(prerequisite)。

一个规则是由目标、先决条件以及命令组成的。需要指出的是,目标和先决条件之间表达的就是依赖关系(dependency),这种依赖关系指明在构建目标之前,必须保证先决条件先满足(即先被构建)。

一个规则可以定义多个目标,当一个规则中存在多个目标且这个规则是Makefile中的第一个规则时,如果运行make命令不带任何目标,那么规则中的第一个目标将被视为默认目标。

 

 

书写时,可以将一个较长行使用反斜线(\)来分解为多行,这样可以使我们的Makefile书写清晰、容易阅读理解。但需要注意:反斜线之后不能有空格(这也是大家最容易犯的错误,错误比较隐蔽)。

 

命令行必需以[Tab]键开始,以和Makefile其他行区别。 就是说所有的命令行必需以[Tab] 字符开始,但并不是所有的以[Tab] 键出现行都是命令行。但make 程序会把出现在第一条规则之后的所有以[Tab] 字符开始的行都作为命令行来处理。

(记住:make程序本身并不关心命令是如何工作的,对目标文件的更新需要你在规则描述中提供正确的命令。“make”程序所做的就是当目标程序需要更新时执行规则所定义的命令)

Makefile中把那些没有任何依赖只有执行动作的目标称为“伪目标”(phony targets)。 

对这些.o 文件为目标的规则处理有下列三种情况:
1. 目标.o 文件不存在,使用其描述规则创建它; 

2. 目标.o 文件存在,目标.o 文件所依赖的.c 源文件、.h 文件中的任何一个比目标.o
  文件“更新”(在上一次 make 之后被修改)。则根据规则重新编译生成它; 

3. 目标.o 文件存在,目标.o 文件比它的任何一个依赖文件(的.c 源文件、.h 文件)
“更新”(它的依赖文件在上一次 make 之后没有被修改),则什么也不做。

  



 

posted @ 2017-05-29 22:03  Liu_Jing  Views(274)  Comments(0Edit  收藏  举报