GNU make手册翻译系列(5)

4.6 没有配方或依赖的规则

        如果一条规则没有配方或依赖,并且规则的目标不是一个存在的文件名,则执行此规则时,make就认为它的目标已经被更新过.这样的目标在作为一个规则的依赖时,因为依赖总被认为被更新过,因此作为依赖所在的规则中定义的命令总会被执行.看一个例子:

clean: FORCE

        rm$(objects)

FORCE:
这个例子中,目标"FORCE"就符合了上边的条件,所以当make执行目标"clean"所在规则时:,它的配方总会被执行.这种没有配方或依赖的特殊目标并没有一个固定的名字,只是习惯上通常命名为"FORCE".

        正如你所看到的,使用"FORCE"目标的效果和将"clean"声明为伪目标的效果相同.

        使用".PHONY"方式显然更加直观高效,只不过因为其他版本的make程序不一定支持".PHONY"方式,所以许多Makefile中还是使用了"FORCE"目标.


4.7 记录事件用的空目标文件

        空目标是伪目标的一种变体,它也是一个用来标识一系列配方的集合,并且通常是在make命令行指定该目标时执行.和伪目标不同的是,这个目标可以是一个存在的文件,但文件的具体内容我们并不关心,通常就是一个空文件.

       空目标文件只是用来记录上一次执行此规则命令的时间戳.实现的方式是在配方中执行touch命令来更新目标文件.

        空目标文件需要有对应的依赖(否则就没有存在的意义).每次make空目标时,只要有任何一个依赖对象比空目标新,所在规则的配方就会被执行;换句话说,就是如果有一个空目标的依赖在最近一次make该空目标后发生变化,那么空目标的重建配方就会被执行.下面就是一个例子:

print: foo.c bar.c

        lpr-p $?

        touchprint
按照上面的规则,当目标"print"的任何一个依赖文件被修改之后,输入"makeprint"就会执行配方中的lpr命令.其中的自动变量"$?"表示只打印变化了的依赖文件.


4.8 特殊的内建目标

Makefile,有一些名字,当它们作为规则的目标时,具有特殊含义.

.PHONY

                目标".PHONY"的依赖被认为是伪目标.如果一个目标是伪目标,make该目标时, 论该目标的同名文件是否存在,该目标所 在规则的配方会被无条件执行.

.SUFFIXES

                目标".SUFFIXES"的依赖是一张在后缀规则中需要检查的后缀名列表.

.DEFAULT

                目标".DEFAULT"的配方被用于重建那些没有找到相应规则(明确规则或隐含规则) 目标.就是说,目标".DEFAULT"指定了配方的前提下,如果存在一个目标,在某个规 则中作为依赖却又不存在构建它的规则,则该目标会套用".DEFAULT"的配方并执行.

.PRECIOUS

             目标".PRECIOUS"的依赖文件在make过程中会被特殊处理:这些依赖文件在作为目 标被构建期间,如果make程序被kill或中断,已经生成的这些依赖文件不会被删除. 使这些依赖文件是中间文件也不会被删除,在这一点上目标".PRECIOUS"和目标 ".SECONDAY"实现的功能相同.另外,你也可以列出包含隐含规则(比如"%.o")的目标 模式作为".PRECIOUS"的依赖文件,这样那些跟该模式匹配的中间文件都会被保留.

.INTERMEDIATE

                 目标".INTERMEDIATE"的依赖文件被作为中间文件对待.没有任何依赖文件的目 ".INTERMEDIATE"是没有意义的.

.SECONDARY

             目标".SECONDARY"的依赖文件被作为中间文件对待,但这些文件不会被自动删除. 有任何依赖文件的目标".SECONDARY"表示将所有目标作为中间过程文件(意味着不 会删除任何目标文件).

.SECONDEXPANSION

         如果在Makefile中的任何位置设置了".SECONDEXPANSION"目标,make程序在读 入了所有的Makefile,会对".SECONDEXPANSION"的依赖对象进行二次展开.

.DELETE_ON_ERROR

                如果在Makefile中的任何位置设置了".DELETE_ON_ERROR"目标,make在执行 过程中,如果规则的命令执行错误,将删除已经被修改的目标文件.

.IGNORE

            如果给目标".IGNORE"指定依赖文件,则忽略创建这个文件所执行命令的错误.目标 ".IGNORE"的配方会被忽略.当目标".IGNORE"不设置依赖文件时,将忽略所有命令执 行的错误.使用".IGNORE"只是为了实现旧版本兼容.".IGNORE"会影响Makefile中的 每个配方,所以它不是很有用;在后续章节中有更多的选择方式去忽略指定配方的错 .

.LOW_RESOLUTION_TIME

              如果给目标".LOW_RESOLUTION_TIME"指定了依赖文件,make程序会将这些依 赖文件当作低分辨率时间戳文件.目标".LOW_RESOLUTION_TIME"的配方会被忽略.

                在判断文件是否是最新的问题上,很多现代文件系统使用高分辨率文件时间戳来减少 出错几率.不幸的是,一部分系统并未提供设置高分辨率文件时间戳的方法,这导致 "cp-p"这些命令在执行时必须丢弃文件时间戳中秒级之后的部分.如果一个文件是 由这些命令创建的,该文件就需要设置为目标".LOW_RESOLUTION_TIME"的依赖, 这样make程序才不会错误地认为该文件已经过期了.例如:

.LOW_RESOLUTION_TIME: dst

dst: src

        cp-p src dst
由于"cp-p"命令会丢弃src文件时间戳中秒级之后的部分,所以dst文件总是会稍微旧 src文件.dst文件作为目标".LOW_RESOLUTION_TIME"的依赖后,只要dst文件 秒级之前部分的时间戳跟src文件秒级之前部分的时间戳相等,make程序就认为dst 文件是最新的.

            由于档案文件格式上存在限制,档案文件中成员文件的时间戳总是低分辨率的.但你 需要将成员文件添加到".LOW_RESOLUTION_TIME"的依赖列表中,因为make程序 会自动完成这些动作.

.SILENT

              如果你将一个目标添加为".SILENT"的依赖,则当make程序重建该目标时,将不会在执 行配方之前打印这些配方.目标".SILENT"的配方会被忽略.

                当目标".SILENT"不设置依赖时,表示make程序将不会在执行任何配方前打印这些配 .使用".SILENT"只是为了实现旧版本兼容,有更多的选择方式可以使指定配方保持 静默.如果你想要在某次make过程中让所有配方保持静默,可以使用命令行选项"-s""--silent".

.EXPORT_ALL_VARIABLES

                目标".EXPORT_ALL_VARIABLES"作为一个简单的不带依赖的目标时,其目的就是告 make程序将所有变量导出给子make进程.

.NOTPARALLEL

                如果设置了目标".NOTPARALLEL",即使命令行传入了"-j"选项,make程序都将会串行 执行.但在递归调用的子make进程中,除非它的Makefile也包含了这个特殊目标,否则 make进程将会并行执行(make命令行设置了"-j"选项前提下).

.ONESHELL

                如果设置了目标".ONESHELL",则每个规则中即便包含了多行独立配方,这些配方也 将在一个shell进程中被执行.

.POSIX

                如果设置了目标".POSIX",make程序会运行在符合POSIX标准的模式.这并不意味 着只有符合POSIX标准的Makefile会被接受,而是所有GNUmake的高级特性仍就是 可用的.更确切地说,这个特殊目标的作用是使make程序在遇到make缺省行为和 POSIX标准存在差别的内容时选择POSIX标准.

                特别是,如果设置了目标".POSIX",shell在执行配方时就像是设置了"-e"标志一样: 方中一旦出现某条命令执行失败就会立刻退出.


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值