59

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?

Nate Barbettini
  • 51,256
  • 26
  • 134
  • 147
claf
  • 9,043
  • 17
  • 62
  • 79

6 Answers6

88

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
  • the - in front of the command makes sure that make ignores a non-zero return code
plof
  • 1,294
  • 1
  • 9
  • 7
  • 1
    That is the classic way of dealing it wish bash, but I was looking for the GNU Make way of solving this problem. And of course I had the command on the next line, just wrote the question in a hurry. BTW, what do you think of the .SILENT answer (which a friend of mine found) ? – claf Jun 30 '10 at 15:16
  • I haven't really used .silent, the GNU Make manual states that it is only supported for historical reasons, but I do like it. It's less verbose than many `@` in your commands. – plof Jul 01 '10 at 02:20
  • 4
    Come to think of it, the `-` and the `|| true` together are too much - either one of them should suffice. You need one of them to prevent Gnu Make from quitting if there is nothing to delete. Better would have been to use `rm -f *.o`, since that doesn't return an error if there is nothing to delete. – plof Jul 01 '10 at 02:28
37

In fact I was looking for something else, adding this line to the Makefile :

.SILENT:clean

while execute every step of the "clean" target silently.

Until someone point some drawback to this, I use this as my favourite solution!

claf
  • 9,043
  • 17
  • 62
  • 79
31

I'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 rming .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.

phorgan1
  • 1,664
  • 18
  • 18
10

If you put an @ in front of the command, it doesn't echo onto the shell. Try changing rm to @rm. (Reference)

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
SCFrench
  • 8,244
  • 2
  • 31
  • 61
4

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.

Andreas Spindler
  • 7,568
  • 4
  • 43
  • 34
4

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 ...
Malvineous
  • 25,144
  • 16
  • 116
  • 151
  • Why does this not have more upvotes? SO is so weird sometimes. This is EXACTLY what I was looking for! – yen Aug 23 '23 at 01:48