help-make
[Top][All Lists]
Advanced

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

Understanding $(eval)


From: Bryan Ischo
Subject: Understanding $(eval)
Date: Mon, 10 Sep 2007 17:11:56 -0400 (EDT)
User-agent: SquirrelMail/1.4.8-4.fc5

Hi all.  I'm trying to understand the gnu make "eval" function.

According to the info page:

"The `eval' function is very special: it allows you to define new
makefile constructs that are not constant; which are the result of
evaluating other variables and functions.  The argument to the `eval'
function is expanded, then the results of that expansion are parsed as
makefile syntax.  The expanded results can define new `make' variables,
targets, implicit or explicit rules, etc."

What I don't understand is, why this function is necessary.  Here's my
reasoning:

Whenever gnu make encounters the invocation of an $(eval) function, it
will evaluate the text therein as make syntax.  Here is an excerpt from
the example from the info page:

     define PROGRAM_template
      $(1): $$($(1)_OBJ) $$($(1)_LIBS:%=-l%)
      ALL_OBJS   += $$($(1)_OBJS)
     endef

     $(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))

What I don't get is, why $(eval) is necessary here.  I would expect that
what make would do at this point in processing the make file is, read in
the text for the $(foreach) invocation, recognize that it's a function
call that should be performed, and evaluate the $(foreach).  When the
$(foreach) has been evaluated, the result is text that make should then
pick up and process just as if it was the text that was at this spot in
the makefile to begin with.  Thus, without the $(eval) in there, I would
expect the $(foreach) call to, for each word in PROGRAMS, call the
PROGRAM_template function, which results in some text.  The end result of
$(foreach) doing this for each PROGRAM is a bunch of text that the
PROGRAM_template invocations made.  Make would then process the text that
the $(foreach) function call resulted in, which itself is the
concatenation of each bit of text that each PROGRAM_template invocation
produced, and since the text is a bunch of rules, those rules would be
handled by make just as if they had been manually written at that spot in
the makefile.

But, in actuality, if you don't include the $(eval) invocation, then make
does not process the text that resulted from the $(call) as make syntax. 
I don't know what it does with it exactly, but it doesn't parse it as make
syntax (when I invoke make on such a construct (a $(call) without an
$(eval) around it), I get an error like this: call.mk:9: *** multiple
target patterns.  Stop.).

I find this even more confusing when I consider that $(eval) seems to be a
no-op when used like this:

$(eval FOO := bar)

This has exactly the same effect as this:

FOO := bar

In this case, make would have processed the FOO := bar as a variable
assignment, just as expected.  Adding the $(eval) in there doesn't seem to
do anything, because make was *already* going to evaluate that text.

So I guess what I'm getting at is, why is $(eval) needed at all?  It seems
like all it does is to tell make to evaluate its argument (be it static
text or text which was produced by evaluating another function) as make
syntax.  But why wouldn't make do that anyway?

Consider this example of what I think "ought" to work:

---
define VARIABLE_CREATION_FUNCTION
variable_$(1)
endef

define RULE_CREATION_FUNCTION
.PHONY: $(1)
$(1):
        @ echo $(1)
endef

FOO := $(call VARIABLE_CREATION_FUNCTION,foo)

$(call RULE_CREATION_FUNCTION, $(FOO))
---


Here is what I would expect:

In the assignment of the variable FOO, make would see a function call, and
would suspend its normal processing of the text at this point to "call"
the given function with the given argument, which will produce some text. 
Make should then resume where it left off; it knew that it was assigning a
value to a variable, so it needs to take whatever text is to the right of
the = sign (which is now the result of the function call) as the value of
the variable.

In the call of the RULE_CREATION_FUNCTION, make should know that at this
point of the file, it's not assigning a value to a variable, and thus
should evaluate whatever text it finds as make syntax.  It sees the call
to the RULE_CREATION_FUNCTION, evaluates it, and the result is some text. 
It should then resume where it left off, which was processing text as make
syntax.  It would then evaluate the result of the function call.  No need
to be explicitly told to do so by an $(eval) function invocation.

My question is, why doesn't make behave this way?  It seems to be that
$(eval) is really superfluous, because wherever an $(eval) would occur in
the makefile, it is just telling make to do what I would expect it should
be doing anyway: evaluating the text as make file syntax.

Is there some other use of $(eval) that I am missing?  Is there some
aspect to how make must process makefile commands that I am not
understanding that makes $(eval) necessary?

Thank you, and best wishes,
Bryan



------------------------------------------------------------------------
Bryan Ischo                address@hidden            2001 Mazda 626 GLX
Hamilton, New Zealand      http://www.ischo.com     RedHat Fedora Core 5
------------------------------------------------------------------------






reply via email to

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