I have a makefile rule in while I am executing a linux tool. I need to check the exit status of the tool command, and if that command fails the make has to be aborted.
I tried checking with $?, $$? \$? etc in the makefile. But they gives me syntax error when makefile runs.
What is the right way to do this ?
Here is the relevant rule in Makefile
mycommand \
if [ $$? -ne 0 ] \
then \
echo "mycommand failed" \
false \
fi
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.
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'; 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 shell commands, separated by semi-colons.
Escaping any new lines you want is annoying and it's easy to forget the semi-colons, but I went with this approach purely because of the caveat mentioned above.
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 > $@