* lib/Automake/General.pm (contents): New function.
authorAlexandre Duret-Lutz <adl@gnu.org>
Tue, 6 May 2003 12:07:22 +0000 (12:07 +0000)
committerAlexandre Duret-Lutz <adl@gnu.org>
Tue, 6 May 2003 12:07:22 +0000 (12:07 +0000)
* aclocal.in (greatest_mtime, force_output): New globals.
(scan_configure, add_file): Update $greatest_mtime.
(parse_arguments): Parse --force.
(write_aclocal): Do not overwrite $output_file unless needed.
* automake.texi (aclocal options): Document --force.
* tests/aclocal7.test: New file.
* tests/Makefile.am (TESTS): Add aclocal7.test.

ChangeLog
NEWS
aclocal.in
automake.texi
lib/Automake/General.pm
tests/Makefile.am
tests/Makefile.in
tests/aclocal7.test [new file with mode: 0755]

index ac518e4..edb45b4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2003-05-06  Alexandre Duret-Lutz  <adl@gnu.org>
+
+       * lib/Automake/General.pm (contents): New function.
+       * aclocal.in (greatest_mtime, force_output): New globals.
+       (scan_configure, add_file): Update $greatest_mtime.
+       (parse_arguments): Parse --force.
+       (write_aclocal): Do not overwrite $output_file unless needed.
+       * automake.texi (aclocal options): Document --force.
+       * tests/aclocal7.test: New file.
+       * tests/Makefile.am (TESTS): Add aclocal7.test.
+
 2003-05-05  Alexandre Duret-Lutz  <adl@gnu.org>
 
        * automake.texi (Optional): Document m4_include.
diff --git a/NEWS b/NEWS
index 3329581..18de252 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -117,6 +117,10 @@ New in 1.7a:
   older versions of Automake; this variable should be considered obsolete
   and will be flagged as such when running `automake -Wobsolete'.
 
+* aclocal will avoid touching aclocal.m4 when possible, so that
+  Autom4te's cache isn't needlessly invalidated.  This behavior can
+  be switched off with the new `--force' option.
+
 \f
 New in 1.7:
 * Autoconf 2.54 is required.
index 1f73856..d7307a1 100644 (file)
@@ -35,6 +35,7 @@ BEGIN
 
 use Automake::General;
 use Automake::XFile;
+use File::stat;
 
 # Some constants.
 $VERSION = '@VERSION@';
@@ -64,6 +65,12 @@ $output = '';
 # Output file name.
 $output_file = 'aclocal.m4';
 
+# Modification time of the youngest dependency.
+$greatest_mtime = 0;
+
+# Option --force.
+$force_output = 0;
+
 # Which macros have been seen.
 %macro_seen = ();
 
@@ -118,6 +125,7 @@ Generate `aclocal.m4' by scanning `configure.ac' or `configure.in'
   --acdir=DIR           directory holding config files
   --help                print this help, then exit
   -I DIR                add directory to search list for .m4 files
+  --force               always update output file
   --output=FILE         put output in FILE (default aclocal.m4)
   --print-ac-dir        print name of directory holding m4 files
   --verbose             don't be silent
@@ -154,6 +162,10 @@ sub parse_arguments (@)
        {
            $print_and_exit = 1;
        }
+       elsif ($arglist[0] eq '--force')
+       {
+           $force_output = 1;
+       }
        elsif ($arglist[0] eq '--verbose')
        {
            ++$verbose;
@@ -232,6 +244,9 @@ sub scan_configure ()
     open (CONFIGURE, $configure_ac)
        || die "aclocal: couldn't open `$configure_ac': $!\n";
 
+    my $mtime = mtime $configure_ac;
+    $greatest_mtime = $mtime if $greatest_mtime < $mtime;
+
     # Make sure we include acinclude.m4 if it exists.
     if (-f 'acinclude.m4')
     {
@@ -357,6 +372,9 @@ sub add_file ($)
     return if ($file_seen{$file});
     $file_seen{$file} = 1;
 
+    my $mtime = mtime $file;
+    $greatest_mtime = $mtime if $greatest_mtime < $mtime;
+
     # If the file to add looks like path outside the project,
     # copy it to the output.
     # The regex catches filenames starting with things like
@@ -440,20 +458,17 @@ sub scan_file ($)
 # Write output.
 sub write_aclocal ()
 {
+    # Nothing to output?!
+    # FIXME: Shouldn't we diagnose this?
     return if ! length ($output);
 
-    print STDERR "aclocal: writing $output_file\n" if $verbose;
-
-    my $out = new Automake::XFile "> $output_file";
-
 # We used to print `# $output_file generated automatically etc.'  But
 # this creates spurious differences when using autoreconf.  Autoreconf
 # creates aclocal.m4t and then rename it to aclocal.m4, but the
 # rebuild rules generated by Automake create aclocal.m4 directly --
 # this would gives two ways to get the same file, with a different
 # name in the header.
-    print $out
-"# generated automatically by aclocal $VERSION -*- Autoconf -*-
+    $output = "# generated automatically by aclocal $VERSION -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
 # Free Software Foundation, Inc.
@@ -467,6 +482,30 @@ sub write_aclocal ()
 # PARTICULAR PURPOSE.
 
 $output";
+
+    # We try not to update $output_file unless necessary, because
+    # doing so invalidate Autom4te's cache and therefore slows down
+    # tools called after aclocal.
+    #
+    # We need to overwrite $output_file in the following situations.
+    #   * The --force option is in use.
+    #   * One of the dependencies is younger.
+    #     (Not updating $output_file in this situation would cause
+    #     make to call aclocal in loop.)
+    #   * The contents of the current file are different from what
+    #     we have computed.
+    if (!$force_output
+       && $greatest_mtime < mtime ($output_file)
+       && $output eq contents ($output_file))
+      {
+       print STDERR "aclocal: $output_file unchanged\n" if $verbose;
+       return;
+      }
+
+    print STDERR "aclocal: writing $output_file\n" if $verbose;
+
+    my $out = new Automake::XFile "> $output_file";
+    print $out $output;
 }
 
 ### Setup "GNU" style for perl-mode and cperl-mode.
index 947e929..0b5d7c3 100644 (file)
@@ -1392,6 +1392,12 @@ Print a summary of the command line options and exit.
 Add the directory @var{dir} to the list of directories searched for
 @file{.m4} files.
 
+@item --force
+@opindex --force
+Always overwrite the output file.  The default is to overwrite the output
+file only when really needed, i.e., when its contents changes or if one
+of its dependencies is younger.
+
 @item --output=@var{file}
 @opindex --output
 Cause the output to be put into @var{file} instead of @file{aclocal.m4}.
index 2bd7a49..fe8915b 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright 2001 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003  Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@ use vars qw (@ISA @EXPORT);
 
 @ISA = qw (Exporter);
 @EXPORT = qw (&debug &find_configure_ac &find_file &getopt &mktmpdir &mtime
-              &uniq &update_file &verbose &xsystem
+              &uniq &update_file &verbose &xsystem &contents
              $debug $help $me $tmp $verbose $version);
 
 # Variable we share with the main package.  Be sure to have a single
@@ -331,4 +331,36 @@ sub xsystem ($)
 }
 
 
+# contents ($FILENAME)
+# --------------------
+# Swallow the contents of file $FILENAME.
+sub contents ($)
+{
+  my ($file) = @_;
+  print STDERR "$me: reading $file\n" if $verbose;
+  local $/;                    # Turn on slurp-mode.
+  my $f = new Automake::XFile "< $file";
+  my $contents = $f->getline;
+  $f->close;
+  return $contents;
+}
+
+
 1; # for require
+
+### Setup "GNU" style for perl-mode and cperl-mode.
+## Local Variables:
+## perl-indent-level: 2
+## perl-continued-statement-offset: 2
+## perl-continued-brace-offset: 0
+## perl-brace-offset: 0
+## perl-brace-imaginary-offset: 0
+## perl-label-offset: -2
+## cperl-indent-level: 2
+## cperl-brace-offset: 0
+## cperl-continued-brace-offset: 0
+## cperl-label-offset: -2
+## cperl-extra-newline-before-brace: t
+## cperl-merge-trailing-else: nil
+## cperl-continued-statement-offset: 2
+## End:
index 379ab7a..f85f4e2 100644 (file)
@@ -9,6 +9,7 @@ aclocal3.test \
 aclocal4.test \
 aclocal5.test \
 aclocal6.test \
+aclocal7.test \
 acoutnoq.test \
 acoutpt.test \
 acoutpt2.test \
index 794d46d..13bfa45 100644 (file)
@@ -120,6 +120,7 @@ aclocal3.test \
 aclocal4.test \
 aclocal5.test \
 aclocal6.test \
+aclocal7.test \
 acoutnoq.test \
 acoutpt.test \
 acoutpt2.test \
diff --git a/tests/aclocal7.test b/tests/aclocal7.test
new file mode 100755 (executable)
index 0000000..bc90274
--- /dev/null
@@ -0,0 +1,57 @@
+#! /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.
+
+# Make sure aclocal does not overwrite aclocal.m4 needlessly.
+
+. ./defs || exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+SOME_DEFS
+END
+
+mkdir m4
+echo 'AC_DEFUN([SOME_DEFS], [])' > m4/somedefs.m4
+
+$sleep
+
+$ACLOCAL -I m4
+
+$sleep
+
+touch foo
+$ACLOCAL -I m4
+
+# aclocal.m4 should not have been updated, so `foo' should be younger
+test `ls -1t aclocal.m4 foo | sed 1q` = foo
+
+$sleep
+$ACLOCAL -I m4 --force
+test `ls -1t aclocal.m4 foo | sed 1q` = aclocal.m4
+
+touch m4/somedefs.m4
+$sleep
+touch foo
+$sleep
+$ACLOCAL -I m4
+
+# aclocal.m4 should have been updated, although its contents haven't changed.
+test `ls -1t aclocal.m4 foo | sed 1q` = aclocal.m4