因为.DEFAULT 不像常规目标。它有非常具体的行为。
来自GNU Make Manual:
.默认
为 .DEFAULT 指定的配方用于未找到任何规则(显式规则或隐式规则)的任何目标。见最后的手段。如果指定了 .DEFAULT 配方,则作为先决条件提到的每个文件,但不是作为规则中的目标,将代表它执行该配方。请参阅隐式规则搜索算法。
所以文档相当清楚地表明.DEFAULT 目标的先决条件不像正常的先决条件那样运行。我现在认为我误读了上面的文档并且不清楚@ 的先决条件是什么987654328@ 规则做/如何处理。于是我就去查了源码。
而且,经过一些源代码挖掘后,事实证明.DEFAULT 在 GNU make 中的实现有点有趣。
如果您查看 main.c 的 line 1859,您可以看到 make 在哪里手动为 .DEFAULT 规则创建(内部)文件条目。
default_file = enter_file (strcache_add (".DEFAULT"));
这是在任何makefile被读取/等之前。 (发生在line 1895)。
如果您从 remake.c 的 Line 502 开始查看,您会看到 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_file 的其他引用,但它们都与当前主题无关。
注意我们还没有看到什么?对.DEFAULT 的任何特殊处理,因为它实际上是从生成文件中读取的。第一个预创建只是为内部缓存提供种子,并允许 make 轻松地通过变量引用 default_file 条目。它不填写命令或先决条件或任何内容。
当 make 在正常操作期间实际从文件中读取 .DEFAULT 规则时,它会找到预先创建的文件条目并填写详细信息。但这意味着(快速测试证实了这一点).DEFAULT 规则的读取和处理方式与其他规则一样。
所以,我们的故事到此结束,您实际上可以运行make .DEFAULT,它会工作(并运行列出的先决条件),因为.DEFAULT 的特殊情况处理仅限于填充任何非-target 目标,仅此而已(显然)。
哦,虽然我在示例中使用了 make 4.1 源代码,但至少自 3.81 以来代码没有改变,虽然我没有检查,但我认为它在 4.1 之后也没有改变。