bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: make handling of prerequisites that interlock?


From: Boris Kolpackov
Subject: Re: make handling of prerequisites that interlock?
Date: Wed, 6 Apr 2005 08:59:52 +0000 (UTC)
User-agent: nn/6.6.5+RFC1522

Ben Pfaff <address@hidden> writes:

>  Prerequisite `c' is newer than target `a'.       <---- 1
>  Prerequisite `b' is newer than target `a'.       <---- 2
> No need to remake target `a'.                     <---- 3

I simplified your makefile a bit:

a: b
        cat $^ >$@

b: x
        cat $^ >$@

clean:
        rm -f a b

Here is a typical command sequence when run in a loop you provided:

cat x >b    # timestamp(b) = 1
cat b >a    # timestamp(a) = 2
echo x >x   # timestamp(x) = 2
cat x >b    # timestamp(b) = 2

Here is what happens: the first line updates file `b' with timestamp = 1.
On line 2 timestamp(a) becomes 2 (assuming timestamp(a) < 1 before
line 2). Now the third line updates `x' which also happened to have its
timestamp = 2. Now `x' is older than `b' so `b' is updated on line 4
with timestamp = 2. In other words three last lines executed fast enough
to end up with the same timestamp. Now even though `b' changed, its
timestamp is no older than `a'. So GNU make decides there is no need to
remake `a'.

The code in GNU make that decides whether to print "Prerequisite `c'
is newer than target `a'" assumes that the two consecutive modifications
to two different files will result in two different timestamps. However
it is not always the case: sometimes they end up having equal timestamps.
So I would say there is a bug in that logic.

To find out all this I had to instrument make a bit. Below is the output
that illustrates the situation I described above:

GNU Make 3.81beta3
Copyright (C) 2003  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i686-pc-linux-gnu
Reading makefiles...
Reading makefile `makefile'...
Updating makefiles....
 Considering target file `makefile'.
: tgt makefile mtime: 1194845150682021891
  Looking for an implicit rule for `makefile'.
  No implicit rule found for `makefile'.
: tgt makefile; must_make: 0
  Finished prerequisites of target file `makefile'.
 No need to remake target `makefile'.
Updating goal targets....
Considering target file `a'.
: tgt a mtime: 1194847602034606083
  Considering target file `b'.
: tgt b mtime: 1194847600960864259
    Considering target file `x'.
: tgt x mtime: 1194847602034606083
     Looking for an implicit rule for `x'.
     No implicit rule found for `x'.
: tgt x; must_make: 0
     Finished prerequisites of target file `x'.
    No need to remake target `x'.
: check_dep x; this-mtime: 1194847600960864259; new-mtime: 1194847602034606083
: dep x; maybe_make: 1
: dep x changed: 0; old-mtime: 1194847602034606083; new-mtime: 
1194847602034606083
: tgt b; must_make: 1
   Finished prerequisites of target file `b'.
   Prerequisite `x' is newer than target `b'.
  Must remake target `b'.
cat x >b
Putting child 0x08071518 (b) PID 335 on the chain.
Live child 0x08071518 (b) PID 335
Reaping winning child 0x08071518 PID 335
Removing child 0x08071518 PID 335 from chain.
  Successfully remade target file `b'.
: check_dep b; this-mtime: 1194847602034606083; new-mtime: 1194847602034606083
: dep b; maybe_make: 0
: dep b changed: 1; old-mtime: 1194847600960864259; new-mtime: 
1194847602034606083
: tgt a; must_make: 0
 Finished prerequisites of target file `a'.
 Prerequisite `b' is newer than target `a'.
No need to remake target `a'.


-boris




reply via email to

[Prev in Thread] Current Thread [Next in Thread]