【Makefile】Makefile文件中的 .PHONY 的作用
目录
即看即用
作用:告诉make,.PHONY:后面跟着的名称不是指文件名,如果makefile中xxxx 写在.PHONY:后面,那么make xxxx 就表示执行xxxx :指定的命令,而不是要(make)生成xxxx
.PHONY:clean install run update
clean:
rm -f *.o temp
install:
……
run:
……
update:
……
执行
make clean 表示运行clean:下面的命令
make install表示运行install:下面的命令
……
详细说明
有两个文件 main1.c,main2.c 我们想要生成2个程序,makefile只能有一个目标,所以可以构造一个没有规则的终极目标all,并以这两个可执行文件作为依赖。
makefile:
all:main1 main2
main1: main1.c
@gcc main1.c -o main1
main2: main2.c
@gcc main2.c -o main2
很多时候我们在执行make时会产生许多过程文件,比如将上面的makefile改为:
makefile:
all:main1 main2
main1: main1.c
@gcc main1.c -o main1
main2: main2.o
@gcc main2.o -o main2
main2.o: main2.c
@gcc -c main2.c
这样就会生成一个我们不需要的过程文件main2.o。
如果希望将生成的过程文件删掉,根据前面再增加一个目标clean:
all:main1 main2 clean
main1: main1.c
@gcc main1.c -o main1
main2: main2.o
@gcc main2.o -o main2
main2.o: main2.c
@gcc -c main2.c
clean:
@rm -f main2.o
但是当我们make之后main2.o仍然存在,怎么回事呢
原来这里的目标clean没有任何依赖,make执行时认为这已经到“根上”了(就是认为磁盘上有clean,就像main2.c),将其忽略(尽管它有规则)。
关键字.PHONY可以解决这问题,告诉make该目标是“假的”(磁盘上其实没有clean),这时make为生成这个目标就会将其规则执行一次。.PHONY修饰的目标就是只有规则没有依赖。
加上一句.PHONY:clean即可:
all:main1 main2 clean
main1: main1.c
@gcc main1.c -o main1
main2: main2.o
@gcc main2.o -o main2
main2.o: main2.c
@gcc -c main2.c
.PHONY:clean
clean:
@rm -f main2.o
makefile 中的PHONY
PHONY 目标
PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字。有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能。
如果编写一个规则,并不产生目标文件,则其命令在每次make 该目标时都执行。
例如:
clean:
rm *.o temp
因为"rm"命令并不产生"clean"文件,则每次执行"make clean"的时候,该命令都会执行。如果目录中出现了"clean"文件,则规则失效了:没有依赖文件,文件"clean"始终是最新的,命令永远不会执行;为避免这个问题,可使用".PHONY"指明该目标。如:
.PHONY : clean
这样执行"make clean"会无视"clean"文件存在与否。
http://blog.chinaunix.net/uid-28458801-id-3452277.html
https://zhuanlan.zhihu.com/p/347929747
例 2
如果.PHONY目标有依赖关系。当一个目录中存在多个可运行程序,将其配置在同一个makefile文件。由于make [command name/ Default command]
默认缺省规则是makefile文件中的第一个规则,一般将这第一个规则称为"all",其依赖文件为多个可运行程序,如下:
all: p1 p2 p3
.PHONY: all
p1: p1.o utils.o
cc -o p1 p1.o utils.o
p2: p2.o utils.o
cc -o p2 p2.o utils.o
p3: p3.o utils.o
cc -o p3 p3.o utils.o
其中p1、p2和p3是三个可执行文件,make把"all"作为主要规则,每次执行时都尝试把"all"更新,因此会检查其依赖文件p1、p2和p3是否需要更新,如果需要,就把它们更新,从而达到我们的目的。通过.PHONY指定目标为all,可以避免目录下同名文件的干扰,即不用检查规则"all"是否有同名文件存在,也不需要查询任何隐含规则,直接假定指定的规则"all"需要被更新。
综上所述,.PHONY
是一个伪目标,可以有效防止在Makefile文件中定义的可执行命令的目标规则和工作目录下的实际文件出现名称冲突,并提高了执行Makefile的性能。
链接:https://www.jianshu.com/p/60b7bc6cf67d