Date: Fri, 3 Feb 2012 21:29:15 +0000 From: Chris Rees <crees@freebsd.org> To: "Conrad J. Sabatier" <conrads@cox.net> Cc: freebsd-ports <freebsd-ports@freebsd.org> Subject: Re: BSD make -- Malformed conditional Message-ID: <CADLo83-yPD7t1yMSjjJivUV2HBBpx1MSeB7rzYEgkU1AB_yOew@mail.gmail.com> In-Reply-To: <20120203152010.3b4d0588@cox.net> References: <4F22CB51.6070507@infracaninophile.co.uk> <20120203152010.3b4d0588@cox.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On 3 February 2012 21:20, Conrad J. Sabatier <conrads@cox.net> wrote: > On Fri, 27 Jan 2012 16:05:37 +0000 > Matthew Seaman <m.seaman@infracaninophile.co.uk> wrote: > >> >> Dear all, >> >> Posting this mostly for the archives, but it's probably relevant to >> some people here too. >> >> When hacking on Makefiles, should you wish to match an item in a list, >> you might write something like this: >> >> .for item in ${LIST} >> .if ${item} =3D=3D ${THING} =A0# Ooops! >> THING_FOUND=3D =A01 >> .endif >> .endfor >> >> This however is a snare and a delusion, and will lead to much weeping >> and wailing, and error messages like so: >> >> % make >> "Makefile", line 7: Malformed conditional (foo =3D=3D ${THING}) >> "Makefile", line 9: if-less endif >> "Makefile", line 7: Malformed conditional (bar =3D=3D ${THING}) >> "Makefile", line 9: if-less endif >> "Makefile", line 7: Malformed conditional (baz =3D=3D ${THING}) >> "Makefile", line 9: if-less endif >> "Makefile", line 7: Malformed conditional (blurfl =3D=3D ${THING}) >> "Makefile", line 9: if-less endif >> make: fatal errors encountered -- cannot continue >> >> Instead you should write your loops like this: >> >> .for item in ${LIST} >> .if ${THING} =3D=3D ${item} >> THING_FOUND=3D =A0 =A01 >> .endif >> .endfor >> >> As the make(1) manual page says on the subject of string comparisons >> using =3D=3D or !=3D : >> >> =A0 =A0 =A0An expression may also be a numeric or string comparison: in >> this case, the left-hand side must be a variable expansion, whereas >> the right-hand side can be a constant or a variable expansion. >> >> So it seems that despite appearing and behaving almost exactly like >> one, the iterator in a .for loop is not actually a variable as such. >> It also means that to match a constant string, you can't just write: >> >> .for item in ${LIST} >> .if ${item} =3D=3D "this" =A0# Ooops >> THIS_FOUND=3D1 >> .endif >> .endfor >> >> but have to assign the text "this" to a variable somewhere, and use >> the second form. >> >> Yes, you can use ${LIST:Mthis} instead, but using this construct can >> be a bit tricky in itself... >> >> % cat Makefile >> >> LIST=3D foo bar baz blurfl >> >> THING=3D =A0 =A0 =A0 =A0baz >> >> all: >> =A0 =A0 =A0 @echo "OK =A0 =A0 \$${LIST:Mfoo} =3D ${LIST:Mfoo}" >> =A0 =A0 =A0 @echo "Not OK \$${LIST:M\$${THING}} =3D ${LIST:M${THING}}" >> % make >> OK =A0 =A0 ${LIST:Mfoo} =3D foo >> Not OK ${LIST:M${THING}} =3D } >> >> =A0 =A0 =A0 Cheers, >> >> =A0 =A0 =A0 Matthew >> > > Wow, that is a pretty obscure bit of an oddity, isn't it? =A0How'd you > ever discover that? > > Looking at the man page, it seems more than a little misleading, as it > does call the iterator in .for loops a "variable" (which for all > intents and purposes, I'd say that it is, in fact). =A0One could easily > lose one's marbles trying to "debug" something like this! > > Looks like a bug, smells like a bug to me. =A0Or at least, some *very* > quirky behavior/a serious design flaw that surely wouldn't be missed, > were someone to take the initiative to change it. <hint-hint> =A0No > language should require you to jump through this sort of torturous, > totally anti-intuitive hoop to accomplish what you want to do. =A0Talk > about your POLA! =A0:-) Judging by the sheer volume of Makefiles out there that quite possibly rely on this 'bug' for some things, it's not worth fixing ;) Just think of it as yet another quirk of make. Chris
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CADLo83-yPD7t1yMSjjJivUV2HBBpx1MSeB7rzYEgkU1AB_yOew>