Makefile的语法是围绕“规则”展开的,每条规则定义了如何生成一个或多个目标文件,以及这些目标文件依赖于哪些其他文件。下面详细讲解Makefile的语法。
-
注释
Makefile中的注释以#
开头,直到行尾。注释可以出现在Makefile的任何位置,用来解释规则或命令的作用。 -
变量
Makefile中可以使用变量来存储文件名、编译器选项等常用值,以便在多处引用。变量在赋值时不加$
符号,但在引用时需要在变量名前加$
符号,并可以用圆括号{}
或不加来包围变量名。CC=gcc CFLAGS=-Wall -g program: main.o $(CC) $(CFLAGS) main.o -o program
-
规则
规则是Makefile的核心,每条规则由目标(target)、依赖(dependencies)和命令(commands)三部分组成。- 目标(Target):通常是文件名,可以是可执行文件、对象文件(.o)或其他需要生成的文件。目标可以是多个,通过空格分隔。
- 依赖(Dependencies):生成目标所需的其他文件列表,用空格分隔。如果依赖文件比目标文件新,或者目标文件不存在,那么就会执行命令来更新目标文件。
- 命令(Commands):用于生成目标的命令序列,每条命令必须以Tab键开头,而不是空格。命令会在shell中执行。
-
通配符
Makefile支持Unix风格的通配符,如*
(匹配任意数量的任意字符)、?
(匹配任意单个字符)等,用于指定一组文件。objects = *.o
但注意,在变量赋值时通配符不会被立即展开,而是在规则中使用时才会。
-
自动变量
Makefile提供了一些自动变量,用于在规则中简化文件名的书写。常用的自动变量有:$@
:表示规则中的目标文件名。$<
:表示规则中的第一个依赖文件名。$^
:表示规则中的所有依赖文件名,使用空格分隔。$?
:表示所有比目标文件新的依赖文件名,列表以空格分隔。
-
伪目标
伪目标(Phony Target)是那些不实际对应文件的规则。伪目标的主要作用是执行一系列命令。为了避免与同名文件冲突,可以使用.PHONY
特殊目标来显式声明伪目标。.PHONY: clean clean: rm -f *.o program
-
条件判断
Makefile支持条件判断,可以根据不同的条件执行不同的命令。条件判断通常与变量和函数结合使用。ifeq ($(CC),gcc) CFLAGS=-Wall -g else CFLAGS=-O2 endif
-
函数
Makefile提供了一系列内置函数,用于对字符串、文件名等进行处理。函数的使用语法是$(function arguments)
。
- 字符串处理函数:如
subst
(字符串替换)、patsubst
(模式字符串替换)等。 - 文件名处理函数:如
wildcard
(查找匹配的文件名)、dir
(取目录部分)、notdir
(取文件名部分)等。 - 其他函数:如
foreach
(循环遍历)、if
(条件判断,注意不是上面提到的条件判断语法)、call
(函数调用)等。
-
包含其他Makefile
可以使用include
指令包含其他Makefile文件,这有助于将大型项目的构建规则拆分成多个更小的文件。include another.mk
总结
Makefile的语法围绕规则展开,通过定义目标、依赖和命令来自动化编译和构建过程。变量、通配符、自动变量、伪目标、条件判断和函数等特性使得Makefile更加强大和灵活。