If a command fails in make
, such as gcc
, it exits...
gcc
gcc: fatal error: no input files
compilation terminated.
make: *** [main.o] Error 4
However, if I have a pipe the exit status of the last command in the pipe is taken. As an example, gcc | cat
, will not fail because cat
succeeds.
I'm aware the exit codes for the whole pipe are stored in the PIPESTATUS
array and I could get the error code 4 with ${PIPESTATUS[0]}
. How should I structure my makefile to handle a piped command and exit on failure as normal?
As in the comments, another example is gcc | grep something
. Here, I assume the most desired behavior is still for gcc
and only gcc
to cause failure and not grep
if it doesn't find anything.
You should be able to tell make to use bash
instead of sh
and get bash
to have set -o pipefail
set so it exits with the first failure in the pipeline.
In GNU Make
3.81 (and presumably earlier though I don't know for sure) you should be able to do this with SHELL = /bin/bash -o pipefail
.
In GNU Make
3.82 (and newer) you should be able to do this with SHELL = /bin/bash
and .SHELLFLAGS = -o pipefail -c
(though I don't know if adding -c
to the end like that is necessary or if make will add that for you even when you specify .SHELLFLAGS
.
From the bash
man page:
The return status of a pipeline is the exit status of the last command, unless the pipefail option is enabled. If pipefail is enabled, the pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. If the reserved word ! precedes a pipeline, the exit status of that pipeline is the logical negation of the exit status as described above. The shell waits for all commands in the pipeline to terminate before returning a value.