From owner-freebsd-ports@FreeBSD.ORG Fri Feb 3 21:20:18 2012 Return-Path: Delivered-To: freebsd-ports@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 730DD106566C for ; Fri, 3 Feb 2012 21:20:18 +0000 (UTC) (envelope-from conrads@cox.net) Received: from eastrmfepo203.cox.net (eastrmfepo203.cox.net [68.230.241.218]) by mx1.freebsd.org (Postfix) with ESMTP id 175698FC0A for ; Fri, 3 Feb 2012 21:20:17 +0000 (UTC) Received: from eastrmimpo306.cox.net ([68.230.241.238]) by eastrmfepo203.cox.net (InterMail vM.8.01.04.00 201-2260-137-20101110) with ESMTP id <20120203212017.TTCB25070.eastrmfepo203.cox.net@eastrmimpo306.cox.net>; Fri, 3 Feb 2012 16:20:17 -0500 Received: from serene.no-ip.org ([98.164.86.55]) by eastrmimpo306.cox.net with bizsmtp id VZLG1i00c1BeFqy02ZLHTf; Fri, 03 Feb 2012 16:20:17 -0500 X-CT-Class: Clean X-CT-Score: 0.00 X-CT-RefID: str=0001.0A02020A.4F2C4F91.006C,ss=1,re=0.000,fgs=0 X-CT-Spam: 0 X-Authority-Analysis: v=1.1 cv=QFd1i8EmGWXMF/FLlwwalaY9IE87M3wXCJnHJtyYFmw= c=1 sm=1 a=Al37l13H2jYA:10 a=G8Uczd0VNMoA:10 a=kj9zAlcOel0A:10 a=fdHYxQQoAueMHNSmXppgDg==:17 a=WF2pI21SAAAA:8 a=kviXuzpPAAAA:8 a=tYDRtNEjE4q66eYXijsA:9 a=Lf5zsbd0aWdM54dk3iQA:7 a=CjuIK1q_8ugA:10 a=MHmzl5aOqcYA:10 a=4vB-4DCPJfMA:10 a=JuTL1bGNGZqNlOne:21 a=o9YfQMN6Drf7zbK2:21 a=fdHYxQQoAueMHNSmXppgDg==:117 X-CM-Score: 0.00 Authentication-Results: cox.net; none Received: from cox.net (localhost [127.0.0.1]) by serene.no-ip.org (8.14.5/8.14.5) with ESMTP id q13LKFtg086941; Fri, 3 Feb 2012 15:20:16 -0600 (CST) (envelope-from conrads@cox.net) Date: Fri, 3 Feb 2012 15:20:10 -0600 From: "Conrad J. Sabatier" To: Matthew Seaman Message-ID: <20120203152010.3b4d0588@cox.net> In-Reply-To: <4F22CB51.6070507@infracaninophile.co.uk> References: <4F22CB51.6070507@infracaninophile.co.uk> X-Mailer: Claws Mail 3.8.0 (GTK+ 2.24.6; amd64-portbld-freebsd10.0) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: freebsd-ports Subject: Re: BSD make -- Malformed conditional X-BeenThere: freebsd-ports@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting software to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 03 Feb 2012 21:20:18 -0000 On Fri, 27 Jan 2012 16:05:37 +0000 Matthew Seaman 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} == ${THING} # Ooops! > THING_FOUND= 1 > .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 == ${THING}) > "Makefile", line 9: if-less endif > "Makefile", line 7: Malformed conditional (bar == ${THING}) > "Makefile", line 9: if-less endif > "Makefile", line 7: Malformed conditional (baz == ${THING}) > "Makefile", line 9: if-less endif > "Makefile", line 7: Malformed conditional (blurfl == ${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} == ${item} > THING_FOUND= 1 > .endif > .endfor > > As the make(1) manual page says on the subject of string comparisons > using == or != : > > An 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} == "this" # Ooops > THIS_FOUND=1 > .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= foo bar baz blurfl > > THING= baz > > all: > @echo "OK \$${LIST:Mfoo} = ${LIST:Mfoo}" > @echo "Not OK \$${LIST:M\$${THING}} = ${LIST:M${THING}}" > % make > OK ${LIST:Mfoo} = foo > Not OK ${LIST:M${THING}} = } > > Cheers, > > Matthew > Wow, that is a pretty obscure bit of an oddity, isn't it? How'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). One could easily lose one's marbles trying to "debug" something like this! Looks like a bug, smells like a bug to me. Or 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. No language should require you to jump through this sort of torturous, totally anti-intuitive hoop to accomplish what you want to do. Talk about your POLA! :-) -- Conrad J. Sabatier conrads@cox.net