For Debian Bug #206299:
authorAlexandre Duret-Lutz <adl@gnu.org>
Sun, 24 Aug 2003 22:34:59 +0000 (22:34 +0000)
committerAlexandre Duret-Lutz <adl@gnu.org>
Sun, 24 Aug 2003 22:34:59 +0000 (22:34 +0000)
* automake.in ($configure_deps_greatest_timestamp,
$output_deps_greatest_timestamp): New variables.
(initialize_per_input): Reset $output_deps_greatest_timestamp.
(scan_autoconf_traces, scan_autoconf_files, read_am_file):
Update $configure_deps_greatest_timestamp and
$output_deps_greatest_timestamp
(generate_makefile): Rewrite the logic to decide whether
to rewrite the output.  Move the leading dup_channel_setup
and trailing drop_channel_setup to MAIN, so that
drop_channel_setup is executed for all exit paths.
* tests/aclocal7.test: Update to check for $AUTOMAKE --no-force
* tests/distcom6.test: New file.  Report from Scott James Remnant.
* tests/Makefile.am (TESTS): Add distcom6.test.

ChangeLog
NEWS
THANKS
automake.in
tests/Makefile.am
tests/Makefile.in
tests/aclocal7.test
tests/distcom6.test [new file with mode: 0755]

index 397527e..277e051 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2003-08-24  Alexandre Duret-Lutz  <adl@gnu.org>
 
+       For Debian Bug #206299:
+       * automake.in ($configure_deps_greatest_timestamp,
+       $output_deps_greatest_timestamp): New variables.
+       (initialize_per_input): Reset $output_deps_greatest_timestamp.
+       (scan_autoconf_traces, scan_autoconf_files, read_am_file):
+       Update $configure_deps_greatest_timestamp and
+       $output_deps_greatest_timestamp
+       (generate_makefile): Rewrite the logic to decide whether
+       to rewrite the output.  Move the leading dup_channel_setup
+       and trailing drop_channel_setup to MAIN, so that
+       drop_channel_setup is executed for all exit paths.
+       * tests/aclocal7.test: Update to check for $AUTOMAKE --no-force
+       * tests/distcom6.test: New file.  Report from Scott James Remnant.
+       * tests/Makefile.am (TESTS): Add distcom6.test.
+
        * configure.in: Require Autoconf 2.57b to be sure
        aclocal can use autom4te --language Autoconf-without-aclocal-m4.
        * m4/init.m4: Likewise.  Move the AC_PREREQ and m4_pattern_allow
diff --git a/NEWS b/NEWS
index 98016d2..986a894 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -151,6 +151,9 @@ New in 1.7a:
     the top level Makefile, and passed to sub-directories when running
     `make dist'.
 
+  - The --no-force option now correctly checks the Makefile.in's
+    dependencies before deciding not to update it.
+
 * Miscellaneous
 
   - Targets dist-gzip, dist-bzip2, dist-tarZ, dist-zip are always defined.
diff --git a/THANKS b/THANKS
index 6f89f43..a87f925 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -198,6 +198,7 @@ Rusty Ballinger             rusty@rlyeh.engr.sgi.com
 Ryan T. Sammartino     ryants@shaw.ca
 Sam Hocevar            sam@zoy.org
 Sander Niemeijer       niemeijer@science-and-technology.nl
+Scott James Remnant    scott@netsplit.com
 Sergey Vlasov          vsu@mivlgu.murom.ru
 Seth Alves             alves@hungry.com
 Shuhei Amakawa         sa264@cam.ac.uk
index 5c8dce2..e990051 100755 (executable)
@@ -362,9 +362,12 @@ my $seen_automake_version = 0;
 # generation.
 my %configure_vars = ();
 
-# Files included by @configure.
+# Files included by $configure_ac.
 my @configure_deps = ();
 
+# Greatest timestamp of configure's dependencies.
+my $configure_deps_greatest_timestamp = 0;
+
 # Hash table of AM_CONDITIONAL variables seen in configure.
 my %configure_cond = ();
 
@@ -437,6 +440,10 @@ my $am_relative_dir;
 my $in_file_name;
 my $relative_dir;
 
+# Greatest timestamp of the output's dependencies (excluding
+# configure's dependencies).
+my $output_deps_greatest_timestamp;
+
 # These two variables are used when generating each Makefile.in.
 # They hold the Makefile.in until it is ready to be printed.
 my $output_rules;
@@ -579,6 +586,8 @@ sub initialize_per_input ()
     $in_file_name = '';
     $relative_dir = '';
 
+    $output_deps_greatest_timestamp = 0;
+
     $output_rules = '';
     $output_vars = '';
     $output_trailer = '';
@@ -4376,6 +4385,13 @@ sub scan_autoconf_traces ($)
          # so we skip absolute filenames here.
          push @configure_deps, '$(top_srcdir)/' . $args[1]
            unless $here =~ m,^(?:\w:)?[\\/],;
+         # Keep track of the greatest timestamp.
+         if (-e $args[1])
+           {
+             my $mtime = mtime $args[1];
+             $configure_deps_greatest_timestamp = $mtime
+               if $mtime > $configure_deps_greatest_timestamp;
+           }
        }
    }
 }
@@ -4393,6 +4409,15 @@ sub scan_autoconf_files ()
   # that won't always be the case.
   %libsources = ();
 
+  # Keep track of the youngest configure dependency.
+  $configure_deps_greatest_timestamp = mtime $configure_ac;
+  if (-e 'aclocal.m4')
+    {
+      my $mtime = mtime 'aclocal.m4';
+      $configure_deps_greatest_timestamp = $mtime
+       if $mtime > $configure_deps_greatest_timestamp;
+    }
+
   scan_autoconf_traces ($configure_ac);
 
   # Set input and output files if not specified by user.
@@ -5196,6 +5221,11 @@ sub read_am_file ($$)
     my $am_file = new Automake::XFile ("< $amfile");
     verb "reading $amfile";
 
+    # Keep track of the youngest output dependency.
+    my $mtime = mtime $amfile;
+    $output_deps_greatest_timestamp = $mtime
+      if $mtime > $output_deps_greatest_timestamp;
+
     my $spacing = '';
     my $comment = '';
     my $blank = 0;
@@ -6476,8 +6506,6 @@ sub generate_makefile ($$)
   # Reset all the Makefile.am related variables.
   initialize_per_input;
 
-  # Any warning setting now local to this Makefile.am.
-  dup_channel_setup;
   # AUTOMAKE_OPTIONS can contains -W flags to disable or enable
   # warnings for this file.  So hold any warning issued before
   # we have processed AUTOMAKE_OPTIONS.
@@ -6612,42 +6640,44 @@ sub generate_makefile ($$)
     }
 
   my ($out_file) = $output_directory . '/' . $makefile . ".in";
-  if (! $force_generation && -e $out_file)
-    {
-      my ($am_time) = (stat ($makefile . '.am'))[9];
-      my ($in_time) = (stat ($out_file))[9];
-      # FIXME: should cache these times.
-      my ($conf_time) = (stat ($configure_ac))[9];
-      # FIXME: how to do unsigned comparison?
-      if ($am_time < $in_time || $am_time < $conf_time)
-       {
-         # No need to update.
-         return;
-       }
-      if (-f 'aclocal.m4')
-       {
-         my ($acl_time) = (stat _)[9];
-         return if ($am_time < $acl_time);
-       }
+
+  # We make sure that `all:' is the first target.
+  $output =
+    "$output_vars$output_all$output_header$output_rules$output_trailer";
+
+  # Decide whether we must update the output file or not.
+  # We have to update in the following situations.
+  #  * $force_generation is set.
+  #  * any of the output dependencies is younger than the output
+  #  * the contents of the output is different (this can happen
+  #    if the project has been populated with a file listed in
+  #    @common_files since the last run).
+  # Output's dependencies are split in two sets:
+  #  * dependencies which are also configure dependencies
+  #    These do not change between each Makefile.am
+  #  * other dependencies, specific to the Makefile.am being processed
+  #    (such as the Makefile.am itself, or any Makefile fragment
+  #    it includes).
+  my $timestamp = mtime $out_file;
+  if (! $force_generation
+      && $configure_deps_greatest_timestamp < $timestamp
+      && $output_deps_greatest_timestamp < $timestamp
+      && $output eq contents ($out_file))
+  {
+      verb "$out_file unchanged";
+      # No need to update.
+      return;
     }
 
-  if (-e "$out_file")
+  if (-e $out_file)
     {
       unlink ($out_file)
        or fatal "cannot remove $out_file: $!\n";
     }
-  my $gm_file = new Automake::XFile "> $out_file";
-  verb "creating $makefile.in";
 
-  print $gm_file $output_vars;
-  # We make sure that `all:' is the first target.
-  print $gm_file $output_all;
-  print $gm_file $output_header;
-  print $gm_file $output_rules;
-  print $gm_file $output_trailer;
-
-  # Back out any warning setting.
-  drop_channel_setup;
+  my $gm_file = new Automake::XFile "> $out_file";
+  verb "creating $out_file";
+  print $gm_file $output;
 }
 
 ################################################################
@@ -6893,7 +6923,13 @@ do
        }
       else
        {
+         # Any warning setting now local to this Makefile.am.
+         dup_channel_setup;
+
          generate_makefile ($output_files{$am_file}, $am_file);
+
+         # Back out any warning setting.
+         drop_channel_setup;
        }
     }
   ++$automake_has_run;
index d82deac..a321395 100644 (file)
@@ -170,6 +170,7 @@ distcom2.test \
 distcom3.test \
 distcom4.test \
 distcom5.test \
+distcom6.test \
 distdir.test \
 distname.test \
 dollar.test \
index 18981fa..91c256a 100644 (file)
@@ -279,6 +279,7 @@ distcom2.test \
 distcom3.test \
 distcom4.test \
 distcom5.test \
+distcom6.test \
 distdir.test \
 distname.test \
 dollar.test \
index bc90274..3504452 100755 (executable)
@@ -19,6 +19,7 @@
 # Boston, MA 02111-1307, USA.
 
 # Make sure aclocal does not overwrite aclocal.m4 needlessly.
+# Also make sure automake --no-force does not overwrite Makefile.in needlessly.
 
 . ./defs || exit 1
 
@@ -26,8 +27,19 @@ set -e
 
 cat >> configure.in << 'END'
 SOME_DEFS
+AC_CONFIG_FILES([sub/Makefile])
 END
 
+mkdir sub
+: > sub/Makefile.am
+
+cat >> Makefile.am << 'END'
+SUBDIRS = sub
+include fragment.inc
+END
+
+: > fragment.inc
+
 mkdir m4
 echo 'AC_DEFUN([SOME_DEFS], [])' > m4/somedefs.m4
 
@@ -35,23 +47,73 @@ $sleep
 
 $ACLOCAL -I m4
 
+# Automake will take aclocal.m4 to be newer if it has the same timestamp
+# as Makefile.in.  Avoid the confusing by sleeping.
+$sleep
+
+$AUTOMAKE --no-force
+
 $sleep
 
 touch foo
 $ACLOCAL -I m4
+$AUTOMAKE --no-force
 
-# aclocal.m4 should not have been updated, so `foo' should be younger
-test `ls -1t aclocal.m4 foo | sed 1q` = foo
+# aclocal.m4 and Makefile.in should not have been updated, so `foo'
+# should be younger
+test `ls -1t aclocal.m4 Makefile.in sub/Makefile.in foo | sed 1q` = foo
 
 $sleep
 $ACLOCAL -I m4 --force
 test `ls -1t aclocal.m4 foo | sed 1q` = aclocal.m4
+# We still use --no-force for automake, but since aclocal.m4 has
+# changed all Makefile.ins should be updated.
+$sleep
+$AUTOMAKE --no-force
+test `ls -1t Makefile.in foo | sed 1q` = Makefile.in
+test `ls -1t sub/Makefile.in foo | sed 1q` = sub/Makefile.in
 
 touch m4/somedefs.m4
 $sleep
 touch foo
 $sleep
 $ACLOCAL -I m4
+$sleep
+$AUTOMAKE --no-force
 
 # aclocal.m4 should have been updated, although its contents haven't changed.
 test `ls -1t aclocal.m4 foo | sed 1q` = aclocal.m4
+test `ls -1t Makefile.in foo | sed 1q` = Makefile.in
+test `ls -1t sub/Makefile.in foo | sed 1q` = sub/Makefile.in
+
+touch fragment.inc
+$sleep
+touch foo
+$ACLOCAL -I m4
+$AUTOMAKE --no-force
+# Only ./Makefile.in should change.
+test `ls -1t aclocal.m4 foo | sed 1q` = foo
+test `ls -1t Makefile.in foo | sed 1q` = Makefile.in
+test `ls -1t sub/Makefile.in foo | sed 1q` = foo
+
+grep README Makefile.in && exit 1
+
+: > README
+$sleep
+touch foo
+$AUTOMAKE --no-force
+# Even if no dependency change, the content changed.
+test `ls -1t Makefile.in foo | sed 1q` = Makefile.in
+test `ls -1t sub/Makefile.in foo | sed 1q` = foo
+
+grep README Makefile.in
+
+: > sub/Makefile.in
+$sleep
+touch foo
+$ACLOCAL -I m4
+$AUTOMAKE --no-force
+# Only sub/Makefile.in should change.
+test `ls -1t aclocal.m4 foo | sed 1q` = foo
+test `ls -1t Makefile.in foo | sed 1q` = foo
+test `ls -1t sub/Makefile.in foo | sed 1q` = sub/Makefile.in
diff --git a/tests/distcom6.test b/tests/distcom6.test
new file mode 100755 (executable)
index 0000000..88c3e86
--- /dev/null
@@ -0,0 +1,74 @@
+#! /bin/sh
+# Copyright (C) 2003  Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Automake is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Automake; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Test to make sure that depcomp and compile required in subdirectories
+# are added to the top-level DIST_COMMON even with --no-force.
+# This is similar to distcom2.test, but with --no-force added.
+# Report from Scott James Remnant (Debian #206299).
+
+. ./defs || exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+AC_PROG_CC
+AC_CONFIG_FILES([subdir/Makefile])
+AC_OUTPUT
+END
+
+cat > Makefile.am << 'END'
+SUBDIRS = subdir
+END
+
+mkdir subdir
+: > subdir/foo.c
+
+cat > subdir/Makefile.am << 'END'
+noinst_PROGRAMS = foo
+foo_SOURCES = foo.c
+foo_CFLAGS = -DBAR
+END
+
+rm -f compile depcomp
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE --add-missing --no-force
+
+test -f compile
+test -f depcomp
+
+sed -n -e '/^DIST_COMMON =.*\\$/ {
+   :loop
+   p
+   n
+   /\\$/ b loop
+   p
+   n
+   }' -e '/^DIST_COMMON =/ p' Makefile.in | grep compile
+
+sed -n -e '/^DIST_COMMON =.*\\$/ {
+   :loop
+   p
+   n
+   /\\$/ b loop
+   p
+   n
+   }' -e '/^DIST_COMMON =/ p' Makefile.in | grep depcomp