Makefile的特殊目标

时间:2022-01-14 12:51:32

Makefile的特殊目标

在Makefile中,有一些名字,当它们作为规则的目标时,具有特殊含义。它们是一些特殊的目标,GNU make所支持的特殊的目标有:

.PHONY

目标“.PHONY”的所有的依赖被作为伪目标。伪目标时这样一个目标:当使用make命令行指定此目标时,这个目标所在规则定义的命令、无论目标文件是否存在都会被无条件执行。

.SUFFIXES:

特殊目标“SUFFIXES”的所有依赖指出了一系列在后缀规则中需要检查的后缀名(就是当前make需要处理的后缀)。

.DEFAULT

Makefile中,目标“.DEFAULT”所在规则定义的命令,被用在重建那些没有具体规则的目标(明确规则和隐含规则)。就是说一个文件作为某个规 则的依赖,但却不是另外一个规则的目标时。Make程序无法找到重建此文件的规则,此种情况时就执行“.DEFAULT”所指定的命令。

.PRECIOUS

目标“.PRECIOUS”的所有依赖文件在make过程中会被特殊处理:当命令在执行过程中被中断时,make不会删除它们。而且如果目标的依赖文件是 中间过程文件,同样这些文件不会被删除。这一点目标“.PRECIOUS”和目标“.SECONDAY”实现的功能相同。

另外,目标“.PRECIOUS”的依赖文件也可以是一个模式,例如“%.o”。这样可以保留有规则创建的中间过程文件。

.INTERMEDIATE

目标“.INTERMEDIATE”的依赖文件在make时被作为中间过程文件对待。没有任何依赖文件的目标“.INTERMEDIATE”没有意义。

.SECONDARY

目标“.SECONDARY”的依赖文件被作为中间过程文件对待。但这些文件不会被自动删除。

没有任何依赖文件的目标“.SECONDARY”的含义是:将所有的文件作为中间过程文件(不会自动删除任何文件)。

.DELETE_ON_ERROR

如果在Makefile中存在特殊目标“.DELETE_ON_ERROR”,make在执行过程中,如果规则的命令执行错误,将删除已经被修改的目标文件。

.IGNORE

如果给目标“.IGNORE”指定依赖文件,则忽略创建这个文件所执行命令的错误。给此目标指定命令是没有意义的。当此目标没有依赖文件时,将忽略所有命令执行的错误。

.LOW_RESOLUTION_TIME

目标“.LOW_RESOLUTION_TIME”的依赖文件被make认为是低分辨率时间戳文件。给目标“.LOW_RESOLUTION_TIME”指定命令是没有意义的。

通常文件的时间辍都是高分辨率的,make在处理依赖关系时、对规则目标-依赖文件的高分辨率的时间戳进行比较,判断目标是否过期。但是在系统中并没有提 供一个修改文件高分辨率时间辍的机制(方式),因此类似“cp-p”这样的命令在根据源文件创建目的文件时,所产生的目的文件的高分辨率时间辍的细粒度部分被丢弃(来源于源文件)。这样可能会造成目的文件的时间戳和 源文件的相等甚至不及源文件新。处理此类命令创建的文件时,需要将命令创建的文件作为目标“.LOW_RESOLUTION_TIME”的依赖,声明这个 文件是一个低分辨率时间辍的文件。例如:

.LOW_RESOLUTION_TIME: dst

dst: src

cp -p src dst

首先规则的命令“cp –p src dst”,所创建的文件“dst”在时间戳上稍稍比“src”晚(因为命令不能更新文件“dst”的细粒度时间)。因此make在判断文件依赖关系时会出 现误判,将文件作为目标“.LOW_RESOLUTION_TIME”的依赖后,只要规则中目标和依赖文件的时间戳中的初始时间相等,就认为目标已经过 期。这个特殊的目标主要作用是,弥补系统在没有提供修改文件高分辨率时间戳机制的情况下,某些命令在make中的一些缺陷。

对于静态库文件(文档文件)成员的更新也存在这个问题。make在创建或者更新静态库时,会自动将静态库的所有成员作为目标“.LOW_RESOLUTION_TIME”的依赖。

.SILENT

出现在目标“.SILENT”的依赖列表中的文件,make在创建这些文件时,不打印出重建此文件所执行的命令。同样,给目标“.SILENT”指定命令行是没有意义的。

没有任何依赖文件的目标“.SILENT”告诉make在执行过程中不打印任何执行的命令。现行版本make支持目标“.SILENT”的这种功能和用法 是为了和旧版本的兼容。在当前版本中如果需要禁命令执行过程的打印,可以使用make的命令行参数“-s”或者“--silent”。

.EXPORT_ALL_VARIABLES

此目标应该作为一个简单的没有依赖的目标,它的功能含义是将之后所有的变量传递给子make进程。

.NOTPARALLEL

Makefile中,如果出现目标“.NOPARALLEL”,则所有命令按照串行方式执行,即使存在make的命令行参数“-j”。但在递归调用的字make进程中,命令可以并行执行。此目标不应该有依赖文件,所有出现的依赖文件将被忽略。

所有定义的隐含规则后缀作为目标出现时,都被视为一个特殊目标,两个后缀串联起来也是如此,例如“.c.o”。这样的目标被称为后缀规则的目标,这种定义方式是已经过时的定义隐含规则的方法(目前,这种方式还被用在很多地方)。原则上,如果将其分为两个部分、并将它们加到后缀列表中,任何目标都可采用这种方式来表示。实际中,后缀通常以“.”开始,因此,以上的这些特别目标同样是以“.”开始。