Makefile:
foo.o: foo.cpp
g++ -o foo.o foo.cpp
foo.cpp:
aslkfdj
Output:
$ 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
$
I would expect an exit code of 2 from make, since g++ returns non-zero, cf.
$ 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.
What am I doing wrong?
For the record, I get the same exit code on 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.
as on some old OS X server:
$ 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
Make clearly states that it recognizes the error and should therefore return error exit code.
However there are certain scenarios where this would result in unexpected results anyway. For example if there's alias redefining make
or echo
it could result in echo $?
not reporting the error from make
. To check if this is the case one could of course run alias
to check, type make
to see if any aliases/shell functions might override the name, or simply backslash out alias (ie run \make -f ; \echo $?
- the -f
without filename will make make
fail without any need of a makefile).
A related scenario is when make
is not the actual executable of make. For example you could have a shell script that wraps make
, but doesn't forward the exit code. To detect this scenario you could run which make
to see which executable is really being run (unless alias is in effect)