WHAT
Makefile 是一种文本文件,由一系列规则(Rules)组成,每个规则描述了一个或多个目标(Target)和相应的依赖关系(Dependencies),以及构建目标所需的命令(Commands)。
以下是最简单的规则示例:
targets: dependenciescommandcommandcommand
target:目标的名称,通常一个规则只有一个目标;
dependencies: 目标所依赖的文件或操作,通常用空格隔开;
command:构建目标所需的命令(注意,这里必须用tab缩进,不能用空格)。
WHY
- 自动化构建:Makefile可以自动化执行构建过程,包括编译源代码、链接库文件、生成可执行文件等。通过定义规则和依赖关系,Makefile 可以根据文件的修改时间和依赖关系来确定需要重新构建的文件,从而减少手动操作和避免不必要的重复编译。
- 跨平台支持:Makefile 是一种与平台无关的构建工具,可以在不同的操作系统上使用,包括 Linux、Unix、macOS 等。
- 灵活性和可扩展性:Makefile 提供了丰富的语法和功能,允许开发人员定义变量、条件语句、循环等,以实现更复杂的构建逻辑。
- 组织和管理依赖关系:Makefile 可以清晰地定义目标和依赖关系,当某个文件或模块发生变化时,Makefile 可以自动识别需要重新构建的目标,并自动更新相关的文件。
- 构建多个目标:Makefile 支持定义多个目标和规则,可以同时构建多个目标,提高构建效率。这对于大型项目或具有多个模块的项目特别有用。
HOW
- 理解目标和依赖关系:目标是需要构建的文件或操作的名称,依赖关系指定了目标所依赖的文件或操作。在 Makefile 中,目标和依赖关系通常以文件名的形式表示。
- 了解常用的内置变量:在 Makefile 中,可以使用内置变量来简化和控制构建过程,例如指定编译器、链接器、目标文件等,以下是常见的内置变量。
注意:内置变量的命名通常使用大写字母,并使用括号 $(…) 进行引用。
| |
---|---|
$(CC) | C 编译器的名称,默认为 cc |
$(CXX) | C++ 编译器的名称,默认为 g++ |
$(AR) | 静态库归档工具的名称,默认为 ar |
$(LD) | 链接器的名称,默认为 $(CC) |
$(RM) | 删除文件的命令,默认为 rm -f |
$(MAKE) | Make 工具的名称,默认为 make |
$(MAKECMDGOALS) | 包含了命令行上指定的目标列表 |
$(MAKEFILE_LIST) | 当前 Makefile 的文件名列表 |
$(CURDIR) | 当前工作目录的绝对路径 |
$(PWD) | 当前工作目录的绝对路径(与 $(CURDIR) 相同) |
$(SHELL) | Shell 程序的名称,默认为 /bin/sh |
$(MAKE_VERSION) | Make 工具的版本号 |
- 理解变量的使用:Makefile 中可以定义变量来存储和传递值。
自定义变量:除了使用内置变量外,可以根据需要定义自己的变量,用于存储特定的值、路径、文件列表等。自定义变量的命名通常使用大写字母和下划线分隔单词,以提高可读性。
| | |
---|---|---|
= | 延迟展开(在使用这个变量时,其右侧的表达式才会被解析) | VAR = value TARGET = $(VAR) VAR = new_value 在这个例子中,TARGET 的值将会是 new_value,因为在赋值时 $(VAR) 被设置为 value,但后来 VAR 的值又被重新赋为 new_value。 |
:= | 立即展开(在赋值时就会对右侧的表达式进行解析) | VAR := value TARGET := $(VAR) VAR := new_value 在这里,TARGET 的值将会是 value,因为在赋值时 $(VAR) 的值已经是 value,后续对 VAR 的修改不会影响 TARGET。 |
?= | 条件赋值(仅当变量未被赋值时才会赋值) | VAR ?= value 如果 VAR 已经有了值,比如通过命令行传递了参数,那么它将保留该值,否则会被设置为 value。 |
+= | 追加值(在原有值的末尾添加新的值) | VAR += new_value 如果 VAR 已经有值,那么 new_value 将会被追加到其末尾;如果 VAR 没有值,则相当于使用 VAR = new_value。 |
- 学习常用的命令:Makefile 中的命令用于执行构建操作。命令通常以制表符开头,并且在同一行中。命令可以是任何有效的 Shell 命令。
| |
---|---|
echo text | 打印文本到标准输出 |
cd directory | 切换当前工作目录到指定目录 |
mkdir directory | 创建新的目录 |
rm file | 删除文件 |
cp source destination | 复制文件或目录 |
- 了解常用的内置函数:内置函数用于在 Makefile 中执行各种操作和处理文本。它们可以帮助实现复杂的构建逻辑、文件操作和任务执行。
| |
---|---|
$(shell command) | 执行命令并返回其输出结果 |
$(wildcard pattern) | 匹配指定模式的文件列表 |
$(foreach var, list, text) | 对列表中的每个元素执行指定操作 |
$(if condition, then-part, else-part) | 根据条件选择执行不同的操作 |
$(subst from, to, text) | 将文本中的指定字符串替换为另一个字符串 |
- 阅读 Makefile 的注释:Makefile 中的注释以 # 开头,可以提供对规则和命令的解释和说明。
- 实践和尝试:通过阅读和分析现有的 Makefile,并尝试自己编写简单的 Makefile,来加深对 Makefile 的理解和熟悉。