Subject: Re: bug#19539: [1.15] AC_CONFIG_AUX_DIR should be called early

From: Pavel Raiskup <[email-masked]>
Date: Fri, 30 Jan 2015 17:49:49 +0100

[+cc autoconf as this should be done in cooperation]

On Thursday 08 of January 2015 16:43:02 Pavel Raiskup wrote:
> Hi, automake-1.15 behaves differently when AC_CONFIG_AUX_DIR is specified
> after AC_USE_SYSTEM_EXTENSIONS (example attached which worked with
> automake-1.14.1):
>
>   $ autoreconf -vfi
>   $ ./configure
>   configure: error: cannot find install-sh, install.sh, or shtool in "." "./.." "./../.."
>
> I think this is result of the commit:
> http://git.savannah.gnu.org/cgit/automake.git/commit/?h=minor&id=7bc592708cc65
>
> I believe that it is bad practice (and probably not-a-bug itself) and
> AC_CONFIG_AUX_DIR should be specified as soon as possible, but we do not
> have this documented (yet).  Thats why I write to bug-automake.  Maybe we
> could install some AC_BEFORE warnings into autoconf but I would like to
> discuss it here.
> And at least it is good to have documented that behavior changed upstream.
>
> Original bugreport:
> https://bugzilla.redhat.com/show_bug.cgi?id=1179182

Some more words, I was probably able to catch the real issue.  In the
failing example was done something like:

  AC_INIT([amhello], [1.0], [[email-masked]])
  AC_GNU_SOURCE
  AC_CONFIG_AUX_DIR([build-aux])
  AM_INIT_AUTOMAKE([foreign -Werror])
  AC_CONFIG_FILES([Makefile])
  AC_OUTPUT

For this file, autoreconf (even upstream git version) produces broken
configure file if automake-1.15 is used.  This is caused by the following
facts:

  * AC_GNU_SOURCE calls transitively AC_PROG_CC

  * aclocal redefines AC_PROG_CC in aclocal.m4 quite hacky way, but truth
    is that this has been automake doing from v1.13.  But..

  * .. the AC_PROG_CC requires AM_AUX_DIR_EXPAND, which was newly changed
    [1] to require AC_CONFIG_AUX_DIR_DEFAULT.  This is not so bad
    practice, I would say, thats actually what AC_CONFIG_AUX_DIR_DEFAULT
    exists for.

Because the example uses explicit non-default AC_CONFIG_AUX_DIR, the
AC_CONFIG_AUX_DIR_DEFAULT is called first and its check fails because all
auxiliary files (including install-sh) are installed in non-default path.

I believe that new autoconf-2.70 should warn when configure.ac calls
AC_CONFIG_AUX_DIR_DEFAULT before AC_CONFIG_AUX_DIR.  This can be done
easily by:

  AC_PROG_INSTALL
  AC_CONFIG_AUX_DIR([non-default-aux-dir])

I'm able to hack on Automake patch, but that depends on the Autoconf
maintainers opinions and whether the attached patch is OK.  The proposed
patch would be:

  If we already hack some macro (namely AC_PROG_CC) which we make
  dependant on AC_CONFIG_AUX_DIR, we should also hack AC_CONFIG_AUX_DIR so
  it calls AC_BEFORE([AC_CONFIG_AUX_DIR], [AC_CONFIG_AUX_DIR_DEFAULT]).
  All that only if autoconf v2.69 or older is used.

At the beginning, the patch for autoconf is attached.

[1] http://git.savannah.gnu.org/cgit/automake.git/commit/?h=minor&id=7bc592708cc65

Pavel
>From 99fab0b28b2d685c186dbfacafa6e745ccf98cbc Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <[email-masked]>
Date: Fri, 30 Jan 2015 13:52:08 +0100
Subject: [PATCH] autoconf: warn about late AC_CONFIG_AUX_DIR call

Some macros explicitly call (require) AC_CONFIG_AUX_DIR_DEFAULT.
When such macro was called _before_ AC_CONFIG_AUX_DIR, the check
for install-sh script would then most probably fail (as the
install-sh script probably resided in re-defined aux directory).
See automake bug #19539.

* lib/autoconf/general.m4(AC_CONFIG_AUX_DIR): Call AC_BEFORE to
warn about bad macro order.  Put AC_BEFORE _before_ actual call to
internal AC_CONFIG_AUX_DIRS as it provides
AC_CONFIG_AUX_DIR_DEFAULT.
* doc/autoconf.texi (AC_CONFIG_AUX_DIR): Document why
AC_CONFIG_AUX_DIR should be called early.
* tests/tools.at (autoconf: AC_CONFIG_AUX_DIR): New testcase.
---
 doc/autoconf.texi       | 11 +++++++++++
 lib/autoconf/general.m4 |  4 +++-
 tests/tools.at          | 41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index d9e833d..65233fd 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -2096,6 +2096,17 @@ name is obsolete because some @command{make} have a rule that creates
 The auxiliary directory is commonly named @file{build-aux}.
 If you need portability to DOS variants, do not name the
 auxiliary directory @file{aux}.  @xref{File System Conventions}.
+
+Call to @code{AC_CONFIG_AUX_DIR} should be done as soon as possible after the
+@code{AC_INIT} because there are several macros requiring properly defined
+auxiliary directory (e.g., @code{AC_PROG_INSTALL}).  If you use such macro
+together with @code{AC_CONFIG_AUX_DIR} you must make sure
+@code{AC_CONFIG_AUX_DIR} is called before such macro.
+
+Also note that if you use Automake (in version 1.13.3 and above), Automake
+redefines Autoconf's @code{AC_PROG_CC} macro the way it also depends on aux
+directory.  Thus, @code{AC_CONFIG_AUX_DIR} must be called before
+@code{AC_PROG_CC} or any other macro requiring it.
 @end defmac
 
 @defmac AC_REQUIRE_AUX_FILE (@var{file})
diff --git a/lib/autoconf/general.m4 b/lib/autoconf/general.m4
index 2d1a291..4f9b877 100644
--- a/lib/autoconf/general.m4
+++ b/lib/autoconf/general.m4
@@ -1681,7 +1681,9 @@ program_transform_name=`AS_ECHO(["$program_transform_name"]) | sed "$ac_script"`
 # in directory DIR.  These are auxiliary files used in configuration.
 # DIR can be either absolute or relative to $srcdir.
 AC_DEFUN([AC_CONFIG_AUX_DIR],
-[AC_CONFIG_AUX_DIRS($1 "$srcdir"/$1)])
+[AC_BEFORE([$0], [AC_CONFIG_AUX_DIR_DEFAULT])
+AC_CONFIG_AUX_DIRS($1 "$srcdir"/$1)dnl
+])

 # AC_CONFIG_AUX_DIR_DEFAULT
diff --git a/tests/tools.at b/tests/tools.at
index 24173c9..889375b 100644
--- a/tests/tools.at
+++ b/tests/tools.at
@@ -605,6 +605,47 @@ AT_CHECK([[grep 'version ]]AT_PACKAGE_VERSION[[ version' configure]],
 AT_CLEANUP

+# autoconf: AC_CONFIG_AUX_DIR
+# ---------------------------
+# Check that calling AC_PROG_INSTALL before AC_CONFIG_AUX_DIR warns user.
+
+AT_SETUP([autoconf: AC_CONFIG_AUX_DIR])
+AT_DATA([configure.ac],
+[[AC_INIT
+AC_PROG_INSTALL
+AC_CONFIG_AUX_DIR([build-aux])
+AC_OUTPUT
+]])
+
+AT_DATA([stderr],
+[[ohohoo
+]])
+
+mkdir build-aux
+touch build-aux/install-sh
+chmod a+x build-aux/install-sh
+
+AT_CHECK_AUTOCONF([], [0], [ignore], [stderr])
+AT_CHECK([dnl
+grep -c 'AC_CONFIG_AUX_DIR_DEFAULT was called before AC_CONFIG_AUX_DIR' stderr],
+[0], [1
+])
+
+AT_CHECK_CONFIGURE([], [1], [ignore], [stderr])
+AT_CHECK([grep -c 'cannot find install-sh' stderr], [0], [1
+])
+
+AT_DATA([configure.ac],
+[[AC_INIT
+AC_CONFIG_AUX_DIR([build-aux])
+AC_PROG_INSTALL
+AC_OUTPUT
+]])
+
+AT_CHECK_AUTOCONF([], [0])
+
+AT_CLEANUP
+
 
 # autoconf: AC_PRESERVE_HELP_ORDER
 # --------------------------------
-- 
2.1.0