Skip site navigation (1)Skip section navigation (2)
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>