Unix 特殊生成目标的依赖项。默认不触发

Unix 特殊生成目标的依赖项。默认不触发,unix,makefile,gnu-make,Unix,Makefile,Gnu Make,我正在编写一个中型C++文件的MaMeC档,并且使用特殊的默认的/COD>目标,允许在系统特定的子文件中存储系统特定的路径和设置。出于我不理解的原因,依赖项似乎不适用于.DEFAULT,就像它们适用于其他目标一样。例如,考虑Mag文件: .DEFAULT: zed @echo $@ bar: zed @echo bar zed: @echo zed 如果我调用makebar,我会看到 zed bar 但是如果我键入makefoo,我只看到 foo 为什么.DEFAU

我正在编写一个中型C++文件的MaMeC档,并且使用特殊的<代码>默认的/COD>目标,允许在系统特定的子文件中存储系统特定的路径和设置。出于我不理解的原因,依赖项似乎不适用于
.DEFAULT
,就像它们适用于其他目标一样。例如,考虑Mag文件:

.DEFAULT: zed
    @echo $@
bar: zed
    @echo bar
zed:
    @echo zed
如果我调用
makebar
,我会看到

zed
bar
但是如果我键入
makefoo
,我只看到

foo

为什么
.DEFAULT
的行为不同?如何实现未命名目标的依赖关系?

因为
.DEFAULT
与常规目标不同。它有非常特殊的行为

从:

.违约

为.DEFAULT指定的配方用于未找到任何规则(显式规则或隐式规则)的任何目标。见最后手段。如果指定了.DEFAULT配方,则作为先决条件(而不是规则中的目标)提及的每个文件都将代表其执行该配方。请参阅隐式规则搜索算法

因此,文档相当清楚地指出,
.DEFAULT
目标的先决条件与正常先决条件不同。我现在认为我误读了上面的文档,不清楚
.DEFAULT
规则的先决条件是什么/如何处理它们。所以我查了资料来源来找出答案

经过一些源代码分析,GNUMake中
.DEFAULT
的实现有点有趣

如果查看main.c的,您可以看到make在何处为
.DEFAULT
规则手动创建(内部)文件条目

default_file = enter_file (strcache_add (".DEFAULT"));
这是在读取任何makefile/etc之前(发生在上)

若你们看一下remake.c的开头,你们会发现make试图为它还并没有任何规则的文件制定规则

/* If file was specified as a target with no commands,
   come up with some default commands.  */

if (!file->phony && file->cmds == 0 && !file->tried_implicit)
  {
    if (try_implicit_rule (file, depth))
      DBF (DB_IMPLICIT, _("Found an implicit rule for '%s'.\n"));
    else
      DBF (DB_IMPLICIT, _("No implicit rule found for '%s'.\n"));
    file->tried_implicit = 1;
  }
if (file->cmds == 0 && !file->is_target
    && default_file != 0 && default_file->cmds != 0)
  {
    DBF (DB_IMPLICIT, _("Using default recipe for '%s'.\n"));
    file->cmds = default_file->cmds;
  }
这里的第一位与我们无关,但我保留了它,以显示make此时正在执行的操作类型

第二点很重要。如果当前文件没有命令且不是目标文件,并且存在默认文件条目且该条目具有命令,则将默认文件的命令复制为当前文件的命令

源代码中还有一些对
default\u文件的其他引用,但没有一个与当前主题相关

注意我们还没有看到什么?对
.DEFAULT
的任何特殊处理,因为它实际上是从生成文件读取的。第一次预创建只是为内部缓存种子,并允许make通过变量轻松引用
default\u文件
条目。它不填充命令、先决条件或任何内容

当make在正常操作期间实际读取文件中的
.DEFAULT
规则时,它将找到预先创建的文件条目,并用详细信息填充该条目。但这意味着(快速测试证实了这一点)读取和处理
.DEFAULT
规则与其他规则一样

因此,我们的故事到此结束,您实际上可以运行
make.DEFAULT
,它将起作用(并运行列出的先决条件),因为
.DEFAULT
的特殊情况处理仅限于填充任何非目标的命令,而没有其他(显然)


哦,虽然我使用make 4.1源代码作为示例,但代码至少在3.81之后没有更改,虽然我没有检查,但我认为它在4.1之后也没有更改。

谢谢!我仍然不清楚这是如何描述
.DEFAULT
的先决条件处理的。在我阅读时,文档说明
.DEFAULT
将匹配其他不存在规则的规则的先决条件,但没有讨论
.DEFAULT
本身的先决条件。@user1590768我想说的是“If a.DEFAULT recipe”这句话讲的是
.DEFUALT.
目标本身的先决条件,但我不确定这是真的。所以你是对的,它没有清楚地表明这些是如何工作的。这意味着我关于它清晰的评论是不正确的。我们可能需要等待并希望@MadScientist在这里插话(或者让我进行源代码分析)。这种行为显然似乎忽略了任何明确的目标,而是按照文档中的说明行事。@tripleee它显然似乎忽略了明确的先决条件,但我实际上看不到讨论这种行为的文档(至少不在节选的第一节中)。可能还有另一个部分讨论了这一点,或者它可能没有文档记录。我可能稍后会浏览源代码,看看是否可以找到任何内容。感谢您非常完整的回答!我觉得有点奇怪,前提条件没有从
。默认值
,但您已经非常清楚地表明这是预期的行为。在赢得15个声誉后,我一定会提高投票率。