掌握Makefile:自动推导与隐含规则解析

需积分: 50 96 下载量 21 浏览量 更新于2024-08-07 收藏 632KB PDF 举报
"使用隐含规则-托马斯微积分第十版" 在编程领域,`Makefile` 是一种用于自动化构建项目的文件,它定义了一系列规则来编译、链接和其他方式处理源代码。本文将深入讲解如何利用隐含规则在 `Makefile` 中提升效率。 隐含规则是 `make` 工具预设的一些通用规则,用于自动推导构建目标的编译和链接过程。例如,`make` 默认知道 `.c` 文件应该用 C 编译器(`cc`)编译成 `.o` 目标文件,并且默认知道如何将多个 `.o` 文件链接成一个可执行文件。在给定的 `Makefile` 示例中,`foo` 可执行文件依赖于 `foo.o` 和 `bar.o`,`make` 会自动应用隐含规则来编译和链接这些文件。 1. **概述** - 程序的编译和链接:通常,源代码(如 `.c` 或 `.cpp` 文件)需要经过编译(生成对象文件)和链接(生成可执行文件)两个步骤。 2. **makefile介绍** - 规则:`makefile` 的核心部分是由一系列规则组成,每个规则定义了一个或多个目标及其依赖项,以及如何生成目标的命令。 - 示例:例如,`foo : foo.o bar.o` 规则表示 `foo` 文件依赖于 `foo.o` 和 `bar.o`,`cc –o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)` 是执行的命令。 - 自动推导:`make` 可以尝试自动推导未明确指定的规则,比如编译 `.c` 文件到 `.o` 文件的规则。 3. **书写规则** - 规则的语法:规则通常包含目标、依赖项和命令,例如 `target : dependency... command...`。 - 通配符:`*` 可以用来匹配多个文件,如 `*.c` 匹配所有 `.c` 文件。 - 文件搜寻:`make` 可以通过包含路径来寻找依赖文件。 - 伪目标:`PHONY` 目标如 `.PHONY` 不代表实际文件,用于确保命令总是被执行,不受同名文件影响。 - 多目标:一个规则可以创建多个目标,通过逗号分隔。 - 静态模式:静态模式规则使用 `%` 作为通配符,可以生成多个规则。 - 自动生成依赖性:可以使用 `-M` 或 `-MM` 选项让编译器自动生成依赖性。 4. **书写命令** - 显示命令:使用 `\` 在行尾断行可以让命令在 `make` 运行时不被折叠。 - 命令执行:`make` 会逐行执行命令,每行被视为一个单独的 shell 命令。 - 错误处理:如果命令执行失败,`make` 通常会停止执行并返回错误。 - 嵌套 `make`:一个 `make` 可以调用另一个 `make` 来处理子项目或库。 - 命令包:使用 `$(shell cmd)` 来在一个命令中执行 shell 脚本。 5. **使用变量** - 变量基础:变量可以存储值,简化 `makefile` 并允许复用。 - 变量中的变量:变量可以包含其他变量的值,实现复杂表达式。 - 追加值:`+=` 操作符可以向变量添加新值而不覆盖原有值。 - `override` 指示符:强制 `make` 使用规则中的变量值,即使在环境变量中已经定义了相同的变量。 - 多行变量:使用 `\` 结束行可以使变量跨行。 - 环境变量:`make` 可以访问环境变量,除非被 `makefile` 中的变量覆盖。 - 目标变量:仅在特定目标中可见的局部变量。 - 模式变量:与模式规则相关的变量,可以用于动态设置规则属性。 6. **使用条件判断** - 条件判断允许根据变量的值选择执行不同的规则或命令。 7. **使用函数** - `make` 提供了一组函数来处理字符串和文件名,增强 `makefile` 的灵活性。 - 字符串处理函数如 `subst`, `patsubst`, `strip`, `findstring`, `filter`, `filter-out`, `sort`, `word`, `wordlist`, `words`, `firstword` 用于处理字符串。 - 文件名操作函数如 `dir`, `notdir` 分别提取路径和文件名。 通过巧妙地利用隐含规则和 `makefile` 的各种特性,可以编写出高效、简洁且易于维护的构建脚本,使得软件工程的构建过程更加自动化和标准化。在编写 `Makefile` 时,理解并善用这些概念和工具是非常重要的。