51

我知道@前缀会抑制 Makefiles 中 shell 命令的输出,并且-前缀会忽略 shell 命令中的错误。有没有办法将两者结合起来,即抑制输出并忽略错误的前缀?我不认为@--@工作。

4

2 回答 2

68

实际上,@-两者-@都可以工作,但会打印make: [target] Error 1 (ignored)警告。

相反,您可以使用

@command || true

或者,因为:truein shell 的简写,

@command ||:

这通常是一件更好的事情,因为它避免了 Make 的令人困惑的警告,即在不可见的命令中忽略了错误。

考虑两种最常见的情况,您可能希望忽略命令的返回值:

  1. 部分构建已损坏,您仍想继续,在这种情况下,您需要学习一些东西。构建已损坏,需要修复,而不是以无法维护的方式进行捆绑。
  2. 一个命令返回一个非零的退出代码,即使它完全按照您的意愿执行,在这种情况下,您并不真的希望 Make 发出警告。

对于第二种情况,请考虑在命令生成的日志文件中对警告进行 grepping 的示例。grep如果找不到匹配项,将返回错误,这不是您想要的:

.PHONY: all one two three

all: at-warning at-success or-success or-warning

at-%: %.log
    @echo Making $@
    @-grep ^Warning $<

or-%: %.log
    @echo Making $@
    @grep ^Warning $< ||:

success.log:
    echo 'Success!' > $@

warning.log:
    echo 'Warning: foo' > $@

clean::
    rm -f {success,warning.log}

产生:

echo 'Warning: foo' > warning.log
Making at-warning
Warning: foo
Making at-success
make: [at-success] Error 1 (ignored)
Making or-success
Making or-warning
Warning: foo

使用@-成功时会产生无意义的忽略错误警告,同时|| true处理警告和没有警告而没有抱怨。

理论上 using|| true比 using 慢@-,但这种开销不太可能成为精心设计和维护的构建系统的瓶颈。绝大多数时间应该花在构建,或者在没有构建的时候检查时间戳,而不是运行成千上万的快速命令,这些命令的返回值都被忽略,这对于产生可衡量的性能影响是必要的。

于 2012-08-08T19:49:53.907 回答
9

GNU make 确实允许您将两者结合@起来-

all:
        @-exit 1

使用 gmake 3.81 运行它会产生以下输出:

gmake:[全部]错误1(忽略)

如您所见,该命令未回显,并且按预期忽略错误。

于 2012-08-08T20:33:06.807 回答