GNU Make工具(二)Phony Targets
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 (see Implicit Rules) 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中也没有生成target的命令,那么每次执行make clean
命令,clean都会被执行,符合我们的预期。但是如果目录下有一个叫clean的文件存在或者被生成,那么clean之后的指令将得不到执行。因为clean是一个target却没有依赖,所以它始终被make工具认为是最新的,所以不会被更新,其定义的command也就不会被执行。
为了解决上述问题,我们可以显式地声明target为phony类型,.PHONY
是make内建的特殊目标名。
.PHONY: clean
clean:
rm *.o temp
如此一来,make clean
定义的命令无论目录下是否存在名叫clean的文件都会被执行。
Phony的其他用法
make的递归使用
大型系统构建时通常会包含很多子目录,我们可以在主目录的makefile中执行命令切换到子目录然后调用make命令来完成子目录的构建。
subsystem:
cd subdir && $(MAKE)
#上述命令等价于
subsystem:
$(MAKE) -C subdir
#同样可以声明为phony对象
.PHONY: subsystem subdir
subsystem: subdir
subdir:
$(MAKE) -C [email protected]
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
上一篇: MySQL入门:用户设置 添加新用户