Calling $(eval) within $(eval) can lead to very unintuitive (at least to me
:) behavior.  In particular, the inner $(eval) is expanded *and* executed
during the expansion of the outer $(eval).  For instance (I've also attached
this example, since my email client mangled the tabs in the code below):

define func2
  MY_FUNC2_VAR := $$(SOME_VALUE)
  all::
       @echo "Here2: $$(MY_FUNC2_VAR)"
endef

define func3
  MY_FUNC3_VAR := $$(SOME_VALUE)
  all::
        @echo "Here3: $$(MY_FUNC2_VAR)"
endef

define func1
  SOME_VALUE := 1
  MY_FUNC1_VAR := $$(SOME_VALUE)
  all::
        @echo "Here1: $$(MY_FUNC1_VAR)"
  $(eval $(call func2))
  ifndef SOME_VALUE
     $(eval $(call func3))
  endif
endef

$(eval $(call func1))
all::
Running gmake (3.81) on this yields:
Here2:
Here3:
Here1: 1

The execution of the inner $(eval)s before the execution of the outer
$(eval) means that:
1.) SOME_VALUE is not defined when either func2 or func3 is executed.
2.) func3 is expanded and executed despite being within a conditional that
never will be true.

After encountering this, I looked this up in the O'Reilly gmake book (
http://www.amazon.com/Managing-Projects-Make-Nutshell-Handbooks/dp/0596006101),
and, while it did discuss it, it presented this behavior as a feature (since
with it one can force early evaluation of code with an $(eval) inside an
$(eval)).

Unfortunately, $$(eval) causes gmake to die, so there does not appear to be
any way to use $(eval) within $(eval) so that it executes within the flow of
the outer $(eval)'s execution.  Is there any way to do this?  One work
around that I have thought of is to simply put the inner eval's function
contents within a file and include the file...  Are there any plans to have
some kind of $$(eval) mechanism that would defer execution inside $(eval)?
Additionally, perhaps the current $(eval) within $(eval) behavior should be
documented in the gmake manual, since it really can take one by surprise the
first time that it is encountered (unless it already is documented, and I
missed it :).  Thank you.

Tony
define func2
  MY_FUNC2_VAR := $$(SOME_VALUE)
  all::
        @echo "Here2: $$(MY_FUNC2_VAR)"
endef

define func3
  MY_FUNC3_VAR := $$(SOME_VALUE)
  all::
        @echo "Here3: $$(MY_FUNC2_VAR)"
endef

define func1
  SOME_VALUE := 1
  MY_FUNC1_VAR := $$(SOME_VALUE)
  all::
        @echo "Here1: $$(MY_FUNC1_VAR)"

  $(eval $(call func2))

  ifndef SOME_VALUE
     $(eval $(call func3))
  endif
endef

$(eval $(call func1))

all::
_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make

Reply via email to