bug-make
[Top][All Lists]
Advanced

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

Bug in `make -t` (was: GNU make suggestion: did the dependency really ch


From: Henning Makholm
Subject: Bug in `make -t` (was: GNU make suggestion: did the dependency really change?)
Date: 03 Nov 2001 03:18:12 +0100

Scripsit "Paul D. Smith" <address@hidden>
> %% Henning Makholm <address@hidden> writes:

>   hm> By the way, it is not *every* make that behaves this way. At least
>   hm> /usr/ccs/bin/make on SunOS 5.7 doesn't.

> Yes it does.

Mea culpa - apparently I didn't think too well during the experiment on
the Sun box so I thought I'd created a no-op command by

  fil2: fil3 ; : echo foo > fil2

> I'm not sure about -t, but -n definitely had some very long-standing
> bugs that were finally noticed and fixed.  Try a newer version of GNU
> make (the latest is 3.79.1).

Easy enough - on further investigation it turns out that the RedHat
machine I'm using has 3.77 as /usr/bin/make by way of RedHat, but our
local sysadmins have installed 3.79.1 as gmake somewhere in the path.

`make -n` now behaves as expected, but the `make -t` bug is still there:

  $ cat Makefile
  a: b ; @echo cp $< $@
  b: c ; @echo "should change b--but don't"
  $ touch b && sleep 1 && touch a && sleep 1 && touch c
  $ gmake -t
  touch b
  gmake: `a' is up to date.
  $ gmake
  cp b a
  $ gmake -v     
  GNU Make version 3.79.1, by Richard Stallman and Roland McGrath.
  Built for i686-pc-linux-gnu
  Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
          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.

  Report bugs to <address@hidden>.

  $ 

Reiterating from my earlier email, just to make this a self-contained
bug report: `make -t` is supposed to touch enough files that after it
completes none of the specified targets are out-of-date. In the above
example, a becomes out-of-date when b is touched, yet a does not get
touched itself.


The following patch ought to fix this bug, and adds a suitable
test case to the test suite.

diff -urN make-3.79.1.original/remake.c make-3.79.1/remake.c
--- make-3.79.1.original/remake.c       Tue Jun 20 16:00:17 2000
+++ make-3.79.1/remake.c        Sat Nov  3 03:15:19 2001
@@ -696,6 +696,7 @@
 {
   struct dep *d;
   int ran = file->command_state == cs_running;
+  int touched = 0 ;
 
   file->command_state = cs_finished;
   file->updated = 1;
@@ -724,24 +725,34 @@
          if (file->phony)
            file->update_status = 0;
          else
-           /* Should set file's modification date and do nothing else.  */
-           file->update_status = touch_file (file);
+            {
+             /* Should set file's modification date and do nothing else.  */
+             file->update_status = touch_file (file);
+              /* Pretend we ran a real touch command, to suppress the
+                 "`foo' is up to date" message.  */
+              commands_started++ ;
+              /* Request for the timestamp to be updated (and distributed
+                 to the double-colon entries). Simply setting ran=1 would
+                 almost have done the trick, but messes up with the also_make
+                 updating logic below.  */
+              touched = 1 ;
+            }
        }
     }
 
   if (file->mtime_before_update == UNKNOWN_MTIME)
     file->mtime_before_update = file->last_mtime;
 
-  if (ran && !file->phony)
+  if (ran && !file->phony || touched)
     {
       struct file *f;
       int i = 0;
 
-      /* If -n or -q and all the commands are recursive, we ran them so
+      /* If -n or -t or -q and all the commands are recursive, we ran them so
          really check the target's mtime again.  Otherwise, assume the target
          would have been updated. */
 
-      if (question_flag || just_print_flag)
+      if (question_flag || just_print_flag || touch_flag)
         {
           for (i = file->cmds->ncommand_lines; i > 0; --i)
             if (! (file->cmds->lines_flags[i-1] & COMMANDS_RECURSE))
diff -urN make-3.79.1.original/tests/scripts/options/dash-t 
make-3.79.1/tests/scripts/options/dash-t
--- make-3.79.1.original/tests/scripts/options/dash-t   Thu Jan  1 01:00:00 1970
+++ make-3.79.1/tests/scripts/options/dash-t    Sat Nov  3 02:32:57 2001
@@ -0,0 +1,40 @@
+#                                                                    -*-perl-*-
+$description = "Test the -t option.\n";
+
+$details = "Look out for regressions of prior bugs related to -t.\n";
+# That means, nobody has even tried to make the tests below comprehensive
+
+# TEST 0
+# bug reported by Henning Makholm <address@hidden> on 2001-11-03:
+#   make 3.79.1 touches only interm-[ab] but reports final-[a] as
+#   'up to date' without touching them.
+# The 'obvious' fix didn't work for double-colon rules, so pay special
+# attention to them.
+
+open(MAKEFILE, "> $makefile");
+print MAKEFILE <<'EOMAKE';
+final-a: interm-a ; echo >> $@
+final-b: interm-b ; echo >> $@
+interm-a:: orig1-a ; echo >> $@
+interm-a:: orig2-a ; echo >> $@
+interm-b:: orig1-b ; echo >> $@
+interm-b:: orig2-b ; echo >> $@
+EOMAKE
+close(MAKEFILE);
+
+&touch('orig1-a','orig2-b');
+sleep(1);
+&touch('interm-a','interm-b');
+sleep(1);
+&touch('final-a','final-b');
+sleep(1);
+&touch('orig2-a','orig1-b');
+
+&run_make_with_options($makefile, "-t final-a final-b", &get_logfile);
+$answer = "touch interm-a\ntouch final-a\ntouch interm-b\ntouch final-b\n";
+&compare_output($answer, &get_logfile(1));
+
+unlink('orig1-a', 'orig2-a', 'interm-a', 'final-a');
+unlink('orig1-b', 'orig2-b', 'interm-b', 'final-b');
+
+1;

-- 
Henning Makholm                             "We're trying to get it into the
                                parts per billion range, but no luck still."



reply via email to

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