I'm wondering how I can avoid some echo in a Makefile :
clean:
rm -fr *.o
this rule will print:
$>make clean
rm -fr *.o
$>
How can I avoid that?
To start with: the actual command must be on the next line (or at least that is the case with GNU Make, it might be different with other Make's - I'm not sure of that)
clean:
rm -rf *.o
(note, you need a TAB before rm -rf *.o
as in every rule)
Making it silent can be done by prefixing a @
:
so your makefile becomes
clean:
@rm -rf *.o
If there are no *.o
files to delete, you might still end up with an error message. To suppress these, add the following
clean:
-@rm -rf *.o 2>/dev/null || true
2>/dev/null
pipes any error message to /dev/null - so you won't see any errors-
in front of the command makes sure that make
ignores a non-zero return codeI'm responding to this ancient topic because it comes up high in search and the answers are confusing. To do just what the user wants,all that is needed is:
clean:
@rm -f *.o
The @ means that make will not echo that command.
The -f
argument to rm
tells rm
to ignore any errors, like there being no *.o
files, and to return success always.
I removed the -r from the OPs example, because it means recursive and here we are just rm
ing .o
files, nothing to recurse.
There's no need for the 2>&1 >/dev/null
because with the -f
there will be no errors printed.
.SILENT: clean
works in place of the @
, but it isn't at the same place in the Makefile as the command that it affects, so someone maintaining the project later might be confused. That's why @ is preferred. It is better locality of reference.
If you put an @ in front of the command, it doesn't echo onto the shell. Try changing rm to @rm. (Reference)
From the manual: .SILENT
is essentially obsolete since @
is more flexible.
Much worse is that make prints far too much information. Warning/error/private messages are buried in the output. On the other hand -s
(.SILENT
) suppresses just anything. Especially the "nothing to be done" and "up to date" messages can be a pain. There is no option to suppress them. You have to filter them out actively or use something like colormake. Here is a solution for grep:
make | egrep -hiv 'nothing to be done|up to date'
But the output will have line numbers. The Perl solution is therefore better, because it suppresses line numbers and flushes stdout immediately:
make | perl -ne '$|=1; print unless /nothing to be done|up to date/i'
Make's a flawed tool. "What’s Wrong With GNU make?" explains this better than I can.
There's a great article on using .SILENT
that explains how to conditionally activate it.
I have used that information to put this in my Makefile:
# Use `make V=1` to print commands.
$(V).SILENT:
# Example rule, only the @echo needs to be added to existing rules
*.o: %.c
@echo " [CC] $<"
gcc ...
What this does is if you run make
normally, normal output is silenced and instead the echo
commands work:
$ make
[CC] test.c
[CC] test2.c
But it allows you to debug problems by passing the V=1
parameter, which still shows the [CC]
messages as it helps break up the output, but the traditional Makefile output is also visible:
$ make V=1
[CC] test.c
gcc ...
[CC] test2.c
gcc ...