Makefile 伪目标
1
例:
clean:
rm *.o temp
规则中“rm”不是创建文件“clean”的命令,而是删除当前目录下的所有.o 文件和 temp文件。当工作目录下不存在“clean”这个文件时,我们输入“make clean”,“rm *.otemp”总会被执行。这是我们的初衷。但是如果在当前工作目录下存在文件“clean”,情况就不一样了,同样我们输入“make clean”,由于这个规则没有任何依赖文件,所以目标被认为是最新的而不去执行规则所定义的命令,因此命令“rm”将不会被执行。这并不是我们的初衷。为了解决这个问题,我们需要将目标“clean”声明为伪目标。将一个目标声明为伪目标的方法是将它作为特殊目标.PHONY”的依赖。如下:
.PHONY : clean
这样目标“clean”就被声明为一个伪目标,无论在当前目录下是否存在“clean”这个文件。我们输入“make clean”之后。“rm”命令都会被执行.
“clean”的完整书写格式应该如下:
.PHONY: clean
clean:
rm *.o temp
2
在 Makefile 中,一个伪目标可以有自己的依赖
例:
#sample Makefile
all : prog1 prog2 prog3
.PHONY : all
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
执行 make 时,目标“all”被作为终极目标。为了完成对它的更新,make 会创建(不存在)或者重建(已存在)目标“all”的所有依赖文件(prog1、prog2 和 prog3)。当需要单独更新某一个程序时,我们可以通过 make 的命令行选项来明确指定需要重建的程序。(例如:“make prog1”)
当一个伪目标作为另外一个伪目标依赖时,make 将其作为另外一个伪目标的子例程来处理(可以这样理解:其作为另外一个伪目标的必须执行的部分,就行 C 语言中的函数调用一样)
例:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff
“cleanobj”和“cleandiff”这两个伪目标有点像“子程序”的意思(执行目标“clearall时会触发它们所定义的命令被执行”)。我们可以输入“make cleanall”和“makecleanobj”和“make cleandiff”命令来达到清除不同种类文件的目的。
备注:
通常在清除文件的伪目标所定义的命令中“rm”使用选项“–f”(--force)来防止在缺少删除文件时出错并退出,使“make clean”过程失败。也可以在“rm”之前加上“-”来防止“rm”错误退出,这种方式时 make 会提示错误信息但不会退出。为了不看到这些讨厌的信息,需要使用上述的第一种方式。另外 make 存在一个内嵌隐含变量“RM”,它被定义为:“RM = rm –f”。因此在书写“clean”规则的命令行时可以使用变量“$(RM)”来代替“rm”,这样可以免出现一些不必要的麻烦!这是我们推荐的用法。