这些符合任何规则的区别是什么?

时间:2019-06-05 00:01:03

标签: makefile gnu-make

如果我用以下示例进行测试,则(1)和(2)的行为非常相似,因此我无法区分它们之间的区别。

在使用% ::规则的情况下,它似乎与% :有一些不同的行为,但我无法确定。

% :                        ------ (1)
    @echo % : $@

----------------------

.DEFAULT :                 ------ (2)
    @echo default : $@

----------------------

% ::                       ------ (3)
    @echo % :: $@

在以下示例中,%.foo : %.bar是非终结符 并且具有与先决条件%.bar相匹配的规则 所以我认为提示中的make a.foo命令必须与%.foo : %.bar规则匹配 但最终符合% ::更长茎的规则

%.foo : %.bar
    @echo target : $@

%.bar :
    @echo target : $@

% ::
    @echo % :: $@

------------------------

sh$ make a.foo 
% :: a.foo

1 个答案:

答案 0 :(得分:1)

  

我认为提示符中的make a.foo命令必须与%.foo:%.bar规则匹配,但最终它与甚至更长茎的%::规则匹配

现在尝试:

$ touch a.bar
$ make a.foo
target : a.foo

如果make已经保证1步链,则make拒绝将其更深地递归到隐式规则中(但否则链长无关紧要)。因此,通常您应该使用.DEFAULT:作为默认配方,而%::仅与一些先决条件一起使用(例如,参见内置规则)。

我承认当我发现它时也感到惊讶。但是事实证明,当the manual says

  

如果所有先决条件都存在或应该存在,或者没有先决条件,则此规则适用。

意思是“懒惰并尽可能缩短递归”。