概述

在Linux(unix)环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译和连接。

make是一个命令工具,它解释Makefile中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。make执行时,根据Makefile的规则检查文件的修改情况,决定是否执行定义的动作(那些修改过的文件将会被重新编译)。这是GNU make的执行依据。

make在执行时,需要一个命名为Makefile的文件。这个文件告诉make以何种方式编译源代码和链接程序。make通过比较对应文件(规则的目标和依赖,)的最后修改时间,来决定哪些文件需要更新、那些文件不需要更新。对需要更新的文件make就执行数据库中所记录的相应命令(在make读取Makefile以后会建立一个编译过程的描述数据库。此数据库中记录了所有各个文件之间的相互关系,以及它们的关系描述)来重建它,对于不需要重建的文件make什么也不做。

Makefile编写规则

一个简单的Makefile描述规则组成:

TARGET... : PREREQUISITES...
    COMMAND
    ...
    ...

target:规则的目标。通常是最后需要生成的文件名或者为了实现这个目的而必需的中间过程文件名。可以是.o文件、也可以是最后的可执行程序的文件名等。另外,目标也可以是一个make执行的动作的名称,如目标“clean”,我们称这样的目标是“伪目标”。

prerequisites:规则的依赖。生成规则目标所需要的文件名列表。通常一个目标依赖于一个或者多个文件。

command:规则的命令行。是规则所要执行的动作(任意的shell命令或者是可在shell下执行的程序)。它限定了make执行这条规则时所需要的动作。一个规则可以有多个命令行,每一条命令占一行。注意:每一个命令行必须以[Tab]字符开始,[Tab]字符告诉make此行是一个命令行。命令就是在任何一个目标的依赖文件发生变化后重建目标的动作描述。一个目标可以没有依赖而只有动作(指定的命令)。比如Makefile中的目标“clean”,此目标没有依赖,只有命令。它所定义的命令用来删除make过程产生的中间文件(进行清理工作)。

在Makefile中“规则”就是描述在什么情况下、如何重建规则的目标文件,通常规则中包括了目标的依赖关系(目标的依赖文件)和重建目标的命令。make执行重建目标的命令,来创建或者重建规则的目标(此目标文件也可以是触发这个规则的上一个规则中的依赖文件)。规则包含了文件之间的依赖关系和更新此规则目标所需要的命令。

执行过程

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

默认的情况下,make执行的是Makefile中的第一个规则,此规则的第一个目标称之为“最终目的”或者“终极目标”。make首先处理目标的所有依赖文件(如.o文件)的更新规则(以这些.o文件为目标的规则)。对这些.o文件为目标的规则处理有下列三种情况:

  • 目标.o文件不存在,使用其描述规则创建它;
  • 目标.o文件存在,目标.o文件所依赖的.c源文件、.h文件中的任何一个比目标.o文件“更新”(在上一次make之后被修改)。则根据规则重新编译生成它;
  • 目标.o文件存在,目标.o文件比它的任何一个依赖文件(的.c源文件、.h文件)“更新”(它的依赖文件在上一次make之后没有被修改),则什么也不做。

对于一个Makefile文件,“make”首先解析终极目标所在的规则,根据其依赖文件依次寻找创建这些依赖文件的规则。首先为第一个依赖文件寻找创建规则,如果第一个依赖文件依赖于其它文件,则同样为这个依赖文件寻找创建规则,直到为所有的依赖文件找到合适的创建规则。之后make从最后一个规则回退开始执行,最终完成终极目标的第一个依赖文件的创建和更新。之后对第二个、第三个、第四个……终极目标的依赖文件执行同样的过程。

更新(或者创建)终极目标的过程中,如果任何一个规则执行出现错误make就立即报错并退出。整个过程make只是负责执行规则,而对具体规则所描述的依赖关系的正确性、规则所定义的命令的正确性不做任何判断。就是说,一个规则的依赖关系是否正确、描述重建目标的规则命令行是否正确,make不做任何错误检查。

在使用make编译.c源文件时,编译.c源文件规则的命令可以不用明确给出。这是因为make本身存在一个默认的规则,能够自动完成对.c文件的编译并生成对应的.o文件。它执行命令“cc -c”来编译.c源文件。在Makefile中我们只需要给出需要重建的目标文件名(一个.o文件),make会自动为这个.o文件寻找合适的依赖文件(对应的.c文件。对应是指:文件名除后缀外,其余都相同的两个文件),而且使用正确的命令来重建这个目标文件。

一点建议

书写规则建议的方式是:单目标,多依赖。就是说尽量要做到一个规则中只存在一个目标文件,可有多个依赖文件。尽量避免使用多目标,单依赖的方式。这样书写的好处是后期维护会非常方便,而且这样做会使Makefile会更清晰、明了。

Logo

更多推荐