编译错误:缺少分隔符。

348

我运行make时遇到以下错误:

Makefile:168: *** missing separator.  Stop.

这是什么原因造成的?


4
这回答您的问题吗?makefile:4:*** missing separator. Stop - S.S. Anne
有很多关于“错误信息不好”的评论。但是,这条消息“missing separator”只是make版本的通用“语法错误”,或者说“我真的不知道你在这里想干什么”。提供更好的错误信息并不可行,因为make无法弄清楚这一行应该是什么。Make的解析器使用“分隔符”:如果它发现一个=,那么它就是变量赋值;如果它找到一个:,那么它就是一个规则;如果它以TAB(或.RECIPEPREFIX字符)开头,则它是一个配方。如果没有这些东西,那么......它就不知道了。 - MadScientist
14个回答

531

在线手册所示,导致该错误的最常见原因是在make期望制表符时,使用空格缩进了行。

正确

target: 
\tcmd

这里的\t代表制表符(U+0009

错误的示范

target:
....cmd

每个.代表一个空格(U+0020)。


9
您可以使用.RECIPEPREFIX来更改make使用的特殊字符。请参见:https://www.gnu.org/software/make/manual/html_node/Special-Variables.html#Special-Variables - aseq
确认一下,我自己也遇到过这个问题。大多数编辑器/IDE都可以帮助检测到这个问题。例如,在IDEA中,转到“视图”菜单,选择“活动编辑器”,“显示空格”。我无法相信在(查看笔记)2022年,空格与制表符仍然是一个问题。 - cpurdy
我有一个字符串变量,其中包含换行符 - 不是出于选择。通过 execute_process 偷偷进入,使用 OUTPUT_STRIP_TRAILING_WHITESPACE 进行修复,因为输出是单行的。然而错误消息非常糟糕。 - Zoe stands with Ukraine

23

为了好玩,以及以防其他人遇到类似的错误:

我遇到了臭名昭著的“缺少分隔符”错误,因为我调用了一个将函数定义为

($eval $(call function,args))

而不是

$(eval $(call function,args))
即使用$而不是$(

什么? :) 我猜你那里没有 0x20 的“空格”,是吗? - user35443
4
好的,我会尽力进行翻译。需要翻译的内容是:“@user35443 The placement of $”。 - smac89

9

这是您的Makefile中的语法错误。如果没有看到文件本身或相关部分,很难说得更具体。


7
对于我来说,问题是我在一个define ... endef的多行变量定义中嵌入了一些末尾的#...注释。删除注释后问题就解决了。

谢谢。我不知道define指令中的注释是按字面意义处理的。实际上,这种行为在文档没有解释。(为了清晰起见:在指令中嵌入井号本身并不是语法错误。但它只是不被解释为注释的开头,所以这样做显然容易出错。) - ynn

6

在我的情况下,这个错误是由于缺少一个空格造成的。我在我的makefile中有这样一个if块:

if($(METHOD),opt)
CFLAGS=
endif

应该是这样的:
if ($(METHOD),opt)
CFLAGS=
endif

如果后面有空格,可以使用“if”语句。


只是为什么,为什么... - phoxd

5

我的错误出现在一个带有多行扩展的变量声明行上。我在 "\" 后面加了一个尾随空格,导致它成为无效的行延续。

MY_VAR = \
   val1 \ <-- 0x20 there caused the error.
   val2

5
在我的情况下,实际上ifeq和下一行命令之间缺失了一个制表符。一开始那里就没有空格。
ifeq ($(wildcard $DIR_FILE), )
cd $FOLDER; cp -f $DIR_FILE.tpl $DIR_FILE.xs;
endif

应该是:

ifeq ($(wildcard $DIR_FILE), )
<tab>cd $FOLDER; cp -f $DIR_FILE.tpl $DIR_FILE.xs;
endif

请注意,<tab> 是实际的制表符。

3

在我的情况下,错误的原因是我尝试在任何目标之外全局执行命令。

更新:要全局运行命令,必须正确形成命令。例如,命令

ln -sf ../../user/curl/$SRC_NAME ./$SRC_NAME

would become:

$(shell ln -sf ../../user/curl/$(SRC_NAME) ./$(SRC_NAME))

2
在我的情况下,同样的错误是因为缺少冒号:,就像staging.deploy:一样。请注意,这可能是一个简单的语法错误。

1
只是再添加一个可能导致此问题出现的原因:
$(eval VALUE)

不是有效的,会产生“缺少分隔符”错误。

$(eval IDENTIFIER=VALUE)

这是可以接受的错误。当我定义了一个带有define的宏并尝试执行时,我遇到了这种错误。

define SOME_MACRO
... some expression ...
endef

VAR=$(eval $(call SOME_MACRO,arg))

当宏没有被评估为赋值时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接