Sunday, September 9, 2012

Makefile: target-specific example


As always, let's start with a simple example that illustrates the difference between global and local scope in GNU Make.  The following Makefile has four targets: all, foo, bar, baz.  All four targets are phony; since I'm only interested in illustrating global and local scope I've ignored actually building any files.

all requires that foo and bar be built and bar needs baz.  The commands for each target all do the same thing.  They print the value of macro VAR using a shell echo.

.PHONY: all foo bar baz

VAR = global scope

all: foo bar
    @echo In $@ VAR is $(VAR)

foo:
    @echo In $@ VAR is $(VAR)

bar: VAR = local scope
bar: baz
    @echo In $@ VAR is $(VAR)

baz:
    @echo In $@ VAR is $(VAR)

VAR is initially defined to have the value global scope.  That's the value VAR will have anywhere in the Makefile; unless, of course, that value is overriden using a target- or pattern-specific macro.

So illustrate local scope I've redefined VAR to local scope for the rule that creates bar.

A target-specific macro definition is exactly like a normal macro definition (it uses the same =, :=, += and ?= operators) but it is preceded by the name of the target (and its colon) for which the macro should be defined.

In the Makefile above VAR is set to local scope for the bar rule by writing:

bar: VAR = local scope

If you run make on this Makefile you'll get the following output:

In foo VAR is global scope
In baz VAR is local scope
In bar VAR is local scope
In all VAR is global scope

You can clearly see that GNU Make is following its standard depth-first, left-to-right search pattern building foo (it's the first prerequisite of all), then baz (which is a prerequisite of bar which is the second prerequisite of all), then bar and finally all.

And sure enough within the rule for bar the value of VAR is local scope.  And, as you expect since there's no local definition of VAR for all and foo, VAR has the value global scope in those rules.

But what about baz.  The Makefile output shows that in baz the value of VAR is local scope, yet there was no explicit target-specific definition of VAR for baz.

baz has the same locally scoped macros as bar because baz is a prerequisite of bar.  In fact, target-specific variables are defined for a target and all prerequisites of that target and all their prerequisites and so on.    A target-specific variable's scope is the entire tree of targets starting from the target for which the variable was defined.

No comments:

Post a Comment