20180416 makefile学习笔记-书写规则(伪目标)
下面的例子中的一个“clean”的目标,就是一个“伪目标”:
clean:
rm *.o temp
clean的作用是当我们生成了许多编译文件时,我们应该提供一个清楚他们的“目标”以备完整地重编译而用(以“make clean”来使用该目标)。
因为,我们并不生成“clean”这个文件,“伪目标”并不是一个文件,只是一个标签,由于“伪命令”不是文件,所以make无法生成它的依赖关系和决定它是否执行,我们只是通过显示地指明这个“目标”才能让其生效,当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。
当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目标”。
.PHONY:clean
只要有这个声明,不管是否有“clean”文件,要运行“clean”这个目标,只有“make clean”这样,于是整个过程可以写成:
.PHONY:clean
clean:
rm *.o temp
“伪目标”一般没有依赖文件,但是,我们也可以为伪命令指定所依赖的文件,伪目标同样可以作为“默认目标”,只要将其放在第一个,一个示例就是,如果你的makefile需要一口气生成若干个可执行文件,但你只想简单地敲一下make完事,并且所有的目标文件都写在一个Makefile里,那么你可以使用伪命令这个特性:
all:prog1 prog2 prog3
.PHONY:all
prog2:prog2.o utils.o
cc -o prog2 prog2.o
prog3:prog3.o utils.o
cc -o prog3 prog3.o sort.o utils.o
prog1:prog1.o utils.o
cc -o prog1 prog1.o utils.o
我们知道,Makefile中的第一个目标会被作为其默认目标,我们声明了一个“all”的伪目标,其依赖于其他三个目标。由于伪目标的特性是 总被执行。所以其依赖的那三个目标的规则总是会被决议。也就达到了我们一口气生成多个目标的目的。“.PHONY:all”声明了“all”这个目标为伪目标。
另外,从上面的例子可以看出,目标也可以成为依赖,所以,伪目标同样同样也可以成为依赖,看下面的例子:
.PHONY:cleanall cleanobj cleandiff
cleanall:cleanobj cleandiff
rm program
cleanobj:
rm *.o
cleandiff:
rm *.diff
“make clean”将清除所有要被清除的文件,“cleanobj”和“cleandiff”这两个伪目标有点像“子程序”的意思。我们可以输入“make cleanall”、“make cleanobj”和“make cleandiff”命令来达到清除不同种类文件的目的。