PHONY在Makefile中是什么意思?我已经经历过了,但这太复杂了。

有人能简单地向我解释一下吗?


当前回答

它是不是文件名的生成目标。

其他回答

默认情况下,Makefile目标是“文件目标”-它们用于从其他文件构建文件。Make假设其目标是一个文件,这使得编写Makefile相对容易:

foo: bar
  create_one_from_the_other foo bar

但是,有时您希望Makefile运行不表示文件系统中物理文件的命令。这方面的好例子是共同目标“干净”和“所有”。可能情况并非如此,但您可能在主目录中有一个名为clean的文件。在这种情况下,Make会感到困惑,因为默认情况下,干净的目标将与此文件相关联,Make只会在文件的依赖关系看起来不是最新时运行它。

这些特殊目标称为假目标,您可以明确告诉Make它们与文件无关,例如:

.PHONY: clean
clean:
  rm -rf *.o

现在,即使您有一个名为clean的文件,makeclean也将按预期运行。

就Make而言,虚假目标只是一个总是过时的目标,因此每当您询问Make<phony_target>时,它就会独立于文件系统的状态运行。一些常见的假冒目标是:all、install、clean、distclean、TAGS、info、check。

我经常用它们来告诉默认目标不要开火。

superclean: clean andsomethingelse

blah: superclean

clean:
   @echo clean

%:
   @echo catcher $@

.PHONY: superclean

如果没有PHONY,使超级清洁将发射干净,以及其他一些东西,并捕捉超级清洁;但是有了PHONY,make superclean就不会解雇捕手superclean了。

我们不必担心会告诉对方,明确的目标是PHONY,因为它并不完全是假的。虽然它从未生成干净的文件,但它有命令可以启动,因此make会认为它是最终目标。

然而,超精简目标确实是假的,因此make将尝试将其与为超精简目标提供dep的任何其他内容叠加起来-这包括其他超精简目标和%目标。

请注意,我们根本没有说任何关于或其他什么的话,所以他们很明显会去找捕手。

输出如下所示:

$ make clean
clean

$ make superclean
clean
catcher andsomethingelse

$ make blah 
clean
catcher andsomethingelse
catcher blah

它是不是文件名的生成目标。

特殊目标.PHONY:允许声明虚假目标,这样make就不会将它们作为实际文件名进行检查:即使这样的文件仍然存在,它也会一直工作。

你可以在Makefile中放入几个。PHONY:

.PHONY: all

all : prog1 prog2

...

.PHONY: clean distclean

clean :
    ...
distclean :
    ...

还有另一种方法可以声明虚假目标:只需::无需先决条件:

all :: prog1 prog2

...

clean ::
    ...
distclean ::
    ...

::还有其他特殊的含义,请参见这里,但在没有前提条件的情况下,它总是执行食谱,即使目标已经存在,因此充当了一个虚假的目标。

.PHONY: install

表示单词“install”不代表此文件中的文件名生成文件;表示Makefile与名为“install”的文件无关在同一目录中。