语言: 日本語 | Español | Français | Português | 中文 | English
上一章 | 下一章 | 目录 | 英文原版(gnu.org)

附录B make 生成的错误

这里列出 make 可能生成的较常见的错误,并说明每种错误的含义以及如何修复它们。

make 的错误并不总是致命的,尤其是在命令 (recipe) 行的开头加了 - 前缀,或者在命令行中指定了 -k 选项时。致命的错误会以字符串 *** 作为前缀。

所有错误信息要么以程序名(通常是「make」)为前缀,要么——如果错误是在 makefile 中发现的——以包含问题的那个文件的文件名和行号为前缀。

在下表中,省略了这些共同的前缀。

[foo] Error NN
[foo] signal description

这些其实根本不是 make 自身的错误。它们的意思是,make 作为命令的一部分所启动的某个程序返回了非 0 的错误码(「Error NN」)——make 把它视为失败——或者它以某种异常的方式(伴随某种类型的信号)终止了。请参阅命令中的错误一节。

如果信息中没有附带 ***,则说明子进程虽然失败了,但 makefile 中的那条规则被前置了特殊字符 -,因此 make 忽略了这个错误。

missing separator. Stop.
missing separator (did you mean TAB instead of 8 spaces?). Stop.

这意味着对于刚刚读入的那一行 makefile,make 几乎无法理解其中的任何内容。GNU make 会查找各种分隔符(:=、命令的前缀字符等),以判断它正在解析的是哪种类型的行。这条信息意味着它找不到一个有效的分隔符。

出现这条信息最常见的原因是,你(或者像许多 MS-Windows 编辑器那样多管闲事的编辑器)用空白而不是制表符(Tab)来缩进命令行。在这种情况下,make 会给出上面第二种形式的错误。请记住,命令中的每一行都必须以制表符(Tab)开头(除非你设置了 .RECIPEPREFIX;请参阅其他特殊变量)。8 个空白并不能替代它。请参阅规则的语法

recipe commences before first target. Stop.
missing rule before recipe. Stop.

这意味着 makefile 最开头的内容看起来像是命令的一部分:该行以命令的前缀字符开头,而且看起来不像是一个合法的 make 指令(directive)(例如变量赋值)。命令必须始终与某个目标相关联。

第二种形式是在该行的第一个非空白字符为分号时生成的;make 把它解释为你漏写了规则中「target: prerequisite」的部分。请参阅规则的语法

No rule to make target `xxx'.
No rule to make target `xxx', needed by `yyy'.

这意味着 make 判断它需要构建某个目标,但随后在 makefile 中找不到任何关于如何构建它的指示,无论是显式的还是隐含的(包括默认规则数据库中的)。

如果你想构建那个文件,就需要在 makefile 中添加一条规则,描述该目标该如何构建。导致这个问题的其他可能原因包括 makefile 中的拼写错误(如果那个文件名写错了),或者源代码树损坏(如果那个文件本不应被构建,而本应只是一个前置条件 (prerequisite),却找不到)。

No targets specified and no makefile found. Stop.
No targets. Stop.

前者意味着你没有在命令行中提供任何要构建的目标,而且 make 也找不到任何可读取的 makefile。后者意味着虽然找到了某个 makefile,但其中不包含默认目标 (goal),命令行中也没有给出目标。在这些情况下,GNU make 没有任何可做的事情。请参阅指定 Makefile 的参数一节。

Makefile `xxx' was not found.
Included makefile `xxx' was not found.

命令行中指定的 makefile(第一种形式),或者被 include 的 makefile(第二种形式),没有找到。

warning: overriding recipe for target `xxx'
warning: ignoring old recipe for target `xxx'

在 GNU make 中,(除双冒号规则外)每个目标只能指定一条命令。如果你为一个已经定义了命令的目标再给出另一条命令,就会发出这个警告,并且第二条命令会覆盖第一条。请参阅一个目标对应多条规则

Circular xxx <- yyy dependency dropped.

这意味着 make 在依赖图中检测到了一个循环:在追踪目标 xxx 的前置条件 yyy,以及它的前置条件,如此层层追踪之后,发现其中某一个又依赖于 xxx

Recursive variable `xxx' references itself (eventually). Stop.

这意味着你定义了一个普通的(递归展开)make 变量 xxx,而在展开它时,会辗转引用到它自身(xxx)。这是不允许的;请改用简单展开变量(「:=」或「::=」),或者使用追加运算符(「+=」)。请参阅如何使用变量

Unterminated variable reference. Stop.

这意味着你在变量引用或函数引用中忘记写上对应的闭合括号(圆括号或花括号)。

insufficient arguments to function `xxx'. Stop.

这意味着你没有为该函数提供所需数量的参数。关于参数的说明,请参阅该函数的文档。请参阅用于转换文本的函数

missing target pattern. Stop.
multiple target patterns. Stop.
target pattern contains no `%'. Stop.
mixed implicit and static pattern rules. Stop.

这些错误是针对格式有误的静态模式规则生成的(请参阅静态模式规则的语法)。第一种意味着规则的目标模式部分为空;第二种意味着目标模式部分中有多个模式字符(%);第三种意味着目标模式部分中没有任何模式字符;第四种意味着静态模式规则的三个部分全都包含模式字符(%)——而第一个部分本不应包含模式字符。

如果你看到这些错误,却并不是想创建静态模式规则,请检查你在目标列表和前置条件列表中所用变量的值,确认它们不包含冒号。

warning: -jN forced in submake: disabling jobserver mode.

这个警告和下一个警告,是在子 make 之间可以相互通信的系统上,make 检测到与并行处理相关的错误状态时生成的(请参阅向子 make 传递选项)。当一个 make 进程的递归调用被强制在其参数列表中带有「-jN」(其中 N 大于 1)时,就会生成这个警告。例如,如果你把 MAKE 环境变量设为「make -j2」,就可能发生这种情况。在这种情况下,该子 make 不会与其他 make 进程通信,只是单纯地假装自己拥有两个作业。

warning: jobserver unavailable: using -j1. Add `+' to parent make rule.

为了让 make 进程之间能够通信,父进程会把信息传递给子进程。由于如果子进程实际上并不是 make,这样做可能会引发问题,因此父进程只有在认为子进程是 make 时才会这样做。父进程使用通常的算法来作出这一判断(请参阅MAKE 变量的工作方式)。如果 makefile 的写法使得父进程无法判断子进程是一个 make 进程,那么子进程就只会收到所需信息的一部分。于是子进程会生成这条警告信息,并以顺序(串行)的方式继续进行构建。

warning: ignoring prerequisites on suffix rule definition

根据 POSIX,后缀规则不能包含前置条件。如果一条本可以成为后缀规则的规则带有前置条件,它就会被解释为一条带有奇怪目标名的简单显式规则。在启用 POSIX 兼容模式时(即定义了 .POSIX 目标时),会遵守这一要求。在 4.3 之前的 GNU make 版本中,不会发出警告,并且会创建后缀规则,但所有前置条件都会被忽略,不会成为后缀规则的一部分。从 GNU make 4.3 起,行为相同,但额外会生成这个警告。在未来的版本中,POSIX 兼容的行为将成为唯一的行为:带有前置条件的规则将不能成为后缀规则,这个警告也会被移除。


上一章 | 下一章 | 目录 | 英文原版(gnu.org)