为什么GNU在出错时退出0?

时间:2016-01-08 10:15:51

标签: makefile exit-code

生成文件:

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

2 个答案:

答案 0 :(得分:1)

明确说明它识别错误,因此应返回错误退出代码。

但是,在某些情况下,无论如何都会导致意外结果。例如,如果别名重新定义echoecho $?,则可能导致make未报告来自alias的错误。要检查是否是这种情况,当然可以运行type make来检查,\make -f ; \echo $?以查看是否有任何别名/ shell函数可能覆盖名称,或者只是反斜杠别名(即运行-f - 没有文件名的make会使make失败而不需要makefile)。

相关场景是make不是make的实际可执行文件。例如,您可以拥有一个包装which make的shell脚本,但不会转发退出代码。要检测此方案,您可以运行 Solution2 soln = (Solution2)visualStudioInstance.Solution; csTemplatePath = soln.GetProjectTemplate("Windows Root\\Windows\\1033\\ClassLibrary\\csClassLibrary.vstemplate", "CSharp"); soln.AddFromTemplate(csTemplatePath, csPrjPath, "MyProject", false); 以查看实际运行的可执行文件(除非别名生效)

答案 1 :(得分:1)

在我的情况下,发生这种情况的原因是以下行:

CXX      := -c++

前导-使Make忽略退出状态,因此不应存在。