为什么.PHONY:目标而不是目标:.PHONY?

tiw*_*iwo 7 makefile gnu-make target

我仍然不明白为什么Makefiles中的"假冒"规则将".PHONY"作为目标.作为先决条件,这将更合乎逻辑.

我需要详细说明吗?如果A依赖B并且B是假的,那么A也是虚假的.因此,依赖图.PHONYB→交通A相比,是令人惊讶的WAAY .PHONY→交通B→交通A.(另一个论点是make必须处理.PHONY目标的实现非常特殊.)

虽然这种批评似乎相当理论化(毫无意义) - "因为制作是如此古老,它的语法就在这里".但我不建议任何语法更改,有一个替代方案:

使用GNU Make(至少),以下Makefile声明虚假target_A:

target_A: _PHONY
        touch target_A

_PHONY:
        #noop
Run Code Online (Sandbox Code Playgroud)

问题1:这是如此简单和干净,当然我不是它的第一个发明者.事实上,鉴于这种替代方案,为什么make需要特殊的语法?

在我看来,这也很好地解决了关于虚假目标中的通配符的问题,甚至可以说明.当初学者怀疑时,PHONY的含义.

问题2:您能否想到这种方法较差的任何情况?(调用make .PHONY有用吗?)

(我应该提一下,当我调用其他make的时,GNU Make是我有一些经验的唯一实现 - 阅读和编写Makefile.)

bta*_*bta 4

using 的一个大问题target_A: .PHONY是它使得使用 make 的许多内置变量变得更加困难。以这个常见的菜谱为例:

%.a: $(OBJ_FILES)
    $(LD) $(LFLAGS) -o $@ $^
Run Code Online (Sandbox Code Playgroud)

$^变量引入了列为先决条件的所有内容。如果.PHONY也在那里列出,那么它将被传递到命令行上的链接器,这可能不会导致任何好的结果。使用元目标作为先决条件会使这些内置变量的用处大大降低,因为它们每次使用时都.PHONY需要大量额外的处理。为了考虑依赖树,$(filter-out .PHONY,$^)反转关系并创建目标有点尴尬,但它清理了 makefile 的其余部分。.PHONY