为什么GNU make在出现错误时会退出并返回0?

6

Makefile:

foo.o: foo.cpp
    g++ -o foo.o foo.cpp

foo.cpp:

aslkfdj

输出:

$ g++ -o foo.o foo.cpp; echo $?
foo.cpp:1:1: error: ‘aslkfdj’ does not name a type
 aslkfdj
 ^
1

$ make; echo $?
g++ -o foo.o foo.cpp
foo.cpp:1:1: error: ‘aslkfdj’ does not name a type
 aslkfdj
 ^
Makefile:2: recipe for target 'foo.o' failed
make: *** [foo.o] Error 1
0
$ 

从make中我期望得到退出码2,因为g++返回了非零值,参见。

$ man make|grep exits -A2
       GNU make exits with a status of zero if all makefiles were successfully parsed and no targets that were built failed.  A sta‐
       tus of one will be returned if the -q flag was used and make determines that a target needs to be rebuilt.  A status  of  two
       will be returned if any errors were encountered.

我哪里做错了?

值得一提的是,我在Xubuntu 15.10上也遇到了相同的退出代码:

$ make --version
GNU Make 4.0
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

就像在某些旧的OS X服务器上一样:

$ make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-apple-darwin10.0

使用上述的Makefile和foo.cpp,我得到了退出码2... - skyking
@Mat 我认为Makefile的相关部分已经显示出来了。如果这是唯一的关闭投票原因,我认为这是走捷径的做法。 - skyking
1
你使用的是哪个shell?是否定义了任何别名?\make -f; \echo $?会打印什么内容(请注意前导反斜杠和故意无效的参数)。 - skyking
@skyking 当然,我在我的 .bashrc 文件中设置了一个别名(在两台机器上都设置了!),但我完全忘记了这一点,导致出现了问题;感谢你找到了解决方法 :-) 我想这可能是因为我的设置太特殊了,应该被关闭(不过如果你把评论写成答案,我会接受它作为解决方案)。 - unhammer
2个回答

2
Make明确表示它认识到错误,因此应该返回错误退出代码。但是,在某些情况下,这仍可能导致意外的结果。例如,如果有别名重新定义了makeecho,那么echo $?可能不会报告来自make的错误。要检查这种情况,可以运行alias进行检查,运行type make以查看是否有任何别名/ shell函数可能覆盖名称,或者只需反斜杠出别名(即运行\make -f; \ echo $? - 不带文件名的-f将使make失败,无需任何makefile)。另一个相关的场景是make不是实际的make可执行文件。例如,您可以有一个包装make的shell脚本,但没有转发退出代码。要检测此场景,可以运行which make以查看实际运行的可执行文件(除非别名生效)。

1
在我的情况下,这是由于以下类似的行引起的:
CXX      := -c++

在Makefile中,前导的-会使得Make忽略退出状态码,因此不应该出现在这里。

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