3.6 Make程序和Makefile文件
从前面给出的程序例子可知,当创建由一个或少数几个源程序生成的执行执行时,只需要在命令行上键入几个简单的命令即可做到。但是对于像内核这样的大型程序来说,若仅使用手工键入一行行命令来编译所有代码文件,其繁杂程度是极大的。make程序正是设计用于自动处理这类情况的最佳工具,其主要功能是能够自动地确定在一个包含很多源文件的大型程序中哪些文件需要被重新编译,并对这些文件发出重新编译的命令。下面以编译C程序为例说明make的简要使用方法,但你可以将其应用于任何可使用shell命令进行编译的编程语言。有关make的详细使用方法请参考《GNU make使用手册》。本书论坛上有其中文版可供下载。
为了使用make工具程序,需要先编写一个名称为Makefile(或makefile)的文本文件供make执行时使用。Makefile文件中主要包含一些make要遵守的执行规则和要求执行的命令等内容,用于告诉make需要对所涉及的源文件做哪些操作和处理以生成相应的目标文件。
3.6.1 Makefile文件内容
一个Makefile文件可以包括五种元素:显式规则、隐含规则、变量定义、指示符和注释信息。
显式规则(explicit rules)用于指定何时以及怎样重新编译一个或多个被称作规则的目标(rule's targets)的文件。规则中明确列出了目标所依赖的被称为目标的先决条件(或依赖)的其他文件,同时也会给出用于创建或更新目标的命令。
隐含规则(implicit rules)则是根据目标和对象的名称来确定何时和如何重新编译一个或多个被称作规则的目标的文件。这种规则描述了目标是如何依赖于与目标名称相类似的文件,并会给出用于创建或更新这样的一个目标文件。
变量定义(variable definitions)用于在一行上为一个变量定义一个文本字符串。该变量可在后续语句中被替换。例如后面例子中的变量objects定义了所有.o文件的列表。
指示符(directives)是make的一个命令,用于指示其在读取Makefile文件时执行的特定操作。这些操作可包括读取另一个makefile文件;确定使用或忽略makefile文件的某部分内容和从包含多行的字符串中定义一个变量。
注释(comments)是指Makefile文件中以"#"字符开始的文字部分。如果确实需要使用"#"字符,我们需要对其进行转义,即在该字符前添加一个反斜杠字符("\#")。注释可以出现在Makefile文件的任何地方。另外,Makefile文件中以制表符TAB开始的一行命令脚本会被完整地被传递给shell,shell会判断这是一条命令还是只是一个注释信息。
一旦编写好一个适当的Makefile文件,那么每次修改源程序后我们就可以在shell命令行上简单地键入"make"来执行所有必要的程序更新操作。make会根据Makefile中的内容以及文件的最后更新时间来确定哪些文件需要被更新(重新编译)。对于每个需要被更新的文件,make会执行Makefile文件中记录的相关命令。