help-make
[Top][All Lists]
Advanced

[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




reply via email to

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