36

Is it possible to suppress command echoing by default from within the Makefile?

I know that running make in --silent mode will do it, as will prefixing every command with @.

I'm looking for a command or stanza I can include inside the Makefile, saving the trouble of littering everything with @ or having the user silence everything manually.

Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
salezica
  • 74,081
  • 25
  • 105
  • 166

3 Answers3

45

If you define the target .SILENT:, then make will not echo anything. It's usually best to guard the definition, so you can easily turn it off:

ifndef VERBOSE
.SILENT:
endif

Now by default, make will print nothing, but if you run make VERBOSE=1, it will print.

Note that despite the statement in the manual claiming that .SILENT is obsolete -- if properly guarded, it is generally much better (more useful and flexible) than @.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • 25
    An even simpler method than using `ifndef` is just to write `$(VERBOSE).SILENT:`. Now if `VERBOSE` is empty you get the `.SILENT` target, but if you set `VERBOSE` to any non-empty value it will be disabled (define a completely different target that means nothing to make). This is also portable to other versions of make, if that matters to you. – MadScientist Jun 03 '14 at 03:46
  • 3
    It should be noted that you make sure you don't put this at the top of your Makefile. Otherwise it will try to execute the target when you set `VERBOSE` to any non-empty value. Might be obvious to some users, but I spent a few minutes wondering why I was getting error `make: Nothing to be done for '1.SILENT'.` when executing `VERBOSE=1 make` thinking it would perform my usual default target. – self. Aug 14 '15 at 16:39
  • To clarify: there's nothing wrong with putting `.SILENT` guarded by `ifndef` at the top of the `Makefile` as described in this answer. Per https://gnu.org/software/make/manual/html_node/How-Make-Works.html, targets that start with a `.` will not become the default. However, @MadScientist's suggestion of using `$(VERBOSE).SILENT` should *not* be first. I personally wouldn't use it for that subtle caveat and because I think it's much less clear. – jamesdlin Mar 06 '23 at 05:47
  • @MadScientist Or, if you really want to be succinct (at the expense of obscuring intent),`.SILENT$(VERBOSE):` would avoid the placement problem. – jamesdlin Mar 06 '23 at 05:51
  • The idea of `.SILENT$(VERBOSE)` is slightly less reliable because GNU Make reserves _every_ symbol that starts with `.[A-Z]` for possible future expansion. Obviously it's highly unlikely that GNU Make will choose to reserve the target name in the exact way that user choose to set `VERBOSE`. – MadScientist Mar 06 '23 at 14:39
36

You can add --silent in the MAKEFLAGS variable at the beginning of your Makefile:

MAKEFLAGS += --silent

all:
    echo foobar

.PHONY: all

And you will have:

$ make
foobar
jmlemetayer
  • 4,774
  • 1
  • 32
  • 46
  • 1
    I'm using GNU make 4.3, and .SILENT does not seem to work any more. However, this trick (adding the --silent flag) still works. – Erik Schnetter Feb 19 '20 at 19:00
  • 2
    This answer guides people to use more clear and readable ways. Thank's – S.M.Mousavi Oct 11 '21 at 18:01
  • @ErikSchnetter Strange, I'm also using GNU make 4.3 and adding a `.SILENT` target correctly suppresses command echoing. – FWDekker Mar 04 '23 at 13:22
  • 1
    Note this method won't work with older versions of GNU make, where modifying MAKEFLAGS inside the makefile isn't as well supported. It also is less portable: the `.SILENT` target is specified by POSIX but `--silent` is not (although `-s` is), and it's not specified by POSIX what happens if you modify `MAKEFLAGS` inside the makefile. – MadScientist Mar 06 '23 at 17:51
11

According to GNU Make's manual, you can use special target .SILENT.

Note that the manual says that:

.SILENT is essentially obsolete since ‘@’ is more flexible.

But it seems to work as expected. The following code silences the all target:

.SILENT:

hoge:
    echo hoge

The following example silences only the hoge target:

.SILENT: hoge

hoge:
    echo hoge

fuga:
    echo fuga
Martijn Heemels
  • 3,529
  • 5
  • 37
  • 38
ymonad
  • 11,710
  • 1
  • 38
  • 49