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

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


当前回答

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

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

.PHONY: all

all : prog1 prog2

...

.PHONY: clean distclean

clean :
    ...
distclean :
    ...

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

all :: prog1 prog2

...

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

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

其他回答

最好的解释是GNU make手册本身:4.6 Phony Targets部分。

.PHONY是make的特殊内置目标名称之一。还有其他你可能感兴趣的目标,所以值得浏览一下这些参考文献。

当该考虑.PHONY目标时,make将运行其配方无条件地,无论具有该名称的文件是否存在或它的最后修改时间是什么。

你也可能对make的标准目标感兴趣,比如all和clean。

注意:make工具读取makefile并检查规则中“:”符号两侧文件的修改时间戳。

实例

在目录“test”中存在以下文件:

prerit@vvdn105:~/test$ ls
hello  hello.c  makefile

在makefile中,规则定义如下:

hello:hello.c
    cc hello.c -o hello

现在假设文件“hello”是一个包含一些数据的文本文件,它是在“hello.c”文件之后创建的。因此,“hello”的修改(或创建)时间戳将比“hello.c”的更新。因此,当我们从命令行调用“make hello”时,它将打印为:

make: `hello' is up to date.

现在访问“hello.c”文件并在其中添加一些空格,这不会影响代码语法或逻辑,然后保存并退出。现在hello.c的修改时间戳比“hello”的修改时间戳记新。现在,如果您调用“make hello”,它将执行以下命令:

cc hello.c -o hello

文件“hello”(文本文件)将被一个新的二进制文件“hell”(上述编译命令的结果)覆盖。

如果我们在makefile中使用.PHONY,如下所示:

.PHONY:hello

hello:hello.c
    cc hello.c -o hello

然后调用“makehello”,它将忽略pwd“test”中存在的任何文件,并每次执行该命令。

现在假设“hello”目标没有声明依赖项:

hello:
    cc hello.c -o hello

如果pwd“test”中已经存在“hello”文件,那么“make hello”将始终显示为:

make: `hello' is up to date.

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

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

.PHONY: all

all : prog1 prog2

...

.PHONY: clean distclean

clean :
    ...
distclean :
    ...

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

all :: prog1 prog2

...

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

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

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

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: install

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