Makefile基本规则
规则描述了何种情况下使用什么命令来重建一个特定的文件,此文件被称为规则目标(通常只有一个)。规则所罗列的其他文件被称为目标的依赖,而规则的命令是用来更新或创建此规则的目标。
终极目标时当没有使用make命令指定具体目标时,make默认的哪一个目标,是Makefile文件中第一个规则的目标。如果Makefile中第一个规则有多个目标,那么多个目标中的第一个将被作为make的终极目标。有两种例外情况:
- 目标名是以点号.开始的,其后不存在斜线/
- 作为模式规则的目标
终极目标是执行Makefile的唯一目的,其所在的规则作为第一个规则。
规则举例
foo.o:foo.c defs.h
cc -c -g foo.c
第一行文件foo.o时规则需要重建的文件(目标),而foo.c和defs.h时重建foo.o所需要的文件(依赖) 。
第二行是规则的命令,描述了如何使用规则中的依赖文件重建目标。
规则语法
通常规则语法如下
TARGETS:PREREQUISITES
COMMAND
...
或
TARGETS:PREREQUISITES;COMMAND
COMMAND
...
规则中,TARGETS可以是空格分开的多个文件名,也可以是一个标签(执行清空的clean)
TRAGETS的文件名可以是通配符,格式A(M)表示文件A的成员M。通常规则只有一个目标文件(建议),偶尔会又多个目标。
两种书写方式:
- 命令可以和目标、依赖描述放在同一行,命令在依赖文件列表后并使用分号;和依赖文件列表分开
- 命令在目标、依赖描述的下一行,作为独立的命令行。以Tab字符开始。
Makefile中的$有特殊的含义(变量或函数的引用),如果规则要使用$,需要书写两个连续的$$。
Makefile一个较长的行,可以使用反斜线\书写到几个独立的物理行上。虽然make对Makefile文本行的最大长度无限制,但还是建议分行,方便书写,便于阅读。
一个规则告诉make两件事,一是目标在什么情况下过期(依赖文件比目标文件的修改时间晚或没有目标文件);二是在需要重建目标时,怎么重建目标。
依赖的类型
GUN make的规则可以使用两种不同类型的依赖,一种是常规依赖(常用的);另一种是order-only依赖。
常规依赖表明了两件事,一决定了重建规则目标要执行命令的顺序,二确定一个依赖关系。
order-only依赖时在更新目标(目标文件已存在)时只要根据依赖文件中的一部分来决定是否需要被重建,而不是任意依赖文件被修改都要重建。对依赖分为两类,一类是依赖文件更新后需要对应更新目标文件,另一类是依赖文件的跟新不会导致目标被重建,这类依赖被称为order-only依赖。书写规则,order-only以来使用管道符号|开始,在依赖列表中管道符号|左边的是常规依赖文件,在符号右边的是order-only依赖。
TARGETTS:NORMAL|ORDER-ONLY
规则中常规依赖文件可以是空,允许对一个目标声明多行按正确顺序依次追加的依赖。(以来规则依赖文件中一个文件被同时声明位常规依赖和order-only依赖,那么文件被作为常规依赖处理)
文件名使用通配符
Makefile中表示一个单一的文件名时可以使用通配符,如*?.符号。在Makefile中,通配符的用法和含义与Linux的Bourne shell完全相同。
例:*.c代表当前工作目录下所有以.c结尾的文件。
但在Makefile中,这些通配符并不是可以用在任何地方,Makefile中通配符可以出现两种场景:
- 用在规则的目标、依赖中,make会自动将其展开
- 用在规则的命令中,其展开是Shell执行此命令时完成
其他位置不能直接使用通配符,要通过wildcard()函数实现。
如果使用的文件名中包含了通配符的字符,使用时要对文件名中的通配字符进行转义处理,使用反斜线\。
注