[Top][All Lists]

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

re: a function that calls a function eval'ing an immediate variable

From: Paul D. Smith
Subject: re: a function that calls a function eval'ing an immediate variable
Date: Thu, 4 Mar 2004 14:03:55 -0500

%% Sandy Currier <address@hidden> writes:

  sc> What fails is that an immediate variable, defined in the first
  sc> (outer) function, does not appear to be accessable by the second
  sc> (inner) macro/function call.

There are two things to keep clear: first is the difference between
expansion and evaluation: expansion is replacing references to variables
with their values and evaluation is examining some text and interpreting
it as makefile command lines, and the second is that make always expands
things from the innermost values _out_, not the outermost values in.

So, for a simple example that doesn't use call or eval:

    $(foo $(bar $(baz $(biz))))

Here make will first expand biz, then expand baz+(result of biz),
then expand bar+(result of baz+biz), then finally expand foo+(result
of foo+baz+biz).

Make is not a procedural language, like C.  It's much closer to Lisp.

I tried to simplify your snippet down to the most basic level:

  sc> TEST2_TEMPLATE = _TEST2_$(1) := $$(DO_FLAVOR_$(1))/$$(_THIS_DIR)

  sc> $(foreach platform, $(PLATFORMS),$(eval $(call 
  sc> endef

  sc> $(eval $(call SECTION_1_MODULE_BLOCK,ZZZ,AAA))

Here make does the following, in this order:

  * Expand the arguments to SECTION_1_MODULE_BLOCK, "ZZZ" and "AAA".
    Since there are no variables, they expand to themselves.

  * Set $1 = ZZZ and $2 = AAA, then expand the value of
    SECTION_1_MODULE_BLOCK.  At this time, nothing is evaluated, so the
    results of this expansion (including the setting of variables like
    _THIS_DIR etc.) is just one long string to make.  It does _NOT_ set
    those variables until later, when the string is evaluated.

  * While expanding SECTION_1_MODULE_BLOCK we do the foreach, and for each
    value of PLATFORMS we expand the TEST2_TEMPLATE value with $1 set to
    that value.  Each time it expands to a string like this:

      _TEST2_sol2 := $(DO_FLAVOR_sol2)/$(_THIS_DIR)

  * Once it's expanded, we evaluate it--here is the _FIRST_ time that we
    evaluate anything so this is the first time any of the expanded
    strings is actually interpreted as a make command.  Note that since
    the variable setting use :=, the right-hand side is expanded right
    now, so whatever the value _THIS_DIR has right now will be used.  We
    haven't evaluated the "outer" part of SECTION_1_MODULE_BLOCK yet, so
    that variable isn't set.

  * After the foreach is done, then we have the expansion of the $(call
    SECTION_1_MODULE_BLOCK,ZZZ,AAA) completed as a long string with
    embedded newlines, then that is given to $(eval ...) to evaluate.
    _NOW_ _THIS_DIR is set to ZZZ, but it's too late now because the
    expansion of the references to this variable happened already.

  sc> Uh, I think I figured out what is wrong with the prior post.  It
  sc> looks like pilot error on my part.

  sc> The correct invocation of the foreach from within the outer
  sc> function should be:

  sc> $$(foreach platform, $(PLATFORMS),$$(eval $$(call 

This is one way to do it, yes.

  sc> and not

  sc> $(foreach platform, $(PLATFORMS),$(eval $(call 

  sc> Not exactly sure why, but the former seems to work and the latter
  sc> does not.

With the above explanation maybe you can see why this works now.  Here,
the internal $(eval ...) doesn't get invoked during the $(call ...),
because it's escaped with $$.  This leaves it to be expanded during the
outer $(eval ...), and in this case _THIS_DIR _HAS_ been set already.

There are other ways to get the same result.

 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]