[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: local variable in make

From: Paul Smith
Subject: Re: local variable in make
Date: Mon, 09 Aug 2010 21:04:06 -0400

On Mon, 2010-08-09 at 17:53 -0500, Peng Yu wrote:
> I tried 'undefine' below. It still has the same problem. I guess this
> is because make has two stage to pass the variables and then construct
> the rules.
> .PHONY: all
> PREFIX:=abc
> all: all1
>       echo all:$(PREFIX)
> undefine PREFIX
> PREFIX:=efg
> all1:
>       echo all1:$(PREFIX)

Right.  In make every global variable (like PREFIX here) has one and
only one value.  When you change that value, then it has the new value.
This is a very fundamental aspect of make: you simply cannot expect to
create complex makefiles until you completely internalize how expansion

You need to read the GNU make manual section on "How make reads a
makefile" again (and again): afterwards you'll understand (hopefully,
unless the manual is not well written) the concept of immediate
expansion vs. deferred expansion.

Only during immediate expansion is the value expanded and so the value
of variables at that point are taken.

As you say, make has a two-pass processor: in the first pass it reads
the entire makefile.  In this pass, recipes are deferred: they are not
expanded.  In the second pass make tries to build all the appropriate
targets.  Just before a target is built, that's when its recipe is

So, for a value of $(PREFIX) in a recipe, whatever the LAST SETTING of
PREFIX was after all the makefiles are read, is the value that $(PREFIX)
will have when any recipe is expanded.

> Is there a walkaround to allow local variables in macro? (Not that I
> couild append the variable with some unique suffix, but this looks
> ugly and I tend to avoid this walkaround. I'm wondering if there is
> any better walkaround)

The values of $1, $2, etc. are local to the call macro.

Why are you trying to set a variable like PREFIX here?  Why not just
reuse the local variables?

        define myfun
                echo all:$1

Of course, it's better to just say:

        define myfun
                echo $@

or even better, skip eval and call altogether and use simply:

                echo $@

I can only assume your real intention is too complex for these simpler
methods.  Eval, in particular, is very tricky to use and so you should
never even attempt to use it unless you're absolutely sure that any
lesser option simply won't work.

Alternatively you could use target-specific variables but it seems like

 Paul D. Smith <address@hidden>          Find some GNU make tips at:            
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist

reply via email to

[Prev in Thread] Current Thread [Next in Thread]