I'm implementing a simple build system that's actually just a wrapper around Make. Since this build system already emits its own error messages, I don't want Make to produce error messages like

make: *** [/cool/makefile:116: /fun/target.o] Error 1

on failure.

I'm already using the -s flag to suppress most of Make's output. And I don't want Make to ignore errors; I still want it to stop and exit with a status. I can't just kill all error output with make 2> /dev/null because I still want to see messages printed to stderr by the tasks Make is running.

Is there a way to do this without manually parsing and sanitizing Make's output? I'm using GNU Make 4.2.1, and I don't mind GNU Make-specific solutions.


Since your system is a wrapper around make, I presume that it generates the makefile. Tweak your generator to add 2>&3 to all the shell commands in the makefile, and make your program redirect file descriptor 3 to standard error (file descriptor 2) and file descriptor 2 to /dev/null. This way the make program itself will print to its standard error, which goes to /dev/null, and build commands will print to their standard error, which goes to the wrapper's standard error.

If you're using a handwritten makefile, you can transform it to add those redirections, assuming the makefile doesn't go too wild with syntax (e.g. no fancy GNU make macros that generate commands). For every line that starts with a tab and optionally @ or -, and where the previous line does not end with a backslash, add exec 2>&3; after the tab and optional @-.

Instead of changing the makefile, you can invoke it with the argument SHELL=/path/to/shell_wrapper where shell_wrapper is executes its argument with standard error redirected to a different descriptor, something like this:

eval "$2" 2>&3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.