如何让GNU make明确测试失败?

64

多年不使用make,我又需要使用它了,现在是gnu版本。我相信我应该能够做到我想要的,但还没有弄清楚如何实现,也没在Google等搜索引擎中找到答案。

我正在尝试创建一个测试目标,它将执行我的程序多次,并将结果保存在日志文件中。一些测试应该会导致程序中止。不幸的是,我的Makefile在第一个测试失败时就会中止并报错。我的Makefile内容大致如下:

# Makefile
# 
test:
        myProg -h > test.log              # Display help
        myProg good_input >> test.log     # should run fine
        myProg bad_input1 >> test.log      # Error 1
        myProg bad_input2 >> test.log      # Error 2

使用上述方法,当 bad_input1 运行后就退出了,永远不会执行 bad_input2。


Make 不太适合这个任务。你可能会遇到一些问题,包括:在管道序列中,最后一个决定退出代码;更复杂的配方行也有同样的问题;如果不跨越很多障碍,使用不同参数重复运行相同的东西可能会让脚本变得烦人。我通常选择编写测试脚本,然后在需要时从 makefile 中使用它。 - Brian Vandenberg
作为替代方案,bash中的set -e可以使得当命令失败时出错,类似于make配方行。 - Brian Vandenberg
3个回答

119

在命令前加上一个-,例如:

-myProg bad_input >> test.log

GNU make 然后会忽略进程退出代码。


1
是的,但这违反了在脚本中运行make test的使用方式,如果失败,则意味着测试未通过!!! - Alexis Wilke
6
虽然这并没有回答实际问题,但它通过阅读标题回答了问题的表面意思,这就是它有那么多赞的原因。 - LukeGT
1
@LukeGT:这个回答比tripleee的回答得到更多投票的部分原因是在tripleee提供更好的答案之前,它已经被选为最佳答案4年了。 - GreenMatt

32

尝试以以下方式运行:

make -i

或者

make --ignore-errors

忽略所有规则中所有错误。

我还建议将其运行为:

make -i 2>&1 | tee results

为了让您看到发生了什么,建议您获取所有错误和输出。

如果在错误后盲目继续执行,可能不是您真正想要做的事情。通常情况下,"make"实用程序需要先前命令的成功完成,以便可以将这些命令的产物作为稍后要执行的命令的先决条件。

顺便说一句,我强烈推荐获取 O'Reilly的该书。第一版对make的基本性质,特别是其向后链接行为有很好的概述。后来的版本仍然很好,但第一版仍然有最清晰的解释是如何实际发生的。事实上,我的个人副本是我给那些来问 "WTF?关于make的问题"的人的第一件东西!(-:


18

如果你想要要求目标失败,正确的解决方案是取反它的退出代码。

# Makefile
# 
test:
    myProg -h > test.log              # Display help
    myProg good_input >> test.log     # should run fine
    ! myProg bad_input1 >> test.log      # Error 1
    ! myProg bad_input2 >> test.log      # Error 2

现在,在这两种情况下成功都是错误的。


2
我晚些时候会指出,如果你的shell不是Bash,则可能无法使用!关键字。 - tripleee

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