Make – How to suppress make error messages without suppressing other output

gnu-makemake

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.

Best Answer

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:

#!/bin/sh
eval "$2" 2>&3
Related Question