Subject: bin/34934: make sometimes fails to handle multiple targets on the left correctly
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <dholland@eecs.harvard.edu>
List: netbsd-bugs
Date: 10/28/2006 22:30:00
>Number: 34934
>Category: bin
>Synopsis: make sometimes fails to handle multiple targets on the left correctly
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Oct 28 22:30:00 +0000 2006
>Originator: David A. Holland
>Release: NetBSD 4.99.3 (20061018)
>Organization:
Moderately organized.
>Environment:
System: NetBSD weatherwax 4.99.3 NetBSD 4.99.3 (WEATHERWAX) #2: Wed Oct 18 18:55:11 EDT 2006 dholland@weatherwax:/usr/src/sys/arch/i386/compile/WEATHERWAX i386
Architecture: i386
Machine: i386
/usr/bin/make:
$NetBSD: crt0.c,v 1.16 2006/05/17 17:08:54 christos Exp $
$NetBSD: arch.c,v 1.52 2006/10/15 08:38:21 dsl Exp $
$NetBSD: buf.c,v 1.19 2005/08/08 16:42:54 christos Exp $
$NetBSD: compat.c,v 1.63 2006/10/15 08:38:21 dsl Exp $
$NetBSD: cond.c,v 1.34 2006/10/15 08:38:21 dsl Exp $
$NetBSD: dir.c,v 1.50 2006/10/15 08:38:21 dsl Exp $
$NetBSD: for.c,v 1.23 2006/10/15 08:38:21 dsl Exp $
$NetBSD: hash.c,v 1.16 2005/08/04 00:20:12 christos Exp $
$NetBSD: job.c,v 1.123 2006/10/15 08:38:21 dsl Exp $
$NetBSD: main.c,v 1.133 2006/10/15 08:38:21 dsl Exp $
$NetBSD: make.c,v 1.66 2006/10/15 08:38:22 dsl Exp $
$NetBSD: parse.c,v 1.118 2006/10/15 21:17:27 dsl Exp $
$NetBSD: str.c,v 1.25 2006/08/11 19:11:00 christos Exp $
$NetBSD: suff.c,v 1.55 2006/10/15 08:38:22 dsl Exp $
$NetBSD: targ.c,v 1.43 2006/10/15 08:38:22 dsl Exp $
$NetBSD: trace.c,v 1.7 2006/01/04 21:35:44 dsl Exp $
$NetBSD: var.c,v 1.114 2006/10/15 08:38:22 dsl Exp $
$NetBSD: util.c,v 1.39 2005/08/08 16:42:54 christos Exp $
$NetBSD: lstAppend.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstAtEnd.c,v 1.11 2005/02/16 15:11:53 christos Exp $
$NetBSD: lstAtFront.c,v 1.11 2005/02/16 15:11:53 christos Exp $
$NetBSD: lstClose.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstConcat.c,v 1.14 2005/08/08 16:42:54 christos Exp $
$NetBSD: lstDatum.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstDeQueue.c,v 1.11 2005/02/16 15:11:53 christos Exp $
$NetBSD: lstDestroy.c,v 1.14 2005/08/09 21:36:42 christos Exp $
$NetBSD: lstDupl.c,v 1.13 2005/08/09 21:36:42 christos Exp $
$NetBSD: lstEnQueue.c,v 1.11 2005/02/16 15:11:53 christos Exp $
$NetBSD: lstFind.c,v 1.12 2005/02/16 15:11:53 christos Exp $
$NetBSD: lstFindFrom.c,v 1.11 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstFirst.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstForEach.c,v 1.11 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstForEachFrom.c,v 1.11 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstInit.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstInsert.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstIsAtEnd.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstIsEmpty.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstLast.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstMember.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstNext.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstOpen.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstRemove.c,v 1.12 2005/08/08 16:42:54 christos Exp $
$NetBSD: lstReplace.c,v 1.10 2004/05/07 00:04:41 ross Exp $
$NetBSD: lstSucc.c,v 1.11 2004/05/07 00:04:41 ross Exp $
>Description:
If you have two (or presumably more) targets on the left hand side of
a rule, and they're files that aren't in the current directory, make
will sometimes fail to detect that they got built together and run the
recipe twice, once "for" each target.
If the recipe is in some way generative, this can result in a broken
build; e.g. if you generate matching .c and .h files and this happens
twice, some parts of a build can end up including one version of the
header file and some the other, which in obscure cases could
conceivably be lethal.
>How-To-Repeat:
Use the included simple example, which has a simple code generator
that generates a source and header file into a subdirectory.
Unpack the example:
tar -xvzf example.tgz
cd example
Compile it:
make
This does
gdir/gen.sh gdir/gen
cc -Igdir -c src.c
cc -Igdir -c gdir/gen.c
cc src.o gen.o -o prog
Note that it runs gen.sh once.
Now, having built it, do this:
touch gdir/gen.sh
make
This causes
gdir/gen.sh gdir/gen
cc -Igdir -c src.c
gdir/gen.sh gdir/gen
cc -Igdir -c gdir/gen.c
cc src.o gen.o -o prog
Note that gen.sh gets run twice and the two source files in the
program are compiled with different copies of gen.h.
I haven't contrived this example so the resulting program breaks
(maybe I should have) but it's clearly not supposed to happen this
way.
Example follows:
begin 644 example.tgz
M'XL(`!K50T4``^U8ST\3012>`@J,)B(G$P\^`9,6PS*[;1=3@0@5B`8TL?'F
M9=D=V(W;W69W40Q!#YR\^0=YTXO_@U<3#QST;H(S^Z,=VB*:T*)QOJ:=>6_>
MSGLSK]^;:>FN46^X%/42A)3('"&LG=/ULL;:&%D;]U52ULA<62O.E9E>U9B,
MRCV-*L5.&!D!`+)LWW4-SSK)[J5-J=N/@/H+FN1_=MMR@E[Y^+/\EWC^BZ2H
MROSW`6+^9[>II_AG[X.HA.@GYU\MM?*OZEK,_Q+//SG[4#KQG^?_S<KZ:BZ7
M:\HY-(ARPOC[M"W%GWF$T3!Z^O;+P>'(P>%EF^N^_C@Z.CKX./;I@TU=U\<(
MK56K%<BO/7I:@*+"7I!_1*/EVGWP-HN@\6K`<EU`2`E?U2-CD[51D+1VU@NH
MJT1T-T**940&4C;#D"G]1##]>IUZT6^O\4:\+H0N"FNY)HP/I>UU]AX5]-\&
M$!IC[4CZ_%#:OY7*@ZG=>IN_;+[;J?UI=B2=;T"P&Q;LLGS<$?H<-<0STFEW
M5?#)L<?>2UWL1)^Q7R:\0\D>#*?QC:6R.-]G9C?>9;YVB/HA]/U('!ML>VKP
MF`<N#[7)%]KDB\T]XKD<9_-=$L9YW(C7,Y-_HD;@>-$64V$>%YOJ"FL'1DX(
M_#]"1_T/[3/WP>O_K\[_HJJUSG]=C^N_QG2R_O<>DS=G-QUO-K3Q)"3IAQD(
M'?Z=@(9KF)1MBT4#V/(#,,#T+<K-:&!$?H"Q:42P"%-[ZKYBP_S\RN-5_,)W
M+&Z2YYW"7<QUHIV9VDTZGNGNL.GFP\AR?,5>;*DF>"3V1-M<L(<!(&%R?B(^
M;)YY$\S%?NSDO'?RWT3&_S`P6:GL#4ZY__'BT.0_*1;C^[]*)/_[@0[.848O
MJ!N.ET\)Q_G'2,9Z`8UV`@\(9]QYQRUQ-LCXOV$\IUM.;_X(.HW_Y9+>.O\U
M+>:_KA')_SZ@]J1:6XB+/S2O@"9^O/PPT?KQI<#'N%I=,$U<75U?6JLMS#S@
MMA@W`G^[`E-Y;E[`HU/Y:K60B3#CP]0]C%NSMAS8%1#NFWA4$)H#[$GNN2*&
MU?20Q,%\'(L:QQ%7(%Y.5^-D!&<U3[%H@WH6QDE;Z?+,Q@:3^"85V`6F:6^Z
MU/"8>5"'F2W@VP!=UPG3;`>G7__%U3+C?[JTGO@X]?S7RRW^EY/__]@/`,G_
H/D"DC/#%[22?.'C>04M(2$A(2$A(2$A(2$A(2/P1?@+?4`\4`"@``-@/
`
end
>Fix:
I don't have time to look into it right now, but I'll put it on my list...
(As a workaround to the broken build problem, one can always run make
repeatedly.)