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, addexec 2>&3;
after the tab and optional@-
.Instead of changing the makefile, you can invoke it with the argument
SHELL=/path/to/shell_wrapper
whereshell_wrapper
is executes its argument with standard error redirected to a different descriptor, something like this: