bin/64327: [PATCH] make(1): document surprising behaviour of assign with expansion

Ruslan Ermilov ru at freebsd.org
Tue Mar 16 05:50:24 PST 2004


The following reply was made to PR bin/64327; it has been noted by GNATS.

From: Ruslan Ermilov <ru at freebsd.org>
To: Oliver Eikemeier <eikemeier at fillmore-labs.com>
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 15:41:50 +0200

 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.
 
 Expanding "echo Assigned with${OUT} expansion" through != gives you "Assigned
 with expansion", and that's what gets printed later.
 
 Whatever, "undefined variables are not expanded" sounds like a non-sense
 to me.  ;)
 
 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;
 
 Perhaps you could convert it to fit the manpage?  Definitely we shouldn't put
 it in the BUGS section.
 
 
 
 Cheers,
 -- 
 Ruslan Ermilov
 FreeBSD committer
 ru at FreeBSD.org


More information about the freebsd-bugs mailing list