How to get exit status of a shell command used in GNU Makefile?
In the makefile-:
mycommand || (echo "mycommand failed $$?"; exit 1)
Each line in the makefile action invokes a new shell - the error must be checked in the action line where the command failed.
If mycommand fails the logic branches to the echo statement then exits.
If all you want is for the make
to be aborted iff the tool exits with a nonzero status, make
will already do that by default.
Example Makefile
:
a: b
@echo making $@
b:
@echo making $@
@false
@echo already failed
.
This is what happens with my make
:
$ make
making b
make: *** [Makefile:6: b] Error 1
Make sure partially or wholly created targets are removed in case you fail. For instance, this
a: b
@gena $+ > $@
b:
@genb > $@
is incorrect: if on the first try, genb
fails, it will probably leave an incorrect b
, which, on the second try, make
will assume is correct. So you need to do something like
a: b
@gena $+ > $@ || { rm $@; exit 1; }
b:
@genb > $@
Here are a couple of other approaches:
shell
& .SHELLSTATUS
some_recipe:
@echo $(shell echo 'doing stuff'; exit 123)
@echo 'command exited with $(.SHELLSTATUS)'
@exit $(.SHELLSTATUS)
Output:
$ make some_recipe
doing stuff
command exited with 123
make: *** [Makefile:4: some_recipe] Error 123
It does have the caveat that the shell
command output isn't streamed, so you just end up with a dump to stdout when it finishes.
$?
some_recipe:
@echo 'doing stuff'; sh -c 'exit 123';\
EXIT_CODE=$$?;\
echo "command exited with $$EXIT_CODE";\
exit $$EXIT_CODE
Or, a bit easier to read:
.ONESHELL:
some_recipe:
@echo 'doing stuff'; sh -c 'exit 123'
@EXIT_CODE=$$?
@echo "command exited with $$EXIT_CODE"
@exit $$EXIT_CODE
Output:
$ make some_recipe
doing stuff
command exited with 123
make: *** [Makefile:2: some_recipe] Error 123
It's essentially one string of commands, executed in the same shell.