GNU Make工具(二)Phony Targets 和 FORCE

Phony Targets

上一篇提到了makefile基本的rule如下:

Here is what a simple rule looks like:

target:   dependencies ...
          commands
          ...

A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.

Phony Target的引入是为了解决某些特定问题的。Phony Target是一系列命令的标识,可以想成是函数名,标号之类。

  • 避免同名文件的冲突
  • 提升性能

The implicit rule search is skipped for .PHONY targets. This is why declaring a target as .PHONY is good for performance, even if you are not worried about the actual file existing.

例如很常见的make clean命令

clean:
	rm *.o temp
	...

使用上面的写法,假如目录下没有叫clean的文件并且command中也没有生成叫clean的target的命令,那么每次执行make clean命令,clean都会被执行,符合我们的预期。但是如果目录下有一个叫clean的文件存在或者被生成,那么clean之后的指令将得不到执行。因为clean是一个target却没有依赖,所以它始终被make工具认为是最新的,所以不会被更新,其定义的command也就不会被执行。

为了解决上述问题,我们可以通过把target clean作为.PHONY的依赖条件,显式地声明target为phony类型,.PHONY是make内建的特殊target 名。

.PHONY: clean
clean:
        rm *.o temp

make 面对phony对象时会无条件地运行该对象的command(recipe)。 如此一来,make clean定义的命令无论目录下是否存在名叫clean的文件都会被执行。

Phony 和 FORCE

对于没有依赖或者命令菜单的规则,并且该规则的target没有同名文件存在,那么这条规则被执行时,这个target会被make假象成被更新过的,也就是最新的。因此我们可以利用这个使得所有依赖这个target的target都将被更新。

clean: FORCE
        rm $(objects)
FORCE:

在这个例子中,FORCE符合最新的条件,所以make clean命令会被强制执行,无论是不是有同名的clean文件存在。

There is nothing special about the name ‘FORCE’, but that is one name commonly used this way.

As you can see, using ‘FORCE’ this way has the same results as using ‘.PHONY: clean’.

Using ‘.PHONY’ is more explicit and more efficient. 

However, other versions of make do not support ‘.PHONY’; thus ‘FORCE’ appears in many makefiles.

Phony的其他用法

make的递归使用

大型系统构建时通常会包含很多子目录,我们可以在主目录的makefile中执行命令切换到子目录然后调用make命令来完成子目录的构建。

subsystem:
       cd subdir && $(MAKE)

#上述命令等价于
subsystem:
   		$(MAKE) -C subdir

#同样可以声明为phony对象
.PHONY: subsystem subdir
subsystem: subdir
subdir:
   		$(MAKE) -C $@

Phony使用规则

phony target通常不作为其他real target的依赖,否则当real target被更新时phony target对应的命令每次都会被执行;
对于make clean而言,我们是保证clean对象不会作为real target的依赖,所以只有显式调用的时候才会执行;
phony target可以有相应的依赖,这个依赖可以是 phony target,也可以是real target;

.PHONY : all
all : prog1 prog2 prog3

prog1 : prog1.o utils.o
        cc -o prog1 prog1.o utils.o

prog2 : prog2.o
        cc -o prog2 prog2.o

prog3 : prog3.o sort.o utils.o
        cc -o prog3 prog3.o sort.o utils.o

如果phony target的依赖也是phony target,那么被依赖的phony target会作为一个subroutine被执行。

.PHONY: cleanall cleanobj cleandiff

cleanall : cleanobj cleandiff
        rm program

cleanobj :
        rm *.o

cleandiff :
        rm *.diff
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值