简体   繁体   English

Makefile中的Phony目标

[英]Phony targets in makefile

I was trying to execute the example in this link . 我试图在此链接中执行示例。

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

With or without PHONY (if i comment out the .PHONY line), the outputs are the same. 有无PHONY(如果我注释掉.PHONY行),输出是相同的。 What is the real use of PHONY here? PHONY在这里的真正用途是什么?

The article mentions this 文章提到了这一点

When one directory contains multiple programs, it is most convenient to describe all of the programs in one makefile

Since the target remade by default will be the first one in the makefile, it is common to make this a phony target named 'all' and give it, as prerequisites, all the individual programs

I cant understand what is the real use of PHONY here. 我无法理解PHONY在这里的真正用途是什么。 Can someone point me a scenario in this example in which the program would behave differently without PHONY? 有人可以在这个例子中给我指出一个方案,其中如果没有PHONY,程序的行为会有所不同?

without .PHONY "all" is just a regular make target which depends on prog1, prog2, prog3. 如果没有.PHONY,则“全部”只是一个常规的make目标,它取决于prog1,prog2,prog3。 This means that if a file named "all" would happen to exist in the directory that is newer than prog1, prog2 and prog3, they will not be built (try it!) - but this is obviously not what you had in mind. 这意味着,如果目录“ pro”,“ prog2”和“ prog3”中存在一个名为“ all”的文件,则将不会构建(尝试!)-但这显然不是您要考虑的。

.PHONY tells GNU make the "all" target is phony - you don't REALLY intended for a file called "all" to be created and it should build the dependencies regardless if a file called "all" exists or not. .PHONY告诉GNU使“所有”目标为假-您并不是真的要创建一个名为“所有”的文件,并且无论是否存在一个名为“所有”的文件,它都应该建立依赖关系。

Added later: 稍后添加:

My example with all and prog1 above was not correct although the general idea is true. 尽管上面的总体思路是正确的,但我上面所有和prog1的示例都不正确。 Here is a much simple example 这是一个简单的例子

all: prog

prog: prog.c

clean:
  $(RM) prog prog.o


giladb@xxx:~/tmp$ ls
Makefile  prog.c
giladb@xxx:~/tmp$ make
cc     prog.c   -o prog
giladb@xxx:~/tmp$ make clean
rm -f prog prog.o
giladb@nps06:~/tmp$ make
cc     prog.c   -o prog
giladb@xxx:~/tmp$ touch clean
giladb@xxx:~/tmp$ make clean
make: `clean' is up to date.

At least for GNU Make in combination with this example the behavior regarding the output is the same, no matter if the target "all" is a phony target or not. 至少对于GNU Make,结合此示例,无论目标“全部”是否为假目标,有关输出的行为都是相同的。 Even if there is a file named "all". 即使有一个名为“ all”的文件。

BUT as described in the manual behind your link the internal behavior of GNU Make is different. 但是,如链接后面的手册中所述,GNU Make的内部行为是不同的。 If "all" is not a phony target, GNU Make checks whether a file named "all" exists and is older than its prerequisites. 如果“ all”不是伪造目标,则GNU Make会检查是否存在一个名为“ all”的文件,并且该文件早于其先决条件。 Try "make -d" and you will see the difference. 尝试“ make -d”,您将看到区别。

Another important point is that the recipe of a phony target is always executed. 另一个重要的一点是,始终执行伪造目标的配方。 If you take this example: 如果您使用以下示例:

all: goal
    echo "Done"

.PHONY : clean

goal:
    echo "Hello World!" > $(@)

clean:
    rm -f goal all

... and execute this: ...并执行以下命令:

$ make clean
rm -f goal all
$ make
echo "Hello World!" > goal
echo "Done"
Done
$ make
echo "Done"
Done
$ touch all
$ make
make: 'all' is up to date.

... the recipe will not be executed after creating the file "all". ...创建文件“ all”后将不执行配方。

With "all" being a phony target: 以“全部”为假冒目标:

all: goal
    echo "Done"

.PHONY : all clean

goal:
    echo "Hello World!" > $(@)

clean:
    rm -f goal all

... the recipe of "all" will be executed always independent of the existence of the file "all". ...“ all”的配方将始终独立于文件“ all”的存在而执行。

$ make clean
rm -f goal all
$ make
echo "Hello World!" > goal
echo "Done"
Done
$ make
echo "Done"
Done
$ make
echo "Done"
Done
$ touch all
$ make
echo "Done"
Done
$ make
echo "Done"
Done

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM