bin/64327: [PATCH] make(1): document surprising behaviour of
assign with expansion
Oliver Eikemeier
eikemeier at fillmore-labs.com
Tue Mar 16 06:00:41 PST 2004
The following reply was made to PR bin/64327; it has been noted by GNATS.
From: Oliver Eikemeier <eikemeier at fillmore-labs.com>
To: Ruslan Ermilov <ru at freebsd.org>
Cc: FreeBSD-gnats-submit at freebsd.org
Subject: Re: bin/64327: [PATCH] make(1): document surprising behaviour of
assign with expansion
Date: Tue, 16 Mar 2004 14:58:35 +0100
Ruslan Ermilov wrote:
> On Tue, Mar 16, 2004 at 12:49:27PM +0100, Oliver Eikemeier wrote:
>
>>Try the Makefile from the patch:
>>
>>VAR1:= Assigned with${OUT} expansion
>>VAR2!= echo Assigned with${OUT} expansion
>>OUT= out
>>all:
>> @echo := - ${VAR1}
>> @echo != - ${VAR2}
>>
>>
>>>Fix:
>>
>>diff -u -r1.29.2.15 make.1
>>--- make.1 17 Dec 2002 19:01:18 -0000 1.29.2.15
>>+++ make.1 16 Mar 2004 11:12:09 -0000
>>@@ -1266,6 +1266,17 @@
>> \&.endfor
>> .Ed
>> won't work, and should be rewritten the other way around.
>>+.Pp
>>+Undefined variables are not expanded when assigned with expansion.
>>+This is intentional, but may lead to surprising results:
>>+.Bd -literal
>>+VAR1:= Assigned with${OUT} expansion
>>+VAR2!= echo Assigned with${OUT} expansion
>>+OUT= out
>>+all:
>>+ @echo := - ${VAR1}
>>+ @echo != - ${VAR2}
>>+.Ed
>> .Sh SEE ALSO
>> .Xr mkdep 1 ,
>> .Xr make.conf 5
>>
>
> So, expanding "Assigned with${OUT} expansion" with := when OUT is undefined
> gives you the same string (have a look at the ``make -r -dv'' output), and it
> becomes a value of VAR1, and when later you print it, it's expanded again (as
> it still has the `$' character). This time OUT is defined, and its value is
> substituted.
Of course you could move `OUT=out' after `all:'. The point is that you'll
encounter problems with that pretty often in bsd.port.mk.
> Expanding "echo Assigned with${OUT} expansion" through != gives you "Assigned
> with expansion", and that's what gets printed later.
I guess I tried my own example before posting it...
> Whatever, "undefined variables are not expanded" sounds like a non-sense
> to me. ;)
Basically that is what it does: it leaves undefined variables there for late
expansion. If you try:
SUFFIX?= .txt
_FILE:= ${FILE}${SUFFIX}
.if exists(${_FILE})
....
.endif
FILE= settings
SUFFIX= .opt
.if exists(${_FILE})
....
.endif
You'll test for the existence of `.txt' in the first .if, and for `settings.txt'
in the second. It took me a while to figure *that* out.
> The following code fragment in make(1) is responsible for this, and has more
> correct wording:
>
> : } else if (type == VAR_SUBST) {
> : /*
> : * Allow variables in the old value to be undefined, but leave their
> : * invocation alone -- this is done by forcing oldVars to be false.
> : * XXX: This can cause recursive variables, but that's not hard to do,
> : * and this allows someone to do something like
> : *
> : * CFLAGS = $(.INCLUDES)
> : * CFLAGS := -I.. $(CFLAGS)
> : *
> : * And not get an error.
> : */
> : Boolean oldOldVars = oldVars;
> :
> : oldVars = FALSE;
I know. Thats the reason I wrote: `This is intentional' and didn't file a bug report.
> Perhaps you could convert it to fit the manpage? Definitely we shouldn't put
> it in the BUGS section.
I though so. What should I use: HISTORY, CAVEATS, IMPLEMENTATION NOTES or something else?
How about:
Undefined variables are left untouched when assigned with expansion.
This is intentional, but may lead to surprising results:
VAR1:= Assigned with${OUT} expansion
all:
@echo ${VAR1}
OUT= out
Outputs `Assigned without expansion'. You can use != and echo to avoid this effect.
More information about the freebsd-bugs
mailing list