[Top][All Lists]
[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.