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.