本文比较完整的讲述GNU make工具,涵盖GNU make的用法、语法。同时重点讨论如何为一个工程编写Makefile。作为一个Linux程序员,make工具的使用以及编写Makefile是必需的。系统、详细讲述make的中文资料比较少,出于对广大中文Linuxer的支持,本人在工作之余,花了18个多月时间完成对“info make”的翻译整理,完成这个中文版手册。本书不是一个纯粹的语言翻译版本,其中对GNU make的一些语法和用法根据我个人的工作经验进行了一些详细分析和说明,也加入了一些个人的观点和实践总结。本书的所有的例子都可以在支持V3.8版本的GNU make的系统中正确执行。
由于个人水平限制,本文在一些地方存在描述不准确之处。恳请大家在阅读过程中,提出您宝贵的意见,也是对我个人的帮助。我的个人电子邮箱地址:xhbdahai@126.com。非常愿意和大家交流!共同学习。
### GUN_make中文手册知识点概览
#### 一、GNU Make工具概述
GNU Make是一款功能强大的自动化构建工具,广泛应用于软件开发过程中。它通过解析Makefile文件中的指令来管理项目的构建流程,帮助开发者自动化编译、链接等任务,极大地提高了工作效率。
**1.1 概述**
GNU Make的核心是Makefile文件,它定义了项目中各个文件之间的依赖关系及如何构建这些文件。Makefile可以非常简单,只包含几行代码,也可以非常复杂,涉及大量的规则和变量定义。
**1.2 准备知识**
使用GNU Make之前,需要具备一定的基础知识,包括但不限于:
- 基本的命令行操作能力。
- 对于目标文件、依赖文件、规则等概念的理解。
- 对于shell脚本有一定的了解。
#### 二、GNU Make介绍
GNU Make的核心在于如何编写有效的Makefile文件。
**2.1 Makefile简介**
Makefile文件包含了构建项目的规则和变量定义。每个规则定义了一个目标(通常是输出文件),以及构建该目标所需的依赖文件和命令。
**2.2 Makefile规则介绍**
规则是Makefile中最基本的组成部分,其格式通常为:
```
target : dependencies
command
```
- `target`:目标文件。
- `dependencies`:构建目标所需要的依赖文件。
- `command`:构建目标所需的命令。
**2.3 简单的示例**
例如,一个简单的Makefile可能如下所示:
```
all: main.o helper.o
gcc -o myprogram main.o helper.o
main.o: main.c
gcc -c main.c
helper.o: helper.c
gcc -c helper.c
```
**2.4 make如何工作**
当make被调用时,它会读取Makefile文件并根据其中定义的规则执行相应的命令。make会检查目标文件和依赖文件的时间戳,如果依赖文件比目标文件新,则执行相应的命令来更新目标文件。
**2.5 指定变量**
Makefile支持定义变量,这可以简化规则的编写。例如:
```
CC = gcc
CFLAGS = -Wall -g
all: main.o helper.o
$(CC) $(CFLAGS) -o myprogram main.o helper.o
```
**2.6 自动推导规则**
GNU Make支持自动推导规则,这意味着对于某些常见的文件扩展名,make可以自动确定如何构建目标文件而无需显式定义规则。例如,对于`.c`到`.o`的转换,make可以自动识别。
**2.7 另类风格的makefile**
除了传统的Makefile风格外,还可以使用其他风格,如使用`make -f`选项指定Makefile文件的位置。
**2.8 清除工作目录过程文件**
通常还需要定义一个`clean`目标来清除构建过程中产生的临时文件,例如:
```
clean:
rm -f *.o myprogram
```
#### 三、Makefile总述
这部分深入介绍了Makefile文件的结构、命名、包含机制等。
**3.1 Makefile的内容**
Makefile通常包含以下内容:
- 规则定义。
- 变量定义。
- 注释和其他元数据。
**3.2 makefile文件的命名**
默认情况下,make会查找名为`Makefile`、`makefile`或`Makefile-`的文件作为构建规则的来源。
**3.3 包含其它makefile文件**
Makefile支持通过`include`指令包含其他文件,这有助于组织大型项目中的构建规则:
```
include common.mk
```
**3.4 变量MAKEFILES**
`MAKEFILES`变量用于记录包含的Makefile文件列表。
**3.5 变量MAKEFILE_LIST**
`MAKEFILE_LIST`变量用于列出所有被包含的Makefile文件。
**3.6 其他特殊变量**
GNU Make还支持其他特殊变量,例如`$@`代表目标文件,`$<`代表第一个依赖文件等。
**3.7 makefile文件的重建**
当Makefile文件发生更改时,make可以通过重新解析Makefile文件来更新规则。
**3.8 重载另外一个makefile**
有时可能需要在构建过程中动态地加载另一个Makefile文件,这可以通过`make -f`命令行选项实现。
**3.9 make如何解析makefile文件**
- **3.9.1 变量取值**:make在解析Makefile文件时会处理变量定义,并在需要时展开它们。
- **3.9.2 条件语句**:Makefile支持条件执行逻辑,例如使用`ifeq`、`ifdef`等指令。
- **3.9.3 规则的定义**:make解析Makefile文件中的规则,并根据需要执行命令。
**3.10 总结**
本章节涵盖了Makefile的基础结构和一些高级特性,为读者提供了编写高效Makefile的基础知识。
#### 四、Makefile的规则
这一部分详细解释了Makefile中的规则定义及其各种特性。
**4.1 一个例子**
本节通过具体的示例解释了如何定义规则。
**4.2 规则语法**
详细介绍了规则的语法结构,包括目标、依赖和命令。
**4.3 依赖的类型**
讲解了不同类型的依赖关系,如显式依赖和隐式依赖。
**4.4 文件名使用通配符**
通配符的使用可以让Makefile更加灵活,例如:
```
%.o: %.c
gcc -c $< -o $@
```
**4.5 目录搜寻**
GNU Make支持通过`VPATH`变量或`vpath`关键字来搜索不在当前目录下的文件。
**4.6 Makefile伪目标**
伪目标是一种特殊的规则,用于定义不会创建任何物理文件的目标,例如`all`和`clean`。
**4.7 强制目标(没有命令或依赖的规则)**
有些目标只是为了方便构建流程而定义的,不涉及实际的文件操作。
**4.8 空目标文件**
空目标文件通常用于标记某个状态。
**4.9 Makefile的特殊目标**
特殊目标用于执行特定的功能,如`PHONY`目标。
**4.10 多目标**
一个规则可以有多个目标文件。
**4.11 多规则目标**
一个目标文件可以由多个规则定义。
**4.12 静态模式**
静态模式允许使用模式匹配来定义一系列相似的目标文件。
**4.13 双冒号规则**
双冒号规则用于定义多个依赖文件与同一个目标文件的关系。
**4.14 自动产生依赖**
GNU Make支持自动检测依赖关系,这对于大型项目特别有用。
#### 五、规则的命令
这一部分详细介绍了如何为规则编写命令。
**5.1 命令回显**
命令执行前是否显示命令字符串。
**5.2 命令的执行**
命令的执行方式及其控制方法。
**5.3 并发执行命令**
make支持并行执行命令以提高构建效率。
**5.4 命令执行的错误**
如何处理命令执行过程中出现的错误。
**5.5 中断make的执行**
在某些条件下中断make的执行。
**5.6 make的递归执行**
递归调用make的过程及其应用场景。
**5.7 定义命令包**
命令包的概念及其用法。
**5.8 空命令**
在某些情况下,可能需要定义空命令。
#### 六、Makefile中的变量
这部分讲解了Makefile中变量的定义、使用和一些高级用法。
**6.1 变量的引用**
如何在Makefile中引用变量。
**6.2 两种变量定义(赋值)**
介绍了两种变量定义的方式:递归展开式变量和直接展开式变量。
**6.3 变量的高级用法**
变量的替换引用、套嵌引用等高级用法。
**6.4 变量取值**
如何获取变量的实际值。
**6.5 如何设置变量**
设置变量的方法和注意事项。
**6.6 追加变量值**
追加变量值的方法及其应用场景。
**6.7 override指示符**
使用`override`指示符来覆盖已定义的变量。
**6.8 多行定义**
如何在Makefile中定义多行变量。
**6.9 系统环境变量**
如何在Makefile中引用系统环境变量。
**6.10 目标指定变量**
针对特定目标定义变量。
**6.11 模式指定变量**
根据模式匹配来定义变量。
#### 七、Makefile的条件执行
这部分介绍了如何在Makefile中实现条件执行逻辑。
**7.1 一个例子**
通过示例展示如何使用条件执行。
**7.2 条件判断的基本语法**
Makefile中条件执行的基本语法。
**7.3 标记测试的条件语句**
如何使用条件语句来测试文件或变量的状态。
#### 八、make的内嵌函数
这部分讲解了GNU Make提供的各种内嵌函数及其用途。
**8.1 函数的调用语法**
如何在Makefile中调用函数。
**8.2 文本处理函数**
GNU Make提供了一系列文本处理函数,用于处理字符串、列表等。
- **8.2.1 $(substFROM,TO,TEXT)**:用于替换字符串中的子串。
- **8.2.2 $(patsubstPATTERN,REPLACEMENT,TEXT)**:模式替换函数。
- **8.2.3 $(stripSTRINT)**:移除字符串两端的空白字符。
- **8.2.4 $(findstringFIND,IN)**:查找子串。
- **8.2.5 $(filterPATTERN…,TEXT)**:筛选出匹配模式的项。
- **8.2.6 $(filter-outPATTERN,TEXT)**:筛选出不匹配模式的项。
- **8.2.7 $(sortLIST)**:对列表进行排序。
- **8.2.8 $(wordN,TEXT)**:获取列表中的第N个元素。
- **8.2.9 $(wordlistS,E,TEXT)**:获取列表中的第S到E个元素。
- **8.2.10 $(wordsTEXT)**:返回列表中元素的数量。
- **8.2.11 $(firstwordTEXT)**:获取列表中的第一个元素。
以上知识点覆盖了GNU Make工具的核心功能和使用方法,对于Linux程序员来说是非常重要的技能。通过熟练掌握这些内容,可以在项目管理和构建自动化方面大大提高效率。
1