### 跟我一起写Makefile #### 第一部分:概述 Makefile 是一种用于自动化构建过程的脚本文件,主要用于 Linux 和 Unix 类操作系统中。它能够帮助开发者通过编写一系列指令来自动化编译、链接和安装等操作,极大地提高了开发效率。 #### 第二部分:关于程序的编译和链接 程序的编译过程包括将源代码转换为机器可识别的目标代码,而链接则是将这些目标代码文件以及所需的库文件组合成一个可执行文件的过程。Makefile 在这个过程中扮演着核心角色,它通过定义一系列规则来管理整个编译和链接流程。 #### 第三部分:Makefile介绍 ##### 一、Makefile的规则 Makefile 规则通常包含目标、依赖项和命令三个主要部分: - **目标**(Target):规则最终要生成的文件。 - **依赖项**(Prerequisites):目标生成前需要满足的文件或规则。 - **命令**(Commands):用于生成目标的具体步骤。 例如,以下是一个简单的 Makefile 规则示例: ```makefile target: prerequisites command ``` ##### 二、一个示例 考虑一个简单的 C 语言程序 `hello.c`,我们希望生成一个名为 `hello` 的可执行文件。可以编写如下 Makefile: ```makefile CC=gcc CFLAGS=-Wall -g hello: hello.o $(CC) $(CFLAGS) -o $@ $^ hello.o: hello.c $(CC) $(CFLAGS) -c $< -o $@ ``` 这个 Makefile 定义了两个规则:`hello.o` 和 `hello`。`hello.o` 规则将源文件 `hello.c` 编译为目标文件 `hello.o`;`hello` 规则将 `hello.o` 链接成可执行文件 `hello`。 ##### 三、make是如何工作的 当执行 `make` 命令时,make 工具会读取 Makefile 文件,并根据其中定义的规则来确定哪些文件需要被编译或链接。make 会跟踪每个文件的修改时间戳,只有当目标文件比其依赖项更旧时才会重新执行相关的命令。 ##### 四、makefile中使用变量 Makefile 支持使用变量来简化规则的编写。变量可以是工具名称、编译选项或其他与构建过程相关的值。 例如,在上面的示例中,`CC` 变量指定了编译器路径,而 `CFLAGS` 则存储了一组编译选项。 ##### 五、让make自动推导 make 允许自动推导目标文件的依赖关系。例如,如果 Makefile 中存在规则 `a.o: a.c`,那么 make 会自动推断出如果 `a.c` 更新,则需要重新编译 `a.o`。 ##### 六、另类风格的makefile 除了传统的 Makefile 格式之外,还有一些非标准但同样有效的格式,例如使用 YAML 或 JSON 来定义 Makefile 规则。 ##### 七、清空目标文件的规则 在开发过程中,经常需要清理之前构建的文件。为此,可以在 Makefile 中定义一个专门用于清理的规则,如: ```makefile clean: rm -f *.o hello ``` 这条规则会删除所有 `.o` 文件和 `hello` 可执行文件。 #### 第四部分:Makefile总述 Makefile 可以包含多种不同的元素,如显式规则、隐含规则、变量定义等。 ##### 一、Makefile里有什么? 1. **显式规则**:明确指定目标文件和其依赖文件之间的关系。 2. **隐晦规则**:make 自动推断的规则。 3. **变量的定义**:用于简化 Makefile 的编写。 4. **文件指示**:用于包含其他 Makefile 文件。 5. **注释**:以 `#` 开头的行。 ##### 二、Makefile的文件名 默认情况下,make 会在当前目录下查找名为 `Makefile` 或 `makefile` 的文件。 ##### 三、引用其它的Makefile 可以通过 `.include` 指令来引入其他 Makefile 文件: ```makefile .include "other.mk" ``` ##### 四、环境变量MAKEFILES `MAKEFILES` 环境变量用于指定额外的 Makefile 文件路径。 ##### 五、make的工作方式 1. **读取 Makefile**:解析并加载 Makefile 文件。 2. **计算依赖关系**:根据规则和文件的时间戳确定需要构建的目标。 3. **执行命令**:对于需要更新的目标执行相应的命令。 #### 第五部分:书写规则 ##### 一、规则举例 一个简单的规则示例: ```makefile target: prereq command ``` ##### 二、规则的语法 规则的基本语法如下: ```makefile target: prereq command ``` ##### 三、在规则中使用通配符 通配符可以用来匹配一组文件。例如: ```makefile %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ ``` 这里 `%` 表示任意字符序列。 ##### 四、文件搜寻 如果依赖文件不在当前目录,make 会在预定义的目录列表中搜索该文件。 ##### 五、伪目标 伪目标是一种特殊的规则,它们不表示真实的文件,而是代表某种操作。例如: ```makefile .PHONY: clean clean: rm -f *.o hello ``` ##### 六、多目标 有时一个规则可能会生成多个目标文件。例如: ```makefile obj1.o obj2.o: obj.h $(CC) $(CFLAGS) -c $< -o $@ ``` ##### 七、静态模式 静态模式规则允许使用更复杂的通配符和自动化变量来简化规则的编写。 #### 第六部分:书写命令 Makefile 中的命令是用来执行具体操作的 shell 命令。 ##### 一、显示命令 通过 `@` 符号可以隐藏命令的执行,仅显示命令本身而不显示执行信息。 ##### 二、命令执行 Makefile 中的命令会被解释器逐条执行。 ##### 三、命令出错 如果命令执行失败,make 会停止执行并返回错误。 ##### 四、嵌套执行make 可以在 Makefile 中使用 `$(MAKE)` 来递归调用 make。 ##### 五、定义命令包 可以将多个命令封装在一个变量中,然后在规则中使用。 #### 第七部分:使用变量 变量在 Makefile 中扮演着重要角色,可以极大地提高规则的复用性和维护性。 ##### 一、变量的基础 变量定义的基本形式为: ```makefile VAR = value ``` ##### 二、变量中的变量 可以在变量定义中引用其他变量。 ##### 三、变量高级用法 包括条件赋值、递归展开等高级功能。 ##### 四、追加变量值 使用 `+=` 运算符可以在原有基础上追加值。 ##### 五、override指示符 可以覆盖其他 Makefile 中的变量定义。 ##### 六、多行变量 变量值可以跨越多行。 ##### 七、环境变量 可以访问系统的环境变量。 ##### 八、目标变量 特定于某个目标的变量。 ##### 九、模式变量 与模式规则相关的变量。 #### 第八部分:使用条件判断 ##### 一、示例 使用 `ifeq`、`ifdef` 等指令来实现条件判断。 ##### 二、语法 条件判断的基本语法如下: ```makefile ifeq (condition, true_part, false_part) ``` #### 第九部分:使用函数 Makefile 提供了许多内置函数,可以用来处理字符串、文件名等。 ##### 一、函数的调用语法 函数调用的一般格式为: ```makefile $(function_name(arg1, arg2, ...)) ``` ##### 二、字符串处理函数 1. **subst**:替换字符串。 2. **patsubst**:模式替换。 3. **strip**:去除空白字符。 4. **findstring**:查找子字符串。 5. **filter**:过滤字符串。 6. **filter-out**:排除某些字符串。 7. **sort**:排序。 8. **word**、**wordlist**、**words**、**firstword**:操作字符串列表。 9. **dir**、**notdir**:处理路径。 10. **suffix**、**basename**:获取文件扩展名或基本名称。 11. **addsuffix**、**addprefix**:添加后缀或前缀。 12. **join**:连接字符串列表。 #### 第十部分:make的运行 ##### 一、make的退出码 make 会根据执行结果返回不同的退出码。 ##### 二、指定Makefile 可以通过 `-f` 或 `--file` 参数指定 Makefile 文件路径。 ##### 三、指定目标 通过 `-t` 或 `--target` 参数指定 make 执行的目标。 ##### 四、检查规则 可以使用 `-n` 或 `--just-print` 参数来查看 make 将要执行的操作。 ##### 五、make的参数 包括 `-j`、`-k` 等选项,用于控制 make 的行为。 #### 第十一部分:隐含规则 ##### 一、使用隐含规则 make 提供了一系列内置的隐含规则,可以根据文件扩展名推断出编译命令。 ##### 二、隐含规则一览 包括针对 C、C++、Pascal 等语言的隐含规则。 ##### 三、隐含规则使用的变量 隐含规则中可以使用各种变量来定制编译行为。 ##### 四、隐含规则链 隐含规则可以形成链式反应,使 make 能够处理复杂的编译任务。 ##### 五、定义模式规则 模式规则允许使用更复杂的通配符和自动化变量。 ##### 六、老式风格的"后缀规则" 旧版本 Makefile 中常用的规则类型。 ##### 七、隐含规则搜索算法 make 使用特定算法来确定使用哪个隐含规则。 #### 第十二部分:使...(原文未给出完整内容) 这一部分可能涉及如何利用 Makefile 的特性来进一步优化构建过程,例如使用条件判断和函数来动态地调整构建行为,或者使用模式规则来简化复杂项目的构建规则等。
剩余77页未读,继续阅读
- 粉丝: 1
- 资源: 2
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助