tech-pkg archive

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

Re: make variable expansion oddity



Am 27.05.2016 um 05:25 schrieb David Holland:
> On Thu, May 26, 2016 at 10:44:51PM +0200, Roland Illig wrote:
>  > > 	.for var val in ${SED_SUBSTS}
>  > > 	SED_CMD+= -e s,@${var}@,${val},
>  > > 	.endfor
>  > 
>  > In a .for loop, the part after "in" is evaluated at parse time. And
>  > there is another quirk. Splitting of the words is done at simple
>  > whitespace, ignoring "double" and 'single quotes' completely. This is
>  > contrary to all other places in make(1).
> 
> Er wut? There isn't anywhere in make that honors shell quotes, except
> maybe in some obscure variable substitution modifier.

If you call all of the modifiers obscure, then yes. Every of the
modifiers (e.g. :S, :C, :M, :N, but not :Q) first splits its arguments
according to the rules in devel/bmake/files/str.c:/^brk_string/, which
take quotes into account.

>  > In summary, these things are evaluated at parse time:
>  > 
>  > * .if conditions
>  > * .for loops
>  > * the right-hand side of the != assignment operator
>  > * the right-hand side of the := assignment operator
>  > * variables in dependency lines, like ${TARGETS}: ${SOURCES}
> 
> The last is not quite accurate :-)
> 
> You can write omnibus rules of the form
> 
>    foo.o bar.o baz.o: $(.TARGET:.o=.c)
> 
> and it will evaluate $(.TARGET) in the context of the target it's
> currently considering; this happens at runtime.

Yep, you're right. I totally forgot about the special variables (which
are documented in the man page; look for ".TARGET"). Normal variables
are evaluated at parse time, though.

SOURCES= file1.src
TARGETS= file1.dst

${TARGETS}: ${SOURCES}
        @echo "Making "${.TARGET:Q}" from "${.ALLSRC:Q}"."

SOURCES+= file2.src
TARGETS+= file2.dst

In this example, when file1.src and file2.src exist, you can run "bmake
file1.dst" and "bmake file2.dst" to show that the variables TARGETS and
SOURCES are evaluated at parse time. Their result is:

$ bmake file1.dst
Making file1.dst from file1.src.

$ bmake file2.dst
bmake: don't know how to make file2.dst. Stop

So I admit that it's complicated.

Roland


Home | Main Index | Thread Index | Old Index