[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Understanding $(eval)
From: |
Paul Smith |
Subject: |
Re: Understanding $(eval) |
Date: |
Tue, 11 Sep 2007 00:26:51 -0400 |
On Mon, 2007-09-10 at 17:11 -0400, Bryan Ischo wrote:
> 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))))
> 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.).
It does TRY to parse the result as make syntax. However, it's a feature
(or limitation, perhaps) of the make parser that a logical line in the
makefile can only expand to a single line. You cannot have a line in
the makefile expand into multiple lines. It just doesn't work; make
will try to treat the results as a single "line" containing newline
characters, where the newlines are treated like any other character
rather than like line separators.
> 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, since the thing eval is expanding is a single line, they
are exactly equivalent.
> 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?
Originally when I set out to implement the feature provided by eval,
this is exactly how I intended to do it: remove the restriction that a
single line of a makefile must expand to a single line, and allow the
expansion to create multiple lines which would then themselves be
parsed. This turned out to be annoyingly tricky, although of course it
would be doable: it's just programming. In fact, it could STILL be done
if we wanted to do it.
However, I then decided to just use an $(eval ...) function since it was
simpler to implement, AND it does provide one very powerful feature you
can't get using the original method; consider this:
all: foo ; @echo $(FOO)
foo: ; $(eval FOO = foo)
Obviously this is a contrived example, but the ability to perform make
operations such as setting make variable from inside command scripts can
provide a lot of power.
--
-------------------------------------------------------------------------------
Paul D. Smith <address@hidden> Find some GNU make tips at:
http://www.gnu.org http://make.mad-scientist.us
"Please remain calm...I may be mad, but I am a professional." --Mad Scientist