makefile - 为什么我将 “Makefile:1: *** missing separator. Stop.”和 “set -e”一起获得?

标签 makefile syntax-error gnu-make

我只有一行Makefile引发以下错误:Makefile:1: *** missing separator. Stop。我知道有些dozens of duplicate questions带有相同的错误消息,但大多数建议使用不使用制表符或神秘的特殊字符来解决问题。

$ cat -e -v -t Makefile 
set -e$

$ make
Makefile:1: *** missing separator.  Stop.

据我所知,没有神秘的特殊字符。也许有些字符cat -e -v -t不显示?

以下工作正常,因此我猜测make安装不是问题:
$ cat -v -e -t Makefile 
foo:$
^Iecho "Foo"$

$ make
echo "Foo"
Foo

一些相关的版本和 shell 信息。
$ make --version
GNU Make 3.81

$ echo $0
-bash

编辑:通过@AProgrammer查看评论

请注意,无论set -e下面有什么内容,它都会引发相同的错误消息。
$ cat -e -v -t Makefile 
set -e$
$
foo:$
^Iecho "foo"$

$ make
Makefile:1: *** missing separator.  Stop.

编辑2:

注意添加#!/bin/bash会引发相同的错误消息。
$ cat -e -v -t Makefile 
#!/bin/bash$
set -e$
$
foo:$
^Iecho "foo"$

$ make
Makefile:2: *** missing separator.  Stop.

编辑3:

直接在我的shell上运行set -e似乎可以正常工作(它按预期退出失败的make调用)。
$ set -e
$ make
Makefile:2: *** missing separator.  Stop.
Saving session...completed.
Deleting expired sessions...11 completed.

[Process completed]

最佳答案

make完全没有理由能够解释规则外的任意shell命令。

如果要在出现错误时立即退出规则,则有几种方法可以或多或少地进行移植。

首先,规则的每一行都是由 shell 程序的单独实例执行的。这意味着,如果您不手动合并它们(使用\;),那么如果每行只有一个命令,则将获得所需的行为。

然后,您可以将set -e用作可能需要它的一些规则的一部分。例如;

foo:
        set -e; for i in a b c d; mkdir $$i; done

使用GNU Make,您可以更改用于调用Shell的标志,另外传递-e:
.SHELLFLAGS=-ec

使用POSIX Make,可以更改 shell 。我不知道是否支持传递标志,但是对于GNU Make来说似乎是这样:
SHELL=/bin/sh -e

但是您始终可以通过包装器来根据需要设置标志:
SHELL=/path/to/mywrapper

mywrapper
#!/bin/sh
exec /bin/sh -e "$@"

关于makefile - 为什么我将 “Makefile:1: *** missing separator. Stop.”和 “set -e”一起获得?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59376937/

相关文章:

c - 随机函数的错误

makefile - 在 Makefile 中首次使用时分配一次变量

c++ - Makefile 不会展开依赖

c - kbuild 外部模块问题

使用 open() 时出现 Python 语法错误

syntax-error - 文本 “genvar”附近的test_bench_lb2.v(14)处的Verilog HDL语法错误;期待 “end”

makefile - 设计 makefile 来编译不同配置的程序

makefile - 使用 make 对每个源文件执行操作

c - 初学者编写makefile;检查我的 Makefile

c - 尝试编译 HDF4 程序时包含文件出错