tech-pkg archive

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

Re: make variable expansion oddity



Am 26.05.2016 um 21:08 schrieb Edgar Fuß:
> I don't know whether this is a pkgsrc problem or a make problem.

The problem is on your side of the keyboard. :)

> I've run into strange issues (on 7/amd64, in case that matters) with make 
> apperantly inconsistently expanding variables.
> 
> Case 1:
> 	FOO_UID!=	${ID} -u ${FOO_USER}
> fails because ${ID} is empty (it works with "id" instead of "${ID}".

The right-hand side of the != operator is evaluated at parsing time.
Unless bsd.prefs.mk has been included before, the ID variable is not
defined at that point.

> However make show-var VARNAME=ID gives /usr/bin/id as expected.

The show-var target looks like this:

show-var:
        @echo ${VARNAME}=${${VARNAME}:Q}

The shell commands that are indented with a tab are evaluated lazily,
i.e. at the time of execution.

> 	.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).

> Case 3c:
> SED_SUBST as above and
> 	do-configure:
> 	.for i in <FILES>
> 		${SED} $$(printf -- "-e s,@%s@,%s, " ${SED_SUBSTS}) ${WRKSRC}/${i}.in >${WRKSRC}/${i}
> 	.endfor
> works as expected.

As I said above, lines indented with a tab are evaluated lazily.

> Are these bugs? Am I trying something strage? Is there a better way?

No, these are not bugs. It has been that way for a long time, and this
exact behavior is known to at least some people.

By the way, when you use "pkglint -Wall" for a while, you should stumble
upon warnings like "VARNAME should not be evaluated at load time" or
similar. And if there are no such warnings, blame the pkglint author for
them. ;)

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}

Roland


Home | Main Index | Thread Index | Old Index