Reputation: 8958
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
Upvotes: 66
Views: 83200
Reputation: 1073
To those who can't still fix it, the original snippet in the question missed a semicolon after mycommand
. So, the working example is:
mycommand; \ # <<== here's the missing semicolon
if [ $$? -ne 0 ]; \
then \
echo "mycommand failed"; \
false; \
fi
Upvotes: 1
Reputation: 7884
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.
Upvotes: 32
Reputation: 8611
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 > $@
Upvotes: 4
Reputation: 17288
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.
Upvotes: 89