Date: Tue, 16 Mar 2004 06:00:40 -0800 (PST) From: Oliver Eikemeier <eikemeier@fillmore-labs.com> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/64327: [PATCH] make(1): document surprising behaviour of assign with expansion Message-ID: <200403161400.i2GE0eMj005175@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/64327; it has been noted by GNATS. From: Oliver Eikemeier <eikemeier@fillmore-labs.com> To: Ruslan Ermilov <ru@freebsd.org> Cc: FreeBSD-gnats-submit@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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200403161400.i2GE0eMj005175>