help-make
[Top][All Lists]
Advanced

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

Re: variable scope


From: Philip Guenther
Subject: Re: variable scope
Date: Wed, 10 Mar 2010 19:29:06 -0800

On Wed, Mar 10, 2010 at 1:59 AM, Massimiliano Cialdi
<address@hidden> wrote:
> Hi I have a problem with variable definition

Not quite.  You have a problem with $(eval) being Too Subtle For
Mortals.  The result is that people *think* they understand $(eval),
but really their programs work only by coincidence...until they stop
working.


To be particular, this definition is broken:

> define asdrubale
> $(info  marker0 $(0) ** $(1))
> $(1)_VAR1 = -param_$$($(1)_MCU)
> $(foreach z,$($(1)_COMPILE_SET),$(eval $(call build_target,$(1),$(z))))
> endef

This is apparently meant to be used with $(eval $(call
asdrubale,target)).  When make sees that expression, it first
COMPLETELY EXPANDS the $(call) by setting the number variables and
performing variable expansion, BUT NOT MAKEFILE EVALUATION.

So, it expands the $(info ...) call, resulting in an empty line and
the side-effect of some output to stdout.  Then it expands the second
line and gets
    target_VAR1 = -param_$(target_MCU)

Note that at this point, that's just text that's the result of
variable expansion.  It's *not* evaluated as a makefile fragment!
Then make expands the third line, which involves expanding the
build_target definition *and* evaluating the result of that expansion.
 That has the side-effect of various variable assignments and rule
definitions, but doesn't generate any text, so the complete expansion
of
$(call asdrubale,target) is
    target_VAR1 = -param_$(target_MCU)
...and a bunch of side-effects.  That text is the argument to $(eval),
so it *finally* gets evaluated and the variable assignment occurs.


There are probably a dozen ways to "fix" this code.  My favorite would
be to not use $(eval) at all, because I don't want to spend my life
maintaining Makefiles that give me headaches and which none of my
co-workers can help me with.  Instead, I would use includes that could
be pulled in repeatedly, because the order of evaluation in those
doesn't stab you in the back.

If you insist on using $(eval), ask yourself why you're using $(eval)
both around the call to asdrubale *and* _inside_ of asdrubale.

...and if you get it working, then ask yourself how sure you are that
stuff isn't *still* being expanded and/or evaluated more times than it
should.  And whether you'll understand why this works next week.  And
whether the guy in the next cube will understand it next month...


Philip Guenther




reply via email to

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