help-make
[Top][All Lists]
Advanced

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

Re: function $(eval ...) in make 3.81 compared to 3.80


From: Philip Guenther
Subject: Re: function $(eval ...) in make 3.81 compared to 3.80
Date: Tue, 26 Jun 2007 11:53:38 -0600

On 6/26/07, Jacques Klein <address@hidden> wrote:
I just upgraded from v3.80 to 3.81 because of strange bugs when using
$(eval ...) on a MacOsX os (the same makefile works fine with a 3.80
make on Linux).

But now, I am "completelly lost" with the "new" behavior of $(eval ..);
to make things work, I have to sometimes use not just TWO $'s but FOUR
of them.

Is there some "expert" to explain this ?, or point to a good and
uptodate (3.81) tutorial for the $(eval ...)  function ?.

Here is a makefile example showing the behaviour:

# -*- Makefile -*-

$(warning MAKE_VERSION=$(MAKE_VERSION))

x := x_val
$(eval $(warning 1 dollar:  x=$x))
$(eval $(warning 2 dollars: x=$$x))

Those 'eval' calls do nothing.  Before the 'eval' is processed, make
expands its arguments.  The expansion of '$(warning ...)' is nothing,
with the side-effect that '...' is printed.  So, the 'eval' calls are
given the empty argument and do nothing else: the side effect of the
'warning' call has already occurred.  If you wanted the eval
processing to happen before the warning you would need to write:

   $(eval $$(warning 1 dollar:  x=$x))

That passes the string '$(warning 1 dollar: x=x_val)' to 'eval', which
then performs the 'warning' call.

...
$(eval 2dollars: \; @echo with 2 dollars: target=$$@)
$(eval 4dollars: \; @echo with 4 dollars: target=$$$$@)
...
../src/makefile.eval:3: MAKE_VERSION=3.80
with 2 dollars: target=2dollars
with 4 dollars: target=

and

../src/makefile.eval:3: MAKE_VERSION=3.81
...
with 2 dollars: target=
with 4 dollars: target=4dollars

Hmm.  It's apparently the backslash before the semicolon which is
causing an extra round of expansion with 3.81: if you take that it
shows target=2dollars.  However, that breaks it for 3.80, where the
unquoted semicolon breaks the 'end of variable' detection.

The work around is to put the bits to eval into a variable and eval
the variable's value:

   tmp = 2d: ; @echo with 2 dollars: target=$@
   $(eval ${value tmp})
or
   define tmp
   2d:




  It's important to realize that the `eval' argument is expanded
_twice_; first by the `eval' function, then the results of that
expansion are expanded again when they are parsed as makefile syntax.
This means you may need to provide extra levels of escaping for "$"
characters when using `eval'.  The `value' function (*note Value
Function::) can sometimes be useful in these situations, to circumvent
unwanted expansions.




reply via email to

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