Subject: remake rules can fail in a weird corner case (VPATH into $distdir).

From: Stefano Lattarini <[email-masked]>
Date: Tue, 22 Nov 2011 20:03:51 +0100

Severity: minor
thanks

This report describes a failure of the automake-generated remake
rules in a particular, low-probability scenario.  I admit upfront
that the scenario I'm speaking about is pretty corner-case, and
very unlikely to be problemtic in practice.  Still, I think it's
still worth having a description and a testsuite exposure for the
problem.

Here is how to reporduce the bug, step by step.

  $ mkdir bug
  $ cd bug
  $ cat > configure.ac <<'END'
  AC_INIT([foo], [1.0])
  AM_INIT_AUTOMAKE([foreign])
  m4_include([foobar.m4])
  AC_CONFIG_FILES([Makefile])
  AC_OUTPUT
  END
  $ : > foobar.m4
  $ cat > Makefile.am <<'END'
  $(srcdir)/foobar.m4:
	echo ': foobar was here :' > $@
  END
  $ autoreconf -vi
  autoreconf: Entering directory `.'
  autoreconf: configure.ac: not using Gettext
  autoreconf: running: aclocal 
  autoreconf: configure.ac: tracing
  autoreconf: configure.ac: not using Libtool
  autoreconf: running: /usr/bin/autoconf
  autoreconf: configure.ac: not using Autoheader
  autoreconf: running: automake --add-missing --copy --no-force
  configure.ac:2: installing `./install-sh'
  configure.ac:2: installing `./missing'
  autoreconf: Leaving directory `.'
  $ ./configure
  checking for a BSD-compatible install... /usr/bin/install -c
  checking whether build environment is sane... yes
  ...
  config.status: creating Makefile
  # OK, so the developer wants to interactively try out how the
  # "distributed form" of his package behaves
  $ make distdir
  ...
  $ ls foo-1.0 
  Makefile.am  aclocal.m4  configure.ac  install-sh
  Makefile.in  configure   foobar.m4     missing
  $ cd f00-1.0
  # He's interested in trying out a VPATH build.
  $ mkdir build && cd build
  $ ../configure
  checking for a BSD-compatible install... /usr/bin/install -c
  ...
  config.status: creating Makefile
  # He wants to verify that the rules he's written to rebuild a file
  # included by configure.in works also in VPATH builds.
  $ rm -f ../foobar.m4
  # But things won't work as expected!
  $ make
  make: Nothing to be done for `all'.
  $ ls -l ../foobar.m4
  ls: cannot access ../foobar.m4: No such file or directory
  $ grep foobar ../configure || echo no match
  no match
  # And a spurious error will fail when trying to rebuild the
  # distribution tarball.
  $ make dist
  ...
  test -d "foo-1.0" || mkdir "foo-1.0"
  cp: cannot stat `../foobar.m4': No such file or directory
  make: *** [distdir] Error 1

Let's see the explanation of the bug.  The following dependency is
in the generated Makefile:

  $(top_srcdir)/configure:  $(am__configure_deps)

Once the macros are expanded, this becomes:

  ../configure: ../foobar.m4 ../configure.ac ../aclocal.m4

GNN make sees that `../foobar.m4' does not exists in the current
directory; but since a VPATH build is being performed, make does not
error out, but rather looks for that file in the $(srcdir) directory
too.  Now, in our case `$(srcdir)' is `..', so make looks for the
file `../../foobar.m4' -- which do exists!  In fact, the first `..'
brings us in the `foo-1.0' directory, the second one in the original
test directory -- where our original, empty `foobar.m4' resides.

If this is true, nesting the build directory one level more should
solve the problem -- and it does:

  $ cd ..
  $ mkdir -p build2/sub
  $ cd build2/sub
  $ ../../configure
  checking for a BSD-compatible install... /usr/bin/install -c
  checking whether build environment is sane... yes
  ...
  config.status: creating Makefile
  $ make
  echo ': foobar was here :' > ../../foobar.m4
  CDPATH="${ZSH_VERSION+.}:" && cd ../.. && /bin/sh /tmp/bug/foo-1.0/missing --run aclocal-1.11 
   cd ../.. && /bin/sh /tmp/bug/foo-1.0/missing --run automake-1.11 --foreign
  CDPATH="${ZSH_VERSION+.}:" && cd ../.. && /bin/sh /tmp/bug/foo-1.0/missing --run autoconf
  /bin/sh ./config.status --recheck
  running CONFIG_SHELL=/bin/sh /bin/sh ../../configure --no-create --no-recursion
  checking for a BSD-compatible install... /usr/bin/install -c
  ...
  configure: creating ./config.status
   /bin/sh ./config.status
  config.status: creating Makefile
  make: Nothing to be done for `all'.

Attached are two test scripts that expose the bug for the related but
slightly different cases of an `.m4' file included by `configure.ac'
and an `.am' file included by `Makefile.am'.  I will soonish add them
to the maint branch if there is no objection.

Regards,
  Stefano