来自文档:
.ONESHELL
如果.ONESHELL被提到作为目标,那么当构建目标时,配方的所有行将被赋予shell的单个调用,而不是单独调用每行(*note Recipe Execution:Execution.).
所以,一个makefile,如:
.ONESHELL :
all ::
echo 'foo
bar'
Run Code Online (Sandbox Code Playgroud)
跑步,我得到:
$ make
echo 'foo
/bin/sh: 1: Syntax error: Unterminated quoted string
makefile:4: recipe for target 'all' failed
make: [all] Error 2 (ignored)
Run Code Online (Sandbox Code Playgroud)
尝试,几乎相同的makefile,但是如果添加-前缀配方,忽略错误,记录:
要忽略配方行中的错误,请在行的文本开头(在初始选项卡之后)写一个" - ".在将行传递给shell以执行之前,将丢弃" - ".
makefile,如:
.ONESHELL :
all ::
-echo 'foo
bar'
Run Code Online (Sandbox Code Playgroud)
跑步,我得到:
$ make
echo 'foo
/bin/sh: 1: Syntax error: Unterminated quoted string
makefile:4: recipe for target 'all' failed
make: [all] Error 2 (ignored)
bar'
/bin/sh: 1: Syntax error: Unterminated quoted string
makefile:4: recipe for target 'all' failed
make: [all] Error 2 (ignored)
Run Code Online (Sandbox Code Playgroud)
为什么?
Jon*_*ler 12
GNU Make 3.81不支持.ONESHELL,但3.82 支持.
$ /usr/gnu/bin/make --version
GNU Make 3.82
$ /usr/bin/gmake --version
GNU Make 3.81
$ cat gnu.mk
.ONESHELL:
all:
echo 'foo' "$$$$"
echo 'bar' "$$$$"
$ /usr/bin/gmake -f gnu.mk
echo 'foo' "$$"
foo 3100
echo 'bar' "$$"
bar 3101
$ /usr/gnu/bin/make -f gnu.mk
echo 'foo' "$$"
echo 'bar' "$$"
foo 3103
bar 3103
$
Run Code Online (Sandbox Code Playgroud)
我推断你从2006年开始使用GNU Make 3.81(或者可能是早期版本,但是从2002年开始使用3.80); 3.82是2010年.当前版本是2014年的4.1.在线文档适用于当前版本.虽然许多材料也适用于旧版本,但并非所有版本都适用.
我还观察到原始makefile的第一行单引号和第二行的单引号似乎也导致麻烦,即使使用GNU Make 3.82.但是,当线条都正常时,它似乎确实有效.这有点令人费解.而且,现在我还安装了GNU Make 4.1(我已经下载了它,但还没有构建它),它也存在以下bust.mk文件的问题.
$ cat bust.mk
.ONESHELL:
all:
echo 'foo
bar' "$$$$"
$ /usr/gnu/bin/make -f bust.mk
echo 'foo
/bin/sh: -c: line 0: unexpected EOF while looking for matching `''
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [all] Error 2
$
Run Code Online (Sandbox Code Playgroud)
我不确定我是否理解GNU Make如何对此感到困惑.可能值得为它提交一个bug.OTOH,我也不确定我是否会担心它.但是你需要在将来的测试中考虑这种奇怪的行为.