bli00
bli00

Reputation: 2787

Makefile result message during parallel build

Given a Makefile that's often times run with the -j flag for parallel builds. I want it to terminate with a result message. I would like this message to say if the build failed, and if it failed, what the error was. It doesn't have to say anything if the build succeeded (although it could) but it must warn the user when a target failed to build and why.

This behavior is already there during sequential builds, but not during parallel builds. Parallel builds interweaves the output and an error message is often overlooked because output from other targets might push the failed target's error off screen. A careless developer might see no errors on his/her screen and assume the build succeeded.

It's quite an intuitive feature and I've searched for an answer, but it doesn't seem like there's any straight forward solutions. Any ideas?

Upvotes: 1

Views: 1098

Answers (2)

HardcoreHenry
HardcoreHenry

Reputation: 6387

-- EDIT --

Updating to use tee, to output on stdout and into file:


Make returns non-zero if one of its recipe's fails so you could do something like this from the command line (assuming bash shell):

make 2>&1 | tee build.log
[ ${PIPESTATUS}[0] -eq 0 ] || ( echo "MAKE FAILED!"; grep --color build.log "Error:" )

The ${PIPESTATUS}[0] gives you the exit code of the first command (make 2>&1) as opposed to the exit status of the entire command (which would the exit status of tee if the make failed). It is bash specific, so it won't work in zsh for example.

Alternatively you could add the same logic as the top level target of a recursive make.

ifndef IN_RECURSION
export IN_RECURSION:=1

$(info At top level -- defining default target)

_default: 
    @echo "doing recursive call of make"
    @$(MAKE) $(MAKECMDGOALS) IN_RECURSION=1 2>&1 | tee build.log; \
     [ ${PIPESTATUS}[0] -eq 0 ] || ( echo "MAKE FAILED!"; grep --color "Error:" build.log )

.PHONY: _default

endif

all: 
   ....

Note that in this case the \ used to catinate the two recipe lines is crucial, as the second command must run in the same shell instance as the first.

Upvotes: 0

root
root

Reputation: 6058

You basically run

make -j 8 2> >(tee /tmp/error.log)
test $? -ne 0 && echo "build errors:"
cat /tmp/error.log

and you get all of stderr after the build finishes.

Upvotes: 1

Related Questions