From d3a058fb9ed4af2a548ea0536188baf0e5a56177 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Sun, 30 Jan 2005 17:47:39 +0000 Subject: [PATCH] Preliminary support for `aclocal --install'. This still lacks #serial support. * aclocal.in (reset_maps, install_file): New functions. (write_aclocal): Copy files if --install. (usage, parse_arguments): Recognize --install. ("MAIN"): Start aclocal again if some file were installed. * tests/acloca10.test: Augment to test --install. * tests/aclocal.in, tests/defs.in: Add support for ACLOCAL_TESTSUITE_FLAGS, used by acloca10.test. * doc/automake.texi (aclocal options, Local Macros): Document --install. (Future of aclocal): Adjust. --- ChangeLog | 13 +++++ NEWS | 4 ++ aclocal.in | 115 +++++++++++++++++++++++++++++++++++++++----- doc/automake.texi | 28 +++++++++-- tests/acloca10.test | 44 ++++++++++++++++- tests/aclocal.in | 2 +- tests/defs.in | 6 ++- 7 files changed, 192 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 72304ef37..ec2f1ec7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2005-01-30 Alexandre Duret-Lutz + Preliminary support for `aclocal --install'. + This still lacks #serial support. + * aclocal.in (reset_maps, install_file): New functions. + (write_aclocal): Copy files if --install. + (usage, parse_arguments): Recognize --install. + ("MAIN"): Start aclocal again if some file were installed. + * tests/acloca10.test: Augment to test --install. + * tests/aclocal.in, tests/defs.in: Add support for + ACLOCAL_TESTSUITE_FLAGS, used by acloca10.test. + * doc/automake.texi (aclocal options, Local Macros): Document + --install. + (Future of aclocal): Adjust. + * doc/automake.texi (Macro search path): Using --acdir is not obvious, it's erroneous. diff --git a/NEWS b/NEWS index 9fd676610..f369e3225 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,10 @@ New in 1.9a: - aclocal now also supports -Wmumble and -Wno-mumble options. + - aclocal supports an --install option, that will cause system-wide + third-party macros to be installed in the local directory + specified with the first -I flag. + - Per-target flags are now correctly handled in link rules. For instance maude_CFLAGS correctly overrides AM_CFLAGS; likewise diff --git a/aclocal.in b/aclocal.in index a905c06d4..44b687eb8 100644 --- a/aclocal.in +++ b/aclocal.in @@ -59,18 +59,21 @@ my @user_includes = (); my @automake_includes = ("@datadir@/aclocal-$APIVERSION"); my @system_includes = ('@datadir@/aclocal'); +# Whether we should copy M4 file in $user_includes[0]. +my $install = 0; + # configure.ac or configure.in. my $configure_ac; # Output file name. my $output_file = 'aclocal.m4'; -# Modification time of the youngest dependency. -my $greatest_mtime = 0; - # Option --force. my $force_output = 0; +# Modification time of the youngest dependency. +my $greatest_mtime = 0; + # Which macros have been seen. my %macro_seen = (); @@ -98,6 +101,12 @@ use constant FT_SYSTEM => 3; # Map file names to included files (transitively closed). my %file_includes = (); +# Files which have already been added. +my %file_added = (); + +# Files that have already been scanned. +my %scanned_configure_dep = (); + # Matches a macro definition. # AC_DEFUN([macroname], ...) # or @@ -129,6 +138,41 @@ sub check_acinclude () } } +sub reset_maps () +{ + $greatest_mtime = 0; + %macro_seen = (); + @file_order = (); + %map = (); + %map_traced_defs = (); + %file_contents = (); + %file_type = (); + %file_includes = (); + %file_added = (); + %scanned_configure_dep = (); + undef &search; +} + +# install_file ($SRC, $DEST) +sub install_file ($$) +{ + my ($src, $dest) = @_; + + if ($force_output + || !exists $file_contents{$dest} + || $file_contents{$src} ne $file_contents{$dest}) + { + if (system ('cp', $src, $dest)) + { + error ("error while copying `$src' to `$dest'"); + } + else + { + msg 'note', "installing `$dest'"; + } + } +} + ################################################################ # scan_m4_dirs($TYPE, @DIRS) @@ -218,7 +262,6 @@ sub add_macro ($) # Scan a configure dependency (configure.ac, or separate m4 files) # for uses of know macros and AC_REQUIREs of possibly unknown macros. # Recursively scan m4_included files. -my %scanned_configure_dep = (); sub scan_configure_dep ($) { my ($file) = @_; @@ -275,7 +318,6 @@ sub scan_configure_dep ($) # add_file ($FILE) # ---------------- # Add $FILE to output. -my %file_added = (); # files which have already been added. sub add_file ($) { my ($file) = @_; @@ -468,6 +510,7 @@ sub scan_configure () ################################################################ # Write output. +# Return 0 iff some files were installed locally. sub write_aclocal ($@) { my ($output_file, @macros) = @_; @@ -493,6 +536,8 @@ sub write_aclocal ($@) # Never include configure.ac :) delete $files{$configure_ac}; + my $installed = 0; + for my $file (grep { exists $files{$_} } @file_order) { # Check the time stamp of this file, and of all files it includes. @@ -508,7 +553,23 @@ sub write_aclocal ($@) if ($file_type{$file} != FT_USER || $file =~ m,^(?:\w:)?[\\/],) { - $output .= $file_contents{$file} . "\n"; + if (!$install || $file_type{$file} != FT_SYSTEM) + { + # Copy the file into aclocal.m4. + $output .= $file_contents{$file} . "\n"; + } + else + { + # Install the file (and any file it includes). + my $dest; + for my $ifile (@{$file_includes{$file}}, $file) + { + $dest = "$user_includes[0]/" . basename $ifile; + verb "installing $ifile to $dest"; + install_file ($ifile, $dest); + } + $installed = 1; + } } else { @@ -517,9 +578,15 @@ sub write_aclocal ($@) } } + if ($installed) + { + verb "running aclocal anew, because some files were installed locally"; + return 0; + } + # Nothing to output?! # FIXME: Shouldn't we diagnose this? - return if ! length ($output); + return 1 if ! length ($output); # We used to print `# $output_file generated automatically etc.' But # this creates spurious differences when using autoreconf. Autoreconf @@ -558,14 +625,14 @@ $output"; && $output eq contents ($output_file)) { verb "$output_file unchanged"; - return; + return 1; } verb "writing $output_file"; my $out = new Automake::XFile "> $output_file"; print $out $output; - return; + return 1; } ################################################################ @@ -584,6 +651,7 @@ Options: --force always update output file --help print this help, then exit -I DIR add directory to search list for .m4 files + --install copy third-party files to the first -I directory --output=FILE put output in FILE (default aclocal.m4) --print-ac-dir print name of directory holding m4 files, then exit --verbose don't be silent @@ -633,6 +701,7 @@ sub parse_arguments () }, 'force' => \$force_output, 'I=s' => \@user_includes, + 'install' => \$install, 'output=s' => \$output_file, 'print-ac-dir' => \$print_and_exit, 'verbose' => sub { setup_channel 'verb', silent => 0; }, @@ -694,6 +763,12 @@ sub parse_arguments () exit 0; } + if ($install && !@user_includes) + { + fatal ("--install should copy macros in the directory indicated by the" + . "\nfirst -I option, but no -I was supplied."); + } + if (! -d $system_includes[0]) { # By default $(datadir)/aclocal doesn't exist. We don't want to @@ -727,12 +802,26 @@ sub parse_arguments () parse_WARNINGS; # Parse the WARNINGS environment variable. parse_arguments; $configure_ac = require_configure_ac; -scan_m4_files; -scan_configure; -if (! $exit_code) + +# We may have to rerun aclocal if some file have been installed, but +# it should not happen more than once. The reason we must run again +# is that once the file has been moved from /usr/share/aclocal/ to the +# local m4/ directory it appears at a new place in the search path, +# hence it should be output at a different position in aclocal.m4. If +# we did not rerun aclocal, the next run of aclocal would produce a +# different aclocal.m4. +my $loop = 0; +while (1) { + ++$loop; + prog_error "Too many loops." if $loop > 2; + + reset_maps; + scan_m4_files; + scan_configure; + last if $exit_code; my %macro_traced = trace_used_macros; - write_aclocal ($output_file, keys %macro_traced); + last if write_aclocal ($output_file, keys %macro_traced); } check_acinclude; diff --git a/doc/automake.texi b/doc/automake.texi index 88dc6e141..71a428f81 100644 --- a/doc/automake.texi +++ b/doc/automake.texi @@ -1657,6 +1657,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 --install +@opindex --install +Install system-wide third-party macros into the first directory +specified with @code{-I @var{dir}} instead of copying them in the +output files. + @item --force @opindex --force Always overwrite the output file. The default is to overwrite the output @@ -2237,6 +2243,24 @@ this requirement will hinder development. An easy solution is to copy such third-party macros in your local @file{m4/} directory so they get distributed. +Since Automake 1.10, @command{aclocal} offers an option to copy these +system-wide third-party macros in your local macro directory, solving +the above problem. Simply use: + +@example + ACLOCAL_AMFLAGS = -I m4 --install +@end example + +@noindent +With this setup, system-wide macros will be copied to @file{m4/} +the first time you run @command{autoreconf}. Then the locally +installed macros will have precedence over the system-wide installed +macros each time @command{aclocal} is run again. (So the only reason +to keep @code{--install} in the flags after the first run is that when +you later edit @file{configure.ac} and depend on a new macro, this +macro will be installed in your @file{m4/} automatically.) + + @node Future of aclocal @section The Future of @command{aclocal} @cindex @command{aclocal}'s scheduled death @@ -2250,9 +2274,7 @@ feature is misplaced. The new implementation will probably be done slightly differently. For instance it could enforce the @file{m4/}-style layout discussed in -@ref{Local Macros}, and take care of copying (and even updating) -third-party macros from @file{/usr/share/aclocal/} into the local -@file{m4/} directory. +@ref{Local Macros}. We have no idea when and how this will happen. This has been discussed several times in the past, but someone still has to commit diff --git a/tests/acloca10.test b/tests/acloca10.test index b41b2910f..d13c5bbd5 100755 --- a/tests/acloca10.test +++ b/tests/acloca10.test @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2003 Free Software Foundation, Inc. +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is part of GNU Automake. # @@ -21,6 +21,8 @@ # Make sure aclocal define macros in the same order as -I's. # This is the same as aclocal9.test, with the macro calls reversed. # (It did make a difference.) +# +# Also check for --install. . ./defs || exit 1 @@ -29,9 +31,10 @@ set -e cat >> configure.in << 'END' MACRO2 MACRO1 +MACRO3 END -mkdir m4_1 m4_2 +mkdir m4_1 m4_2 dirlist-test cat >m4_1/somedefs.m4 <> foo]) @@ -42,14 +45,51 @@ cat >m4_2/somedefs.m4 <> foo]) EOF +cat >dirlist-test/macro.m4 <> foo]) +EOF + $ACLOCAL -I m4_1 -I m4_2 $AUTOCONF ./configure grep macro11 foo grep macro21 foo +grep macro3 foo +grep MACRO3 aclocal.m4 +test ! -f m4_1/macro.m4 +test ! -f m4_2/macro.m4 $ACLOCAL -I m4_2 -I m4_1 $AUTOCONF ./configure grep macro12 foo grep macro21 foo +grep macro3 foo +grep MACRO3 aclocal.m4 +test ! -f m4_1/macro.m4 +test ! -f m4_2/macro.m4 + +ACLOCAL_TESTSUITE_FLAGS='-I m4_1 -I m4_2' +$ACLOCAL --install +$AUTOCONF +./configure +grep macro11 foo +grep macro21 foo +grep macro3 foo +grep MACRO3 aclocal.m4 && exit 1 +test -f m4_1/macro.m4 +test ! -f m4_2/macro.m4 +cp aclocal.m4 copy.m4 + +echo '#GREPME' >>dirlist-test/macro.m4 +$ACLOCAL --install +$AUTOCONF +./configure +grep macro11 foo +grep macro21 foo +grep macro3 foo +grep MACRO3 aclocal.m4 && exit 1 +grep GREPME m4_1/macro.m4 && exit 1 +test -f m4_1/macro.m4 +test ! -f m4_2/macro.m4 +diff aclocal.m4 copy.m4 diff --git a/tests/aclocal.in b/tests/aclocal.in index 59b7e8b50..ea3464c9a 100644 --- a/tests/aclocal.in +++ b/tests/aclocal.in @@ -14,5 +14,5 @@ perllibdir="@abs_top_builddir@/lib@PATH_SEPARATOR@@abs_top_srcdir@/lib" export perllibdir # Most of the files are in $srcdir/../m4. However amversion.m4 is # generated in ../m4, so we include that directory in the search path too. -exec @abs_top_builddir@/aclocal \ +exec @abs_top_builddir@/aclocal $ACLOCAL_TESTSUITE_FLAGS \ -I @abs_top_builddir@/m4 --acdir=@abs_top_srcdir@/m4 ${1+"$@"} diff --git a/tests/defs.in b/tests/defs.in index 6f36fbe30..e9ae198aa 100644 --- a/tests/defs.in +++ b/tests/defs.in @@ -1,7 +1,7 @@ # -*- shell-script -*- # @configure_input@ # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is part of GNU Automake. @@ -77,6 +77,10 @@ test -z "$MISSING" && MISSING=`pwd`/../lib/missing # Use -Werror because this also turns some Perl warnings into error. # (Tests for which this is inappropriate should use -Wno-error.) test -z "$ACLOCAL" && ACLOCAL="aclocal-@APIVERSION@ -Werror" +# Extra flags to pass to aclocal before all other flags added by this script. +ACLOCAL_TESTSUITE_FLAGS= +export ACLOCAL_TESTSUITE_FLAGS + # See how Automake should be run. We put --foreign as the default # strictness to avoid having to create lots and lots of files. A test # can override this by specifying a different strictness. Use -Wall -- 2.34.1