Re: Make's empty(), defined() and .ifdef don't catch outer .for iterators

Roland Illig <[email protected]> Wed, 8 Jul 2026 07:57:12 +0200
Newsgroups gmane.os.netbsd.devel.userlevel
Message-ID <[email protected]>
------=_Part_12_89055496.1783490232277
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Am 08.07.2026 03:22:35 schrieb Kogule Ryo :

> Hi forks,
>
> Make's empty() does not catch outer .for iterators.
>
>> .for i in yes no
>> .=C2=A0 if !empty(i:M[Yy][Ee][Ss])
>> output+=3D=C2=A0=C2=A0=C2=A0 yes
>> .=C2=A0 endif
>> .endfor
>
> defined() and .ifdef do the same.=C2=A0 Is this behavior intentional?

Is rather say accepted than intended. It is a consequence of how the .for l=
oops are implemented. When evaluating a .for loop, text that looks like an =
expression of the form ${i:=E2=80=A6} is expanded textually before processi=
ng the lines of the body of the .for loop.

This limitation is not documented in the manual page, though. It would even=
 be possible to fix it by creating temporary variables during iteration. Up=
 to now, the pressure to do this was not high enough to get this edge case =
fixed.

The usual workaround is to write this instead:

.if ${i:M[Yy][Ee][Ss]}

Or, even shorter:

.if ${i:tl} =3D=3D "yes"

See usr.bin/make/unit-tests/directive-for-empty.mk for a more detailed expl=
anation.

Roland

------=_Part_12_89055496.1783490232277--