[Top][All Lists]

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

Re: local variable in make

From: Philip Guenther
Subject: Re: local variable in make
Date: Mon, 9 Aug 2010 19:58:14 -0700

On Mon, Aug 9, 2010 at 7:13 PM, Peng Yu <address@hidden> wrote:
>> 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
>> works.
> Are you considering adding the local variable feature to macros? I
> know that it may not easy to implement such feature in a backward
> compatible way. But having such feature helps writing more complex and
> more flexible Makefiles.

Given the way that variable expansion works in make, 'local' variables
would be a *HUGE* trap.  If you think you have headaches from $(eval),
combining them with local variables will make your code completely
impossible to debug or maintain.  Just think about how deferred
expansion works: the scope of a "local" variable would have to include
contexts outside of the macro's expansion, or else they would have to
be so completely limited as to be almost pointless.  I.e., they would
either be a misnomer or a bad choice.

What you probably want is simply a way to generate a relatively unique
name for a variable.  Fortunately, you can do that right now by
including some unique argument in the variable names.  In this case,
$1 should work, no?
PREFIX.$1 = $1
        echo all:$$(PREFIX.$1)

Of course, this example is completely ridiculous (you have $1, so USE
IT!), but given the example that's the best that can be shown.

>> 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.
> I found the following way of defining PREFIX as a macro that takes an
> argument ($1).
> ########
> .PHONY: all
> define myfun
> PREFIX=$$(patsubst %,%,$$(1))

This only works because PREFIX has the same definition in each case.
I.e., it's a completely pointless variable.  Why do you want a
variable PREFIX when you already have the value in $1?

>> or even better, skip eval and call altogether and use simply:
>>        all%:
>>                echo $@

Yes, this is *EXACTLY* what should be done.  It sometimes seems that
people use $(eval) because they think it's simpler than pattern rules,
or maybe that it's easier to think about, but the opposite is true.

>> 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.
> Yes. My real case is too complex to be described here. If I did,
> probably you will get lost. So I made a simple example to capture the
> gist of my real case. But making my example even simpler won't help my
> real case.

If your case is so complex that you can't describe it, then it's too
complicated, period.  You need to find a way that *you* understand
that can break it down into smaller problems that you can solve.  For
many many years, the answers to that have been
 - just write out all the rules
 - write a program (in shell, awk, m4, whatever) to generate
   the makefile...that has them all written out

Note that $(eval) is basically the latter, but you're writing that
program in a weird language with deferred expansion and confusing
lexical rules.  It's like using the most uncomfortable screwdriver to
insert screws, just because it came in the box of screws.

> The complexity of the usage eval probably should be better expanded in
> the manual. The current explanation of eval in the manual is probably
> too sparse, considering that there could be many tricks in using eval
> for high-order programming (just as eval in Lisp and Perl).

Umm, Lisp programs put 'eval' in the very back corner of their
toolbox, with barbed-wire around it, because 99 times out of 100 (or
(more!) it's the Wrong Thing.  The Right Thing there is generally
defmacro...which is not what make has.  The perl people do the same
thing with _their_ "expand and re-evaluate as perl code" operator
(which is one of the two uses of their eval) for similar reasons:
variable references, closures, and compiled regexps solved 99/100 of
their problems.

>> Alternatively you could use target-specific variables but it seems like
>> overkill.
> Yes, that is the reason that I am looking for some walkaround for
> 'local' variables.

I don't get it.  "I'm looking for a workaround for my problem.  This
is a workaround, but I don't want to use it."  ?

Philip Guenther

reply via email to

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