From: Alexandre Duret-Lutz Date: Fri, 2 Jan 2004 14:53:48 +0000 (+0000) Subject: * aclocal.in (%file_includes): New variable. X-Git-Tag: Release-1-8b~112 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=91f9239ba9a67f788ced307652017b463a0f41dd;p=automake.git * aclocal.in (%file_includes): New variable. (scan_configure_dep): Compile $m4_include_rx and $ac_require_rx once. (scan_file): Scan for included files, and process these files recursively. Fill %file_includes and %file_contents. Return the list of included files, not the contents. (scan_m4_files): Adjust calls to scan_files. (strip_redundant_includes): New function. (trace_used_macros): Call it. (write_aclocal): Likewise. Also check the mtime of included files. * tests/Makfile.am (TESTS): Add acloca14.test. * tests/acloca14.test: New file. Report from Phil Edwards. --- diff --git a/ChangeLog b/ChangeLog index 2ea6f49e..2df55d9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-01-02 Alexandre Duret-Lutz + + * aclocal.in (%file_includes): New variable. + (scan_configure_dep): Compile $m4_include_rx and $ac_require_rx once. + (scan_file): Scan for included files, and process these files + recursively. Fill %file_includes and %file_contents. Return the + list of included files, not the contents. + (scan_m4_files): Adjust calls to scan_files. + (strip_redundant_includes): New function. + (trace_used_macros): Call it. + (write_aclocal): Likewise. Also check the mtime of included files. + * tests/Makfile.am (TESTS): Add acloca14.test. + * tests/acloca14.test: New file. + Report from Phil Edwards. + 2004-01-01 Alexandre Duret-Lutz * automake.in (handle_languages): Do not define DEP_FILES. diff --git a/THANKS b/THANKS index 4e2b87d3..8be67c6f 100644 --- a/THANKS +++ b/THANKS @@ -185,6 +185,7 @@ Peter Gavin pgavin@debaser.kicks-ass.org Peter Mattis petm@scam.XCF.Berkeley.EDU Peter Muir iyhi@yahoo.com Petter Reinholdtsen pere@hungry.com +Phil Edwards phil@jaj.com Phil Nelson phil@cs.wwu.edu Philip Fong pwlfong@users.sourceforge.net Philip S Tellis philip@ncst.ernet.in diff --git a/aclocal.in b/aclocal.in index 8f328bd1..c5541ab3 100644 --- a/aclocal.in +++ b/aclocal.in @@ -74,6 +74,8 @@ $force_output = 0; # Remember the order into which we scanned the files. # It's important to output the contents of aclocal.m4 in the opposite order. +# (Definitions in first files we have scanned should override those from +# later files. So they must appear last in the output.) @file_order = (); # Map macro names to file names. @@ -82,6 +84,9 @@ $force_output = 0; # Map file names to file contents. %file_contents = (); +# Map file names to included files (transitively closed). +%file_includes = (); + # How much to say. $verbose = 0; @@ -125,7 +130,7 @@ sub scan_m4_files (@) # First, scan acinclude.m4 if it exists. if (-f 'acinclude.m4') { - $file_contents{'acinclude.m4'} = &scan_file ('acinclude.m4'); + &scan_file ('acinclude.m4'); } local ($m4dir); @@ -149,7 +154,7 @@ sub scan_m4_files (@) next if $file eq 'aclocal.m4'; $fullfile = $m4dir . '/' . $file; - $file_contents{$fullfile} = &scan_file ($fullfile); + &scan_file ($fullfile); } closedir (DIR); } @@ -219,12 +224,12 @@ sub scan_configure_dep ($) s/\bdnl\b.*$//; s/\#.*$//; - while (/$m4_include_rx/g) + while (/$m4_include_rx/go) { push (@ilist, $1 || $2); } - while (/$ac_require_rx/g) + while (/$ac_require_rx/go) { push (@rlist, $1 || $2); } @@ -261,15 +266,23 @@ sub add_file ($) # Point to the documentation for underquoted AC_DEFUN only once. my $underquoted_manual_once = 0; -# Scan a single M4 file. Return contents. +# Scan a single M4 file, and all files it includes. +# Return the list of included files. sub scan_file ($) { - local ($file) = @_; + my ($file) = @_; + my $base = dirname $file; + + # Do not scan the same file twice. + return @$file_includes{$file} if exists $file_includes{$file}; + # Prevent potential infinite recursion (if two files include each other). + return () if exists $file_contents{$file}; unshift @file_order, $file; my $fh = new Automake::XFile $file; my $contents = ''; + my @inc_files = (); while ($_ = $fh->getline) { # Ignore `##' lines. @@ -277,7 +290,7 @@ sub scan_file ($) $contents .= $_; - if (/$ac_defun_rx/) + while (/$ac_defun_rx/go) { if (! defined $1) { @@ -288,11 +301,12 @@ sub scan_file ($) unless $underquoted_manual_once; $underquoted_manual_once = 1; } - if (! defined $map{$1 || $2}) + my $macro = $1 || $2; + if (! defined $map{$macro}) { - print STDERR "aclocal: found macro $1 in $file: $.\n" + print STDERR "aclocal: found macro $macro in $file: $.\n" if $verbose; - $map{$1 || $2} = $file; + $map{$macro} = $file; } else { @@ -301,18 +315,69 @@ sub scan_file ($) # extremely unpopular. It causes actual problems which # are hard to work around, especially when you must # mix-and-match tool versions. - print STDERR "aclocal: ignoring macro $1 in $file: $.\n" + print STDERR "aclocal: ignoring macro $macro in $file: $.\n" if $verbose; } } + + while (/$m4_include_rx/go) + { + my $ifile = $1 || $2; + # m4_include is relative to the directory of the file which + # perform the include, but we want paths relative to the + # directory where aclocal is run. Do not use + # File::Spec->rel2abs, because we want to store relative + # paths (they might be used later of aclocal outputs an + # m4_include for this file, or if the user itself includes + # this file). + $ifile = "$base/$ifile" + unless $base eq '.' || File::Spec->file_name_is_absolute ($ifile); + push (@inc_files, $ifile); + } } + $file_contents{$file} = $contents; + + # For some reason I don't understand, it does not work + # to do `map { scan_file ($_) } @inc_files' below. + # With Perl 5.8.2 it undefines @inc_files. + my @copy = @inc_files; + my @all_inc_files = (@inc_files, map { scan_file ($_) } @copy); + $file_includes{$file} = \@all_inc_files; + return @all_inc_files; +} - return $contents; +# strip_redundant_includes (%FILES) +# --------------------------------- +# Each key in %FILES is a file that must be present in the output. +# However some of these files might already include other files in %FILES, +# so there is no point in including them another time. +# This removes items of %FILES which are already included by another file. +sub strip_redundant_includes (%) +{ + my %files = @_; + # Files at the end of @file_order should override those at the beginning, + # so it is important to preserve these trailing files. We can remove + # a file A if it is going to be output before a file B that includes + # file A, not the converse. + foreach my $file (reverse @file_order) + { + next unless exists $files{$file}; + foreach my $ifile (@{$file_includes{$file}}) + { + next unless exists $files{$ifile}; + delete $files{$ifile}; + print STDERR "$ifile is already included by $file\n" + if $verbose; + } + } + return %files; } sub trace_used_macros () { my %files = map { $map{$_} => 1 } keys %macro_seen; + $files{'acinclude.m4'} = 1 if -f 'acinclude.m4'; + %files = strip_redundant_includes %files; my $traces = ($ENV{AUTOM4TE} || 'autom4te'); $traces .= " --language Autoconf-without-aclocal-m4 "; @@ -358,11 +423,16 @@ sub write_aclocal ($@) my %files = map { $map{$_} => 1 } @macros; $files{'acinclude.m4'} = 1 if -f 'acinclude.m4'; + %files = strip_redundant_includes %files; for $file (grep { exists $files{$_} } @file_order) { - my $mtime = mtime $file; - $greatest_mtime = $mtime if $greatest_mtime < $mtime; + # Check the time stamp of this file, and all files it includes. + for my $ifile ($file, @{$file_includes{$file}}) + { + my $mtime = mtime $ifile; + $greatest_mtime = $mtime if $greatest_mtime < $mtime; + } # If the file to add looks like outside the project, copy it # to the output. The regex catches filenames starting with diff --git a/tests/Makefile.am b/tests/Makefile.am index 122f05f7..0be4b2dc 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -16,6 +16,7 @@ acloca10.test \ acloca11.test \ acloca12.test \ acloca13.test \ +acloca14.test \ acoutnoq.test \ acoutpt.test \ acoutpt2.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index c7d833bd..5292f6d9 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -130,6 +130,7 @@ acloca10.test \ acloca11.test \ acloca12.test \ acloca13.test \ +acloca14.test \ acoutnoq.test \ acoutpt.test \ acoutpt2.test \ diff --git a/tests/acloca14.test b/tests/acloca14.test new file mode 100755 index 00000000..5ad6d16e --- /dev/null +++ b/tests/acloca14.test @@ -0,0 +1,111 @@ +#! /bin/sh +# Copyright (C) 2004 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 m4_included files are also scanned for definitions. +# Report from Phil Edwards. + +required=GNUmake +. ./defs || exit 1 + +set -e + +cat >> configure.in << 'END' +AM_PROG_LIBTOOL +AC_OUTPUT +END + +echo 'm4_include([a.m4])' > acinclude.m4 +echo 'm4_include([b.m4])' > a.m4 +cat >b.m4 < c.m4 +echo 'AC_DEFUN([SOMETHING_ELSE])' >d.m4 + +mkdir defs +echo 'AC_DEFUN([SOMETHING_ELSE])' >defs/e.m4 +echo 'AC_DEFUN([ANOTHER_MACRO])' >defs/f.m4 + +cat >>Makefile.am<<\EOF +ACLOCAL_AMFLAGS = -I defs +testdist1: distdir + test -f $(distdir)/acinclude.m4 + test -f $(distdir)/a.m4 + test -f $(distdir)/b.m4 + test -f $(distdir)/c.m4 + test -f $(distdir)/d.m4 + test ! -d $(distdir)/defs +testdist2: distdir + test -f $(distdir)/acinclude.m4 + test -f $(distdir)/a.m4 + test -f $(distdir)/b.m4 + test -f $(distdir)/c.m4 + test -f $(distdir)/d.m4 + test ! -f $(distdir)/defs/e.m4 + test -f $(distdir)/defs/f.m4 +EOF + +$ACLOCAL -I defs + +$FGREP acinclude.m4 aclocal.m4 +# None of the following macro should be included. acinclude.m4 +# includes the first four, and the last two are not needed at all. +$FGREP a.m4 aclocal.m4 && exit 1 +$FGREP b.m4 aclocal.m4 && exit 1 +$FGREP c.m4 aclocal.m4 && exit 1 +$FGREP d.m4 aclocal.m4 && exit 1 +$FGREP defs/e.m4 aclocal.m4 && exit 1 +$FGREP defs/f.m4 aclocal.m4 && exit 1 + +$AUTOCONF +$AUTOMAKE + +./configure +$MAKE testdist1 + +cp aclocal.m4 stamp +$sleep + +cat >>c.m4 <<\EOF +AC_DEFUN([FOO], [ANOTHER_MACRO]) +EOF +$MAKE +# Because c.m4 has changed, aclocal.m4 must have been rebuilt. +test `ls -1t aclocal.m4 stamp | sed 1q` = aclocal.m4 +# However, since FOO is not used, f.m4 should not be included +# and the contents of aclocal.m4 should remain the same +cmp aclocal.m4 stamp + + +# If FOO where to be used, that would be another story, of course. +cat >>configure.in <