Subject: bug#12845: [PATCH] aclocal: tracing AC_CONFIG_MACRO_DIRS can work with older autoconf as well (was: Re: bug#12845: [PATCH] AC_CONFIG_MACRO_DIRS: improve tracing and add sanity checks)

From: Stefano Lattarini <[email-masked]>
Date: Thu, 15 Nov 2012 11:58:18 +0100

[+cc automake-patches]

On 11/14/2012 03:50 PM, Eric Blake wrote:
> On 11/14/2012 07:41 AM, Stefano Lattarini wrote:
>>> If I understand your argument correctly, you are claiming that
>>> AC_CONFIG_MACRO_DIR should _not_ trace into AC_CONFIG_MACRO_DIR_TRACE,
>>> so that case (2) can be distinguished by automake; but that would mean
>>> that automake has to trace _both_ AC_CONFIG_MACRO_DIR_TRACE and
>>> AC_CONFIG_MACRO_DIR for case (0) to work.
>>>
>> Currently, Automake is already tracing both AC_CONFIG_MACRO_DIR and
>> AC_CONFIG_MACRO_DIR_TRACE, to avoid several testsuite breakages.  Are
>> you arguing that tracing both macros is a bad idea?  If yes, I might
>> add in 'm4/init.m4' a (re)definition of the AC_CONFIG_MACRO_DIR and
>> AC_CONFIG_MACRO_DIRS macros if pre-2.70 autoconf is detected, so that
>> packages using older autoconf but newer aclocal/automake will still be
>> able to rely on that macros.  And this hack will be removed in Automake
>> 1.14 (when we'll start requiring autoconf 2.70), so this clumsy extra
>> code won't pollute our codebase for too long.
>>
>> Opinions?
> 
> As long as you aim to interoperate with autoconf 2.69 but still diagnose
> mismatches between ACLOCAL_AMFLAGS on the primary directory [granted,
> the mistmatch diagnosis patch still needs to be written], then you have
> to trace AC_CONFIG_MACRO_DIR.  However, you should only need to pay
> attention to the AC_CONFIG_MACRO_DIR trace in the case where
> AC_CONFIG_MACRO_DIR_TRACE had no hits (that is, only for older
> autoconf).  On the other hand, it is harmless if, under newer autoconf,
> you pay attention to both macros - it just means that you will encounter
> the primary directory twice (once under each trace).
> 
> As soon as you AC_PREREQ([2.70]), then yes, you can quit tracing
> AC_CONFIG_MACRO_DIR.
> 
The below patch should allow our users to employ AC_CONFIG_MACRO_DIRS
with autoconf 2.69 as well.  It still doesn't work with autoconf 2.68
and earlier though, due to a bug in autom4te option parsing (fixed by
autoconf commit v2.68-120-gf4be358).  That could be fixed by using an
external file rather than stdin to pass aclocal the contents of
'$ac_config_macro_dirs_fallback'; but I rather do so in a separate
patch, with a dedicated rationale.

So, OK to go?

Regards,
  Stefano

---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< ----

>From a966b8bde5fe8bb4927ade875d80e057b4d3fa2f Mon Sep 17 00:00:00 2001
Message-Id: <a966b8bde[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Wed, 14 Nov 2012 16:54:38 +0100
Subject: [PATCH] aclocal: tracing AC_CONFIG_MACRO_DIRS can work with older autoconf as well

This will allow our users to interact also with pre-2.70 autoconf without
need for the user to add ACLOCAL_AMFLAGS in Makefile.am.  For example,
before this change, in order to have aclocal look for macros in 'm4/dir1'
and 'm4/dir2' also when (say) autoconf 2.69 was used, our users would
have had to add something like:

    ACLOCAL_AMFLAGS = -I m4/dir1 -I m4/dir2

in Makefile.am, in addition to the

    AC_CONFIG_MACRO_DIRS([m4/dir1 m4/dir2])

in configure.ac.  Now, the AC_CONFIG_MACRO_DIRS call is enough.

See the long-winded discussion on automake bug#12845 for more details:
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12845>

* aclocal.in ($ac_config_macro_dirs_fallback): New global variable,
contains m4 code to issue a fallback definition of AC_CONFIG_MACRO_DIRS
as an alias for the private macro _AM_CONFIG_MACRO_DIRS.
(trace_used_macros): Handle and trace that macro.  Do some code
reorganization and fix related botched indentation while at it.
(write_aclocal): Output '$ac_config_macro_dirs_fallback' early in
the generated aclocal.m4.
* t/aclocal-macrodirs.tap: Run unconditionally, even with older
autoconf.
* t/subpkg-macrodir.sh: Likewise.
* doc/automake.texi: Document only AC_CONFIG_MACRO_DIRS, rather
than AC_CONFIG_MACRO_DIR.

Signed-off-by: Stefano Lattarini <[email-masked]>
---
 aclocal.in              | 53 ++++++++++++++++++++++++++++++++++++++-----------
 doc/automake.texi       |  6 +++---
 t/aclocal-macrodirs.tap |  6 ------
 t/subpkg-macrodir.sh    |  6 ------
 4 files changed, 44 insertions(+), 27 deletions(-)

diff --git a/aclocal.in b/aclocal.in
index d4e7000..3ee83c9 100644
--- a/aclocal.in
+++ b/aclocal.in
@@ -45,6 +45,16 @@ use File::Path ();

 # Some globals.

+# Support AC_CONFIG_MACRO_DIRS also with older autoconf.
+# FIXME: To be removed in Automake 1.14, once we can assume autoconf
+#        2.70 or later.
+# NOTE: This variable deliberately contain no newlines.
+my $ac_config_macro_dirs_fallback =
+  "m4_ifndef([AC_CONFIG_MACRO_DIRS], [" .
+    "m4_defun([_AM_CONFIG_MACRO_DIRS], [])" .
+    "m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS(\$@)])" .
+  "])";
+
 # We do not operate in threaded mode.
 $perl_threads = 0;

@@ -716,16 +726,23 @@ sub trace_used_macros ()
   my %files = map { $map{$_} => 1 } keys %macro_seen;
   %files = strip_redundant_includes %files;

-  my $traces = ($ENV{AUTOM4TE} || '@am_AUTOM4TE@');
-  $traces .= " --language Autoconf-without-aclocal-m4 ";
+  my $early_m4_code = "";
   # When AC_CONFIG_MACRO_DIRS is used, avoid possible spurious warnings
   # from autom4te about macros being "m4_require'd but not m4_defun'd";
   # for more background, see:
   # http://lists.gnu.org/archive/html/autoconf-patches/2012-11/msg00004.html
   # as well as autoconf commit 'v2.69-44-g1ed0548', "warn: allow aclocal
   # to silence m4_require warnings".
-  $traces = "echo 'm4_define([m4_require_silent_probe], [-])' | " .
-            "$traces - ";
+  $early_m4_code .= "m4_define([m4_require_silent_probe], [-])";
+  # Support AC_CONFIG_MACRO_DIRS also with older autoconf.
+  # FIXME: To be removed in Automake 1.14, once we can assume autoconf
+  #        2.70 or later.
+  $early_m4_code .= $ac_config_macro_dirs_fallback;
+
+  my $traces = ($ENV{AUTOM4TE} || '@am_AUTOM4TE@');
+  $traces .= " --language Autoconf-without-aclocal-m4 ";
+  $traces = "echo '$early_m4_code' | $traces - ";
+
   # All candidate files.
   $traces .= join (' ',
 		   (map { "'$_'" }
@@ -738,11 +755,12 @@ sub trace_used_macros ()
 		     'AC_DEFUN_ONCE',
 		     'AU_DEFUN',
 		     '_AM_AUTOCONF_VERSION',
-		     # FIXME: We still need to trace AC_CONFIG_MACRO_DIR
-                     # for compatibility with older autoconf.  Remove this
-                     # when we can assume Autoconf 2.70 or later.
+		     'AC_CONFIG_MACRO_DIR_TRACE',
+                     # FIXME: This is an hack for compatibility with older
+                     # autoconf.  Remove this in Automake 1.14, when we can
+                     # assume Autoconf 2.70 or later.
 		     'AC_CONFIG_MACRO_DIR',
-		     'AC_CONFIG_MACRO_DIR_TRACE')),
+		     '_AM_CONFIG_MACRO_DIRS')),
 		   # Do not trace $1 for all other macros as we do
 		   # not need it and it might contains harmful
 		   # characters (like newlines).
@@ -776,18 +794,28 @@ sub trace_used_macros ()
         {
           push @ac_config_macro_dirs, $arg1;
         }
-    # FIXME: We still need to trace AC_CONFIG_MACRO_DIR
-    # for compatibility with older autoconf.  Remove this
-    # when we can assume Autoconf 2.70 or later.
-    elsif ($macro eq 'AC_CONFIG_MACRO_DIR')
+      # FIXME: We still need to trace AC_CONFIG_MACRO_DIR
+      # for compatibility with older autoconf.  Remove this
+      # once we can assume Autoconf 2.70 or later.
+      elsif ($macro eq 'AC_CONFIG_MACRO_DIR')
         {
           @ac_config_macro_dirs = ($arg1);
         }
+      # FIXME:This is an hack for compatibility with older autoconf.
+      # Remove this once we can assume Autoconf 2.70 or later.
+      elsif ($macro eq '_AM_CONFIG_MACRO_DIRS')
+        {
+           # Empty leading/trailing fields might be produced by split,
+           # hence the grep is really needed.
+           push @ac_config_macro_dirs, grep (/./, (split /\s+/, $arg1));
+        }
     }

   # FIXME: in Autoconf >= 2.70, AC_CONFIG_MACRO_DIR calls
   # AC_CONFIG_MACRO_DIR_TRACE behind the scenes, which could
   # leave unwanted duplicates in @ac_config_macro_dirs.
+  # Remove this in Automake 1.14, when we'll stop tracing
+  # AC_CONFIG_MACRO_DIR explicitly.
   @ac_config_macro_dirs = uniq @ac_config_macro_dirs;

   $tracefh->close;
@@ -915,6 +943,7 @@ $output";
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.

+$ac_config_macro_dirs_fallback
 $output";

   # We try not to update $output_file unless necessary, because
diff --git a/doc/automake.texi b/doc/automake.texi
index 0118a21..c0b1abf 100644
--- a/doc/automake.texi
+++ b/doc/automake.texi
@@ -3605,10 +3605,10 @@ will be almost impossible to share macros between packages.
 The second possibility, which we do recommend, is to write each macro
 in its own file and gather all these files in a directory.  This
 directory is usually called @file{m4/}.  Then it's enough to update
-@file{configure.ac} by adding a proper call to @code{AC_CONFIG_MACRO_DIR}:
+@file{configure.ac} by adding a proper call to @code{AC_CONFIG_MACRO_DIRS}:

 @example
-AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_MACRO_DIRS([m4])
 @end example

 @command{aclocal} will then take care of automatically adding @file{m4/}
@@ -3731,7 +3731,7 @@ MyPackage uses an @file{m4/} directory to store local macros as
 explained in @ref{Local Macros}, and has

 @example
-AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_MACRO_DIRS([m4])
 @end example

 @noindent
diff --git a/t/aclocal-macrodirs.tap b/t/aclocal-macrodirs.tap
index 28abb7c..0b6886b 100755
--- a/t/aclocal-macrodirs.tap
+++ b/t/aclocal-macrodirs.tap
@@ -20,12 +20,6 @@
 am_create_testdir=empty
 . test-init.sh

-{ $AUTOCONF -o /dev/null - <<END
-    AC_INIT([x], [0])
-    AC_CONFIG_MACRO_DIRS([.])
-END
-} || skip_all_ "autoconf doesn't define the AC_CONFIG_MACRO_DIRS macro"
-
 plan_ 14

 ocwd=$(pwd) || fatal_ "getting current working directory"
diff --git a/t/subpkg-macrodir.sh b/t/subpkg-macrodir.sh
index 275af0d..a16f42b 100755
--- a/t/subpkg-macrodir.sh
+++ b/t/subpkg-macrodir.sh
@@ -19,12 +19,6 @@

 . test-init.sh

-{ $AUTOCONF -o /dev/null - <<END
-    AC_INIT([x], [0])
-    AC_CONFIG_MACRO_DIRS([.])
-END
-} || skip_ "autoconf doesn't define the AC_CONFIG_MACRO_DIRS macro"
-
 cat > configure.ac <<'END'
 AC_INIT([super], [1.0])
 AM_INIT_AUTOMAKE
-- 
1.8.0