NetBSD Problem Report #34934

From dholland@eecs.harvard.edu  Sat Oct 28 22:26:18 2006
Return-Path: <dholland@eecs.harvard.edu>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id A5D6963B8CA
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 28 Oct 2006 22:26:18 +0000 (UTC)
Message-Id: <20061028222519.038085426@weatherwax.eecs.harvard.edu>
Date: Sat, 28 Oct 2006 18:25:18 -0400 (EDT)
From: dholland@eecs.harvard.edu
Reply-To: dholland@eecs.harvard.edu
To: gnats-bugs@NetBSD.org
Subject: make sometimes fails to handle multiple targets on the left correctly
X-Send-Pr-Version: 3.95

>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
>Last-Modified:  Sun Oct 29 18:35:01 +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.)

>Audit-Trail:
From: David Laight <david@l8s.co.uk>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/34934: make sometimes fails to handle multiple targets on the left correctly
Date: Sun, 29 Oct 2006 07:18:35 +0000

 On Sat, Oct 28, 2006 at 10:30:00PM +0000, dholland@eecs.harvard.edu wrote:
 > >Number:         34934
 > >Category:       bin
 > >Synopsis:       make sometimes fails to handle multiple targets on the left correctly
 ...
 > >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 you have:

 a1 a1: b
 	echo $@

 The make runs the rules twice, once for a1 and once for a2.
 This is the correct and required behaviour.
 (Otherwise the above could't output 'a1' and 'a2'.)

 If you have something that generates two files then you have to
 do something else (eg have one of the files depend on the other one).

 	David

 -- 
 David Laight: david@l8s.co.uk

From: dholland@eecs.harvard.edu (David Holland)
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org,
	dholland@eecs.harvard.edu
Subject: Re: bin/34934: make sometimes fails to handle multiple targets on the left correctly
Date: Sun, 29 Oct 2006 13:29:39 -0500 (EST)

  >  If you have:
  >  
  >  a1 a1: b
         ^2
  >  	echo $@
  >  
  >  The make runs the rules twice, once for a1 and once for a2.
  >  This is the correct and required behaviour.
  >  (Otherwise the above could't output 'a1' and 'a2'.)

 Yes.

 It's not a matter of what the rules mean; it's a matter of when
 timestamps can and cannot be cached. If you have

 a1 a2: b
 	echo foo > a1; echo bar > a2

 then after running the recipe make is required to check and ascertain
 that both a1 and a2 have been updated. Then it won't run the recipe a
 second time. Whereas if you don't list both a1 and a2 on the left make
 is allowed to assume that the one not listed isn't modified, and this
 can cause things to go wrong later. (Lying to make rarely goes
 unpunished.)

 You'll note that make does actually do this; the problem is that
 something breaks some of the time if a1 and a2 are in another
 directory.

 -- 
    - David A. Holland / dholland@eecs.harvard.edu

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.