Tracing rule execution in GNU Make


Who hasn't wondered what exactly Make's log file output means. This article is about Makefile tracing. I cover tracing the execution of Makefile rules.

Who hasn't wondered what exactly Make's log file output means.

This article is about Makefile tracing. Back in October 2004 I wrote about tracing GNU Make macro values; here I cover tracing the execution of Makefile rules.

An Example

Throughout the this article I'll use the follow example. It builds to files: foo.o and bar. foo.o is created using a built-in rule from foo.c (which is assumed to exist) and bar has a simple rule that just touches $@.

.PHONY: all

all: foo.o bar


    @touch $@

If you run make for the first time with this Makefile you'd see the following output:

$ make

cc -c -o foo.o foo.c

There's no sign of the rule for bar being run (that's because the touch $@ was hidden using GNU Make's @ modifier so that the command was printed). There's no indication that it was the rule for foo.o that generated the compilation line. And there's no indication that the all rule was used.

You could, of course, use make -n to take look at the work that GNU Make would perform. In this case, it's practical, but in general make -n's output can be just as cryptic as a normal lo g file, and it doesn't provide any way of matching lines in ! the log with lines in the Makefile:

$ make -n

cc -c -o foo.o foo.c

touch bar

The SHELL hack

One simple way to enhance the output of GNU Make is to redefine SHELL. SHELL is a GNU Make built-in variable that contains the name of the shell to use when GNU Make executes commands.

Since most shells have a -x option that causes them to print out each command they are about to execute modifying SHELL in a Makefile by appendin -x causes every command to be printed (usually preceded by +) as the Makefile is run.

Here's the example Makefile modified using GNU Make's += operator to append -x to SHELL:

SHELL += -x

.PHONY: all

all: foo.o bar


    @touch $@

Now when the Makefile is run with GNU Make the output reveals the touch bar generated by the rule for bar:

$ make

cc -c -o foo.o foo.c

+ cc -c -o foo.o foo.c

+ touch bar

The SHELL technique has one disadvantage: it slows GNU Make down. If SHELL is left untouched GNU Make will sometimes avoid using the shell entirely if it knows it can execute the command directly (which is the case for simple operations like compilation and links). Once SHELL is redefined in a Makefile GNU Make will always use the shell slowing down exection.

Of course, that doesn't make this a bad debugging trick: getting additional information for a small slow down is a very small price to pay. But this redefinition of SHELL doesn't help track the relationship between the lines in a log file and the Makefile. Luckily, it's possible to do that with an even smarter redefinition of SHELL

Even smarter SHELL hack

If SHELL has been redefined GNU Make will expand its value before it runs each line of each rule. This means that if the expansion of SHELL were to output information it would be possible to print out information before each rule runs.

GNU Make has a $(warning) function the helpfully outputs a string of our choosing and the name of the Makefile and line number at which the $(warning) was written. It turns out that when SHELL is expanded it's possible to use $(warning) to print detailed information about the rule that's about to run.

To make this work I

About the author

John Graham-Cumming's picture John Graham-Cumming

John Graham-Cumming is Co-Founder at Electric Cloud, Inc . Prior to joining Electric Cloud, John was a Venture Consultant with Accel Partners, VP of Internet Technology at Interwoven, Inc. (IWOV), VP of Engineering at Scriptics Corporation (acquired by Interwoven), and Chief Architect at Optimal Networks, Inc. John holds BA and MA degrees in Mathematics and Computation and a Doctorate in Computer Security from Oxford University. John is the creator of the highly acclaimed open source POPFile project. He also holds two patents in network analysis and has others pending.

AgileConnection is one of the growing communities of the TechWell network.

Featuring fresh, insightful stories, is the place to go for what is happening in software development and delivery.  Join the conversation now!