| 
Home arrow Articles arrow Columns arrow Ask Mr. Make arrow Printing the Value of a Makefile Variable
Printing the Value of a Makefile Variable Print
Written by John Graham-Cumming   
Sunday, 27 June 2004


If you've ever looked in a Makefile you'll realize that Makefile variables (often called macros) form the backbone of any Make process. The variables usually define which files will be compiled, what command-line parameters to pass to compilers, even where to find the compiler itself. And if you've ever tried to debug a Makefile you'll know that the number 1 question you ask yourself is “What is the value of variable X?.”


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.



John Graham-Cumming is Founder and VP of Engineering 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.

Trackback(0)
Comments (0)add
Write comment
smaller | bigger

security image
Write the displayed characters


busy
 
< Prev   Next >

Video News

Whitepaper Spotlight

Stay up to date with Configuration Management and Application Lifecycle Management technology products and services by browsing our featured white papers below: See all the Featured Whitepapers>>
Tool Spotlight
CollabNet
CollabNet Subversion is an enterprise-ready distribution of Subversion® that includes, in one package,...
Read More
AccuRev
AccuRev is a best-of-breed, process-centric software configuration management (SCM) solution for...
Read More
IBM Rational Build Forge Express Edition
IBM Rational Build Forge Express Edition is a flexible and robust build automation framework developed,...
Read More
Sapient ResultSpace
ResultSpace is the Agile Application Lifecycle Management (ALM) solution that enables software development...
Read More