1. Overview

Make prints each command present in a Makefile before executing it, which can lead to the unnecessary output. In this tutorial, we’ll learn how to suppress the echo of the command invocations in a Makefile.

2. Echo of Command Invocation in a Makefile

Let’s create a small Makefile to see how make executes it:

$ cat Makefile
all: foo bar

foo:
    printf "%s\n" "Target foo executing..."
    printf "%s\n" "Hello from foo!"
bar:
    printf "%s\n" "Target bar executing..."
    printf "%s\n" "Hello from bar!"

Here, we have two targets, foo and bar, which print some text with the printf command:

$ make
printf "%s\n" "Target foo executing..."
Target foo executing...
printf "%s\n" "Hello from foo!"
Hello from foo!
printf "%s\n" "Target bar executing..."
Target bar executing...
printf "%s\n" "Hello from bar!"
Hello from bar!

As we can see, both the invocation of the printf command and the output of the printf command are printed. Here, the lines containing printf “%s\n” are the command invocations.

3. Suppressing the Echo of Command Invocation

To reduce clutter, we only want to print the actual command output and not the executed command itself. Now, let’s explore the various methods for doing so.

3.1. Per-Command

We can suppress the echo on a per-command basis by prefixing the command with the @ symbol. Let’s suppress the first printf call for both the targets:

$ cat Makefile
all: foo bar

foo:
    @printf "%s\n" "Target foo executing..."
    printf "%s\n" "Hello from foo!"
bar:
    @printf "%s\n" "Target bar executing..."
    printf "%s\n" "Hello from bar!"

As we can see, the invocation of the first printf command that says “Target … executing …”  is not shown anymore:

$ make
Target foo executing...
printf "%s\n" "Hello from foo!"
Hello from foo!
Target bar executing...
printf "%s\n" "Hello from bar!"
Hello from bar!

3.2. Per-Target

We can suppress all command invocations for a target by marking it as a dependency of the special .SILENT target.

Let’s silence the foo target:

$ cat Makefile
.SILENT: foo

all: foo bar

foo:
    printf "%s\n" "Target foo executing..."
...

Now, we can see that the command invocations are printed only from the bar target:

$ make
Target foo executing...
Hello from foo!
printf "%s\n" "Target bar executing..."
Target bar executing...
printf "%s\n" "Hello from bar!"
Hello from bar!

3.3. Globally

Finally, we can pass the -s flag to make to silence the command invocations of every target. This method also has the benefit of not requiring any modifications to the Makefile:

$ make -s
Target foo executing...
Hello from foo!
Target bar executing...
Hello from bar!

This method is quite handy as we can use it to reduce clutter once the Makefile is ready and fall back to executing make as normal during development. The extra output is helpful during development as it aids debugging.

4. Conclusion

In this article, we learned about the echo of command invocation in a Makefile and how we can suppress it to reduce unnecessary output.