[Make] Phony Target

1 篇文章 0 订阅

一个phony target 并不是一个文件的名称。使用phony target的2个原因:

  • 避免与同名文件冲突
  • 提高性能

如果你写了一个没有创建实际目标文件的规则,一旦该目标文件被标记调用,那么它所对应的命令会被执行。

clean:
	rm *.o temp

因为rm 命令不会创建名为clean的文件,如果本地也没有一个同名的clean文件,那么你每次调用make clean 时,都会调用rm命令。

在上述例子中,如果本地有一个clean文件被创建,那么clean规则不会正常执行。因为它没有必要条件,clean总是被认为是最新的,它的命令不会被调用。为了避免这个问题,你可以显式的声明该目标是一个phony,通过标记该目标是特殊目标.PHONY的必要条件。

.PHONY : clean
clean:
	rm *.o temp

一旦标记clean为phony,那么make clean总是会调用rm,不论本地是否有一个clean文件。

Phony target 在递归调用make中也是很有用的技术。这种情况下,makefile经常包含一个需要构建的子目录的列表。处理这个的简单方法是,定义一个规则,在该规则中循环调用子目录的make。例如

SUBDIRS = foo bar baz

subdirs:
	for dir in $(SUBDIRS);do \
		$(MAKE) -C $$dir; \
	done

然而这个会有一些问题。

  • 如果子目录中的make调用发生了错误,则该规则会忽略,继续执行剩下的子目录。这个问题可以通过增加shell返回值来检测。
  • 由于是一个规则,无法使用的make并行技术。

但是 .PHONY 可以解决这些问题

SUBDIRS =foo bar baz
.PHONY : subdirs $(SUBDIRS)
subdirs : $(SUBDIRS)
$(SUBDIRS):
	$(MAKE) -C $@
foo: baz

在上例中,我们声明 直到baz构建完成后才能构建foo.在并行构建时,这种相对关系声明是很重要的。

在.PHONY目标中,隐式规则会忽略,这就是为什么可以提高性能的原因了。

一个PHONY 目标不应该是一个实际目标的必要条件。因为每次执行make时,.phony target都会被执行,则对应的实际目标也被构建(浪费时间)。只要.phony 不是实际目标的必要条件,则调用.phony target时必须在make中显式指定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值