Printing the Value of a Makefile Variable

[article]
Summary:

There aren't any debuggers for Make, and Make doesn't provide the sort of interactivity you'd see from a scripting language like Perl or Python. So what is an easy way to figure out the value of a variable? This simple Makefile does all the work for you.

There aren't any debuggers for Make and Make doesn't provide the sort of interactivity you'd see from a scripting language like Perl or Python. So how do you figure out the value of a variable? Take a look at this simple Makefile (which does nothing but set various variables):

X=$(YS) hate $(ZS)

Y=dog
YS=$(Y)$(S)
Z=cat
ZS=$(Z)$(S)
S=s
all:

What's the value of X? The small size and simplicity of this Makefile means that tracing through all the variable assignments is feasible, leading to the conclusion the X is “dogs hate cats”. In a real multi-thousand line Makefile that unleashes the power of GNU Make's variables and functions figuring out the value of a variable can be a laborious task. But here's a little Make recipe that does all the work for you. Create a Makefile called helper.mak and place in it:

print-%:

@echo $* = $($*)


Now we can find the value of variable X with the following command:

gmake -f Makefile -f helper.mak print-X

The first -f Makefile tells GNU Make to load our original Makefile, and the second -f helper.mak loads in the receipe. The print-X directs make to “build” the target named print-X. Since there isn't an explicit rule to build print-X GNU Make looks for a pattern and finds print-% (the % acts as a wildcard) and runs the associated command.

The command uses $* (a special GNU Make variable that will have the value matched by the % in the rule) to print the name of the variable and then by doing $($*) gets the value of the variable named by $*. So experimenting with it we can see the following:

$ gmake -f Makefile -f helper.mak print-X
X = dogs hate cats
$ gmake -f Makefile -f helper.mak print-YS
YS = dogs
$ gmake -f Makefile -f helper.mak print-S
S = s

Sometimes it's useful to know how a variable was defined. GNU Make provides the $(origin) function that returns a string containing the type of the variable

(e.g. Whether it was defined in a Makefile, on the command-line, or in the environment). Modifying helper.mak prints out origin information as well.

print-%:
@echo $* = $($*)
@echo $*\'s origin is $(origin $*)

Now we see that YS is defined in the Makefile.

$ gmake -f Makefile -f helper.mak print-YS

YS = dogs
YS's origin is file

If we override the value of YS on the GNU Make command-line we'll see:

$ gmake -f Makefile -f helper.mak print-YS YS=fleas

YS = fleas
YS's origin is command line

Next time I'll serve up a recipe for printing every variable in a Makefile.

About the author

AgileConnection is a TechWell community.

Through conferences, training, consulting, and online resources, TechWell helps you develop and deliver great software every day.