[PATCH 0/4] Fix automake bug#13928

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/4] Fix automake bug#13928

Stefano Lattarini
Stefano Lattarini (4):
  deps: 'subdir-object' option now works when foo_SOURCES contains $(var)
  tests: fix some bugs in an XFAILing test
  compile: don't place built object files in $(srcdir), ever ...
  deps: fix corner-case "make distclean" bug

 NEWS                                  |  43 +++++++++++
 PLANS/subdir-objects.txt              |  10 +--
 THANKS                                |   1 +
 bin/automake.in                       | 134 +++++++++++++++++++--------------
 lib/am/configure.am                   |   6 +-
 lib/am/depend.am                      |  14 +++-
 m4/depout.m4                          |  78 +++++++++----------
 m4/make.m4                            |  59 +++++++--------
 t/depcomp8a.sh                        |  16 ++--
 t/depcomp8b.sh                        |  16 ++--
 t/{postproc.sh => depend-postproc.sh} |  29 ++++++-
 t/extra-sources.sh                    |   5 +-
 t/lex-depend-cxx.sh                   |   5 ++
 t/lex-depend-grep.sh                  |   2 +-
 t/list-of-tests.mk                    |   5 +-
 t/pr224.sh                            |   4 +-
 t/subobj-indir-pr13928.sh             |   4 +-
 t/subobj-pr13928-more-langs.sh        | 138 ++++++++++++++++++++++++++++++++++
 t/subobj-vpath-pr13928.sh             |  89 +++++++++++++++++++---
 t/subobj11b.sh                        |  10 +--
 t/subobj11c.sh                        |   2 +-
 21 files changed, 478 insertions(+), 192 deletions(-)
 rename t/{postproc.sh => depend-postproc.sh} (68%)
 create mode 100644 t/subobj-pr13928-more-langs.sh

--
2.1.3


Reply | Threaded
Open this post in threaded view
|

[PATCH 2/4] tests: fix some bugs in an XFAILing test

Stefano Lattarini
* t/subobj-vpath-pr13928.sh: This one. The test would have failed (or
hung!) even if the bug it was testing against were fixed.

Signed-off-by: Stefano Lattarini <[hidden email]>
---
 t/subobj-vpath-pr13928.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/t/subobj-vpath-pr13928.sh b/t/subobj-vpath-pr13928.sh
index 9c78d2e..8c3a6c5 100644
--- a/t/subobj-vpath-pr13928.sh
+++ b/t/subobj-vpath-pr13928.sh
@@ -33,7 +33,7 @@ AUTOMAKE_OPTIONS = subdir-objects
 noinst_PROGRAMS = test
 test_SOURCES = $(srcdir)/test.c
 test-objs:
- test ! -f $(srcdir)/test.$(OBJEXT)
+ test ! -f '@srcdir@/test.$(OBJEXT)'
  test -f test.$(OBJEXT)
 END
 
@@ -42,7 +42,7 @@ $ACLOCAL && $AUTOCONF && $AUTOMAKE -a || fatal_ "autotools failed"
 $EGREP 'test\.|DEPDIR|dirstamp|srcdir' Makefile.in || : # For debugging.
 $EGREP '\$.srcdir./test\.[o$]' Makefile.in && exit 1
 $FGREP '$(srcdir)/$(am__dirstamp)' Makefile.in && exit 1
-$FGREP '$(srcdir)/$(DEPDIR)' && exit 1
+$FGREP '$(srcdir)/$(DEPDIR)' Makefile.in && exit 1
 
 cat > test.c << 'END'
 int main (void)
--
2.1.3


Reply | Threaded
Open this post in threaded view
|

[PATCH 1/4] deps: 'subdir-object' option now works when foo_SOURCES contains $(var)

Stefano Lattarini
In reply to this post by Stefano Lattarini
Following a suggestions of Johan Kristensen, we have config.status use
'make' invocations rather than Makefile-parsing 'sed' hacks to bootstrap
the dependency-tracking '.Po' and '.Plo' makefile fragments. To handle
the inclusion of such files that are still missing when make is first
we basically generate a temporary Makefile without these includes, and
call 'make' on that Makefile.

This fixes the serious bug bug#13928, which was an hard blocker to make the
behavior mandated by the 'subdir-object' active by default (which we want
to do in Automake 2.0).

The issue has also been reported in bug#15919.

* NEWS, THANKS: Update.
* bin/automake.in (handle_languages): Add a trailing "marking" comment
("# am--include-marker") to the generated Makefile lines issuing 'include'
directives for the dependency-tracking '.Po' and '.Plo' makefile fragments.
Also rename the generated Makefile variable 'am__depfiles_maybe' to the
clearer 'am__maybe_remake_depfiles'.
Minor unrelated refactoring.
* lib/am/configure.am: Adjust to account for the 'am__depfiles_maybe' ->
'am__maybe_remake_depfiles' renaming.
* lib/am/depend.am: Add rules to generate a dummy version of all the
dependency-tracking '.Po' and '.Plo' makefile fragments.
* m4/depout.m4: Use make invocations rather than Makefile-parsing sed hacks
to bootstrap the dependency-tracking '.Po' and '.Plo' makefile fragments.
We still use some sed trickery in order to remove the inclusion of the
still non existing .Po and .Plo files from the Makefile we invoke make
upon; this is done stripping lines that contain the magic string
"# am--include-marker".
* m4/make.m4 (AM_MAKE_INCLUDE): Given that now automake generates Makefiles
containing include statements with trailing comment, adjust the checks done
here to make sure $MAKE support that; e.g., "include foo.mk # comment"
rather than just "include foo.mk".
Also refactor and adjust to leave better debugging info in config.log.
* t/postproc.sh: Rename ...
* t/depend-postproc.sh: ... to this, and adjust and enhance.
* t/list-of-tests.mk (handwritten_TESTS): Adjust.
(XFAIL_TESTS): Remove 't/subobj-indir-pr13928.sh', which is now succeeding.
* t/subobj-indir-pr13928.sh: Simplify slightly, now that we expect it to
pass.
* t/depcomp8a.sh: Adjust grepping check to account for the changes in
the generated Makefile, and tp be somewhat more robust in light of possible
future modifications.
* t/depcomp8b.sh: Likewise.
* t/subobj11b.sh: Likewise.
* t/subobj11c.sh: Likewise.
* t/extra-sources.sh: Likewise.
* t/lex-depend-grep.sh: Likewise.
* t/lex-depend-cxx.sh: Add a command to help debugging in case of test
failure.

Helped-by: Johan Kristensen <[hidden email]>
Signed-off-by: Stefano Lattarini <[hidden email]>
---
 NEWS                                  | 28 ++++++++++++
 THANKS                                |  1 +
 bin/automake.in                       | 84 ++++++++++++++++++-----------------
 lib/am/configure.am                   |  6 +--
 lib/am/depend.am                      |  7 +++
 m4/depout.m4                          | 78 ++++++++++++++------------------
 m4/make.m4                            | 59 +++++++++++-------------
 t/depcomp8a.sh                        | 16 +++----
 t/depcomp8b.sh                        | 16 +++----
 t/{postproc.sh => depend-postproc.sh} | 29 ++++++++++--
 t/extra-sources.sh                    |  5 ++-
 t/lex-depend-cxx.sh                   |  5 +++
 t/lex-depend-grep.sh                  |  2 +-
 t/list-of-tests.mk                    |  3 +-
 t/subobj-indir-pr13928.sh             |  4 +-
 t/subobj11b.sh                        | 10 ++---
 t/subobj11c.sh                        |  2 +-
 17 files changed, 203 insertions(+), 152 deletions(-)
 rename t/{postproc.sh => depend-postproc.sh} (68%)

diff --git a/NEWS b/NEWS
index 84a5e0a..a930049 100644
--- a/NEWS
+++ b/NEWS
@@ -62,6 +62,34 @@
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+New in 1.16:
+
+* Bugs fixed:
+
+  - Automatic dependency tracking has been fixed to work also when the
+    subdir-object option is used and some 'foo_SOURCES' definition contains
+    unexpanded references to make variables, as in, e.g.:
+
+        a_src = sources/libs/aaa
+        b_src = sources/bbb
+        foo_SOURCES = $(a_src)/bar.c $(b_src)/baz.c
+
+    With such a setup, the created makefile fragment containing dependency
+    tracking information will be correctly placed under the directories
+    named 'sources/libs/aaa/.deps' and 'sources/bbb/.deps', rather than
+    mistakenly under directories named (literally!) '$(src_a)/.deps' and
+    '$(src_b)/.deps' (this was automake bug#13928).
+
+    Notice that in order to fix this bug we had to slightly change the
+    semantics of how config.status bootstraps the makefile fragments
+    required for the dependency tracking to work: rather than attempting
+    to parse the Makefiles via grep and sed trickeries only, we actually
+    invoke 'make' on a slightly preprocessed version of those Makefiles,
+    using a private target that is only meant to bootstrap the required
+    makefile fragments.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 New in 1.15:
 
 * Improvements and refactorings in the install-sh script:
diff --git a/THANKS b/THANKS
index b66f744..8b87d58 100644
--- a/THANKS
+++ b/THANKS
@@ -192,6 +192,7 @@ Joel N. Weber II                [hidden email]
 Joerg-Martin Schwarz            [hidden email]
 Johan Dahlin                    [hidden email]
 Johan Danielsson                [hidden email]
+Johan Kristensen                [hidden email]
 Johannes Nicolai                [hidden email]
 John Calcote                    [hidden email]
 John F Trudeau                  [hidden email]
diff --git a/bin/automake.in b/bin/automake.in
index eedc8bc..f19be92 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -1230,48 +1230,50 @@ sub check_user_variables
 sub handle_languages ()
 {
     if (! option 'no-dependencies')
-    {
- # Include auto-dep code.  Don't include it if DEP_FILES would
- # be empty.
- if (keys %extension_seen && keys %dep_files)
- {
-    # Set location of depcomp.
-    define_variable ('depcomp',
-     "\$(SHELL) $am_config_aux_dir/depcomp",
-     INTERNAL);
-    define_variable ('am__depfiles_maybe', 'depfiles', INTERNAL);
-
-    require_conf_file ("$am_file.am", FOREIGN, 'depcomp');
-
-    my @deplist = sort keys %dep_files;
-    # Generate each 'include' individually.  Irix 6 make will
-    # not properly include several files resulting from a
-    # variable expansion; generating many separate includes
-    # seems safest.
-    $output_rules .= "\n";
-    foreach my $iter (@deplist)
-    {
- $output_rules .= (subst ('AMDEP_TRUE')
-  . subst ('am__include')
-  . ' '
-  . subst ('am__quote')
-  . $iter
-  . subst ('am__quote')
-  . "\n");
-    }
-
-    # Compute the set of directories to remove in distclean-depend.
-    my @depdirs = uniq (map { dirname ($_) } @deplist);
-    $output_rules .= file_contents ('depend',
-    new Automake::Location,
-    DEPDIRS => "@depdirs");
- }
-    }
+      {
+        # Include auto-dep code.  Don't include it if DEP_FILES would
+        # be empty.
+        if (keys %extension_seen && keys %dep_files)
+          {
+            my @dep_files = sort keys %dep_files;
+            # Set location of depcomp.
+            define_variable ('depcomp',
+                             "\$(SHELL) $am_config_aux_dir/depcomp",
+                             INTERNAL);
+            define_variable ('am__maybe_remake_depfiles', 'depfiles', INTERNAL);
+            define_variable ('am__depfiles_remade', "@dep_files", INTERNAL);
+            # Generate each 'include' directive individually.  Several make
+            # implementations (IRIX 6, Solaris 10, FreeBSD 8) will fail to
+            # properly include several files resulting from a variable
+            # expansion. Just Generating many separate includes seems thus
+            # safest.
+            $output_rules .= "\n";
+            foreach my $depfile (@dep_files)
+              {
+                $output_rules .= subst ('AMDEP_TRUE') .
+                                 subst ('am__include') .
+                                 " " .
+                                 subst('am__quote') .
+                                 $depfile .
+                                 subst('am__quote') .
+                                 " " .
+                                 "# am--include-marker\n";
+              }
+
+            require_conf_file ("$am_file.am", FOREIGN, 'depcomp');
+
+            # Compute the set of directories to remove in distclean-depend.
+            my @dep_dirs = uniq (map { dirname ($_) } @dep_files);
+            $output_rules .= file_contents ('depend',
+                                            new Automake::Location,
+                                            DEPDIRS => "@dep_dirs");
+          }
+      }
     else
-    {
- define_variable ('depcomp', '', INTERNAL);
- define_variable ('am__depfiles_maybe', '', INTERNAL);
-    }
+      {
+        define_variable ('depcomp', '', INTERNAL);
+        define_variable ('am__maybe_remake_depfiles', '', INTERNAL);
+      }
 
     my %done;
 
diff --git a/lib/am/configure.am b/lib/am/configure.am
index 34ebd17..a6086dd 100644
--- a/lib/am/configure.am
+++ b/lib/am/configure.am
@@ -76,10 +76,10 @@ endif %?TOPDIR_P%
 ?TOPDIR_P?    $(SHELL) ./config.status;; \
 ?!TOPDIR_P?    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
   *) \
-## FIXME: $(am__depfiles_maybe) lets us re-run the rule to create the
+## FIXME: $(am__maybe_remake_depfiles) lets us re-run the rule to create the
 ## .P files.  Ideally we wouldn't have to do this by hand.
-    echo ' cd $(top_builddir) && $(SHELL) ./config.status %CONFIG-MAKEFILE% $(am__depfiles_maybe)'; \
-    cd $(top_builddir) && $(SHELL) ./config.status %CONFIG-MAKEFILE% $(am__depfiles_maybe);; \
+    echo ' cd $(top_builddir) && $(SHELL) ./config.status %CONFIG-MAKEFILE% $(am__maybe_remake_depfiles)'; \
+    cd $(top_builddir) && $(SHELL) ./config.status %CONFIG-MAKEFILE% $(am__maybe_remake_depfiles);; \
  esac;
 
 ## Avoid the "deleted header file" problem for the dependencies.
diff --git a/lib/am/depend.am b/lib/am/depend.am
index 00ba5b3..0b226b6 100644
--- a/lib/am/depend.am
+++ b/lib/am/depend.am
@@ -16,6 +16,13 @@
 
 am__mv = mv -f
 
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+.PHONY: am--depfiles
+
 ## This Makefile depends on Depdirs' files, so we should never
 ## erase them in -am or -recursive rules; that would prevent any other
 ## rules from being recursive (for instance multilib clean rules are
diff --git a/m4/depout.m4 b/m4/depout.m4
index a59dcf5..2109bb3 100644
--- a/m4/depout.m4
+++ b/m4/depout.m4
@@ -6,7 +6,6 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-
 # _AM_OUTPUT_DEPENDENCY_COMMANDS
 # ------------------------------
 AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
@@ -14,49 +13,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   # Older Autoconf quotes --file arguments for eval, but not when files
   # are listed without --file.  Let's play safe and only enable the eval
   # if we detect the quoting.
-  case $CONFIG_FILES in
-  *\'*) eval set x "$CONFIG_FILES" ;;
-  *)   set x $CONFIG_FILES ;;
-  esac
+  # TODO: see whether this extra hack can be removed once we start
+  # requiring Autoconf 2.70 or later.
+  AS_CASE([$CONFIG_FILES],
+          [*\'*], [eval set x "$CONFIG_FILES"],
+          [*], [set x $CONFIG_FILES])
   shift
-  for mf
+  # Used to flag and report bootstrapping failures.
+  am_rc=0
+  for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    mf=`echo "$mf" | sed -e 's/:.*$//'`
-    # Check whether this is an Automake generated Makefile or not.
-    # We used to match only the files named 'Makefile.in', but
-    # some people rename them; so instead we look at the file content.
-    # Grep'ing the first line is not enough: some people post-process
-    # each Makefile.in and add a new line on top of each file to say so.
-    # Grep'ing the whole file is not good either: AIX grep has a line
+    am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile which includes
+    # dependency-tracking related rules and includes.
+    # Grep'ing the whole file directly is not great: AIX grep has a line
     # limit of 2048, but all sed's we know have understand at least 4000.
-    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
-      dirpart=`AS_DIRNAME("$mf")`
-    else
-      continue
-    fi
-    # Extract the definition of DEPDIR, am__include, and am__quote
-    # from the Makefile without running 'make'.
-    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
-    test -z "$DEPDIR" && continue
-    am__include=`sed -n 's/^am__include = //p' < "$mf"`
-    test -z "$am__include" && continue
-    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
-    # Find all dependency output files, they are included files with
-    # $(DEPDIR) in their names.  We invoke sed twice because it is the
-    # simplest approach to changing $(DEPDIR) to its actual value in the
-    # expansion.
-    for file in `sed -n "
-      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
-      # Make sure the directory exists.
-      test -f "$dirpart/$file" && continue
-      fdir=`AS_DIRNAME(["$file"])`
-      AS_MKDIR_P([$dirpart/$fdir])
-      # echo "creating $dirpart/$file"
-      echo '# dummy' > "$dirpart/$file"
-    done
+    sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \
+      || continue
+    am_dirpart=`AS_DIRNAME(["$am_mf"])`
+    am_filepart=`AS_BASENAME(["$am_mf"])`
+    AM_RUN_LOG([cd "$am_dirpart" \
+      && sed -e '/# am--include-marker/d' "$am_filepart" \
+        | $MAKE -f - am--depfiles]) || am_rc=$?
   done
+  if test $am_rc -ne 0; then
+    AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
+    for automatic dependency tracking.  Try re-running configure with the
+    '--disable-dependency-tracking' option to at least be able to build
+    the package (albeit without support for automatic dependency tracking).])
+  fi
+  AS_UNSET([am_dirpart])
+  AS_UNSET([am_filepart])
+  AS_UNSET([am_mf])
+  AS_UNSET([am_rc])
+  rm -f conftest-deps.mk
 }
 ])# _AM_OUTPUT_DEPENDENCY_COMMANDS
 
@@ -65,11 +56,10 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
 # -----------------------------
 # This macro should only be invoked once -- use via AC_REQUIRE.
 #
-# This code is only required when automatic dependency tracking
-# is enabled.  FIXME.  This creates each '.P' file that we will
-# need in order to bootstrap the dependency handling code.
+# This code is only required when automatic dependency tracking is enabled.
+# This creates each '.Po' and '.Plo' makefile fragment that we'll need in
+# order to bootstrap the dependency handling code.
 AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 [AC_CONFIG_COMMANDS([depfiles],
      [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
-     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
+     [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])])
diff --git a/m4/make.m4 b/m4/make.m4
index a82d2d2..f5520b1 100644
--- a/m4/make.m4
+++ b/m4/make.m4
@@ -8,42 +8,35 @@
 
 # AM_MAKE_INCLUDE()
 # -----------------
-# Check to see how make treats includes.
+# Check whether make has an 'include' directive that can support all
+# the idioms we need for our automatic dependency tracking code.
 AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
+[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive])
+cat > confinc.mk << 'END'
 am__doit:
- @echo this is the am__doit target
+ @echo this is the am__doit target >confinc.out
 .PHONY: am__doit
 END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
 am__include="#"
 am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from 'make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
-  am__include=include
-  am__quote=
-  _am_result=GNU
-  ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
-   echo '.include "confinc"' > confmf
-   case `$am_make -s -f confmf 2> /dev/null` in #(
-   *the\ am__doit\ target*)
-     am__include=.include
-     am__quote="\""
-     _am_result=BSD
-     ;;
-   esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
+# BSD make does it like this.
+echo '.include "confinc.mk" # ignored' > confmf.BSD
+# Other make implementations (GNU, Solaris 10, AIX) do it like this.
+echo 'include confinc.mk # ignored' > confmf.GNU
+_am_result=no
+for s in GNU BSD; do
+  AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out])
+  AS_CASE([$?:`cat confinc.out 2>/dev/null`],
+      ['0:this is the am__doit target'],
+      [AS_CASE([$s],
+          [BSD], [am__include='.include' am__quote='"'],
+          [am__include='include' am__quote=''])])
+  if test "$am__include" != "#"; then
+    _am_result="yes ($s style)"
+    break
+  fi
+done
+rm -f confinc.* confmf.*
+AC_MSG_RESULT([${_am_result}])
+AC_SUBST([am__include])])
+AC_SUBST([am__quote])])
diff --git a/t/depcomp8a.sh b/t/depcomp8a.sh
index 94b7afa..ee440ed 100644
--- a/t/depcomp8a.sh
+++ b/t/depcomp8a.sh
@@ -51,10 +51,10 @@ $ACLOCAL
 # FIXME: stop disabling the warnings in the 'unsupported' category
 # FIXME: once the 'subdir-objects' option has been mandatory.
 $AUTOMAKE -a -Wno-unsupported
-grep include Makefile.in # For debugging.
-grep 'include.*\./\$(DEPDIR)/foo\.P' Makefile.in
-grep 'include.*\./\$(DEPDIR)/bar\.P' Makefile.in
-grep 'include.*/\./\$(DEPDIR)' Makefile.in && exit 1
+grep '\.P' Makefile.in # For debugging.
+grep '\./\$(DEPDIR)/foo\.Po' Makefile.in
+grep '\./\$(DEPDIR)/bar\.Po' Makefile.in
+grep '/\./\$(DEPDIR)' Makefile.in && exit 1
 
 $AUTOCONF
 # Don't reject slower dependency extractors, for better coverage.
@@ -68,10 +68,10 @@ DISTCHECK_CONFIGURE_FLAGS='--enable-dependency-tracking' $MAKE distcheck
 echo AUTOMAKE_OPTIONS = subdir-objects >> Makefile.am
 
 $AUTOMAKE
-grep include Makefile.in # For debugging.
-grep 'include.*\./\$(DEPDIR)/foo\.P' Makefile.in
-grep 'include.*[^a-zA-Z0-9_/]sub/\$(DEPDIR)/bar\.P' Makefile.in
-$EGREP 'include.*/(\.|sub)/\$\(DEPDIR\)' Makefile.in && exit 1
+grep '\.P' Makefile.in # For debugging.
+grep '\./\$(DEPDIR)/foo\.Po' Makefile.in
+grep '[^a-zA-Z0-9_/]sub/\$(DEPDIR)/bar\.Po' Makefile.in
+$EGREP '/(\.|sub)/\$\(DEPDIR\)' Makefile.in && exit 1
 
 $AUTOCONF
 # Don't reject slower dependency extractors, for better coverage.
diff --git a/t/depcomp8b.sh b/t/depcomp8b.sh
index 47bf5c5..f1f65f3 100644
--- a/t/depcomp8b.sh
+++ b/t/depcomp8b.sh
@@ -48,10 +48,10 @@ $ACLOCAL
 # FIXME: stop disabling the warnings in the 'unsupported' category
 # FIXME: once the 'subdir-objects' option has been mandatory.
 $AUTOMAKE -a -Wno-unsupported
-grep include Makefile.in # For debugging.
-grep 'include.*\./\$(DEPDIR)/foo\.P' Makefile.in
-grep 'include.*\./\$(DEPDIR)/bar\.P' Makefile.in
-grep 'include.*/\./\$(DEPDIR)' Makefile.in && exit 1
+grep '\.P' Makefile.in # For debugging.
+grep '\./\$(DEPDIR)/foo\.Plo' Makefile.in
+grep '\./\$(DEPDIR)/bar\.Plo' Makefile.in
+grep '/\./\$(DEPDIR)' Makefile.in && exit 1
 
 $AUTOCONF
 # Don't reject slower dependency extractors, for better coverage.
@@ -64,10 +64,10 @@ DISTCHECK_CONFIGURE_FLAGS='--enable-dependency-tracking' $MAKE distcheck
 echo AUTOMAKE_OPTIONS += subdir-objects >> Makefile.am
 
 $AUTOMAKE
-grep include Makefile.in # For debugging.
-grep 'include.*\./\$(DEPDIR)/foo\.P' Makefile.in
-grep 'include.*[^a-zA-Z0-9_/]sub/\$(DEPDIR)/bar\.P' Makefile.in
-$EGREP 'include.*/(\.|sub)/\$\(DEPDIR\)' Makefile.in && exit 1
+grep '\.P' Makefile.in # For debugging.
+grep '\./\$(DEPDIR)/foo\.Plo' Makefile.in
+grep '[^a-zA-Z0-9_/]sub/\$(DEPDIR)/bar\.Plo' Makefile.in
+$EGREP '/(\.|sub)/\$\(DEPDIR\)' Makefile.in && exit 1
 
 $AUTOCONF
 # Don't reject slower dependency extractors, for better coverage.
diff --git a/t/postproc.sh b/t/depend-postproc.sh
similarity index 68%
rename from t/postproc.sh
rename to t/depend-postproc.sh
index 3ac64a4..74088db0 100644
--- a/t/postproc.sh
+++ b/t/depend-postproc.sh
@@ -15,20 +15,22 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Check to make sure we recognize a Makefile.in, even if post-processed
-# and renamed.
+# and renamed.  The particularly tricky code for automatic dependency
+# tracking support used to have issues with that.
 
 required=cc
 . test-init.sh
 
-cat >configure.ac <<END
+cat > configure.ac <<END
 AC_INIT([$me], [1.0])
 AM_INIT_AUTOMAKE
 AC_PROG_CC
 AC_CONFIG_FILES([myMakefile])
+dnl: AC_CONFIG_LINKS([Makefile:Makefile])
 AC_OUTPUT
 END
 
-cat > myMakefile.am << 'END'
+cat > myMakefile.am <<'END'
 bin_PROGRAMS = fred
 fred_SOURCES = fred.c
 END
@@ -45,4 +47,25 @@ cat myMakefile.old >> myMakefile.in
 
 test -f .deps/fred.Po || test -f _deps/fred.Po || exit 1
 
+$sleep
+
+cat > Makefile <<'END'
+include myMakefile
+END
+
+sed 's/^dnl: *//' configure.ac >t
+mv -f t configure.ac
+
+$MAKE myMakefile Makefile
+
+rm -rf .deps _deps
+./config.status
+
+test ! -e fred.c
+echo 'int main (void) { return 0; }' > fred.c
+
+$MAKE
+test -f .deps/fred.Po || test -f _deps/fred.Po || exit 1
+$MAKE distcheck
+
 :
diff --git a/t/extra-sources.sh b/t/extra-sources.sh
index e3f15c8..8e204a5 100644
--- a/t/extra-sources.sh
+++ b/t/extra-sources.sh
@@ -21,7 +21,7 @@
 
 echo AC_PROG_CC >> configure.ac
 
-cat > Makefile.am << 'END'
+cat > Makefile.am <<'END'
 bin_PROGRAMS = www
 www_SOURCES = www.c
 EXTRA_www_SOURCES = xtra.c
@@ -31,6 +31,7 @@ END
 $ACLOCAL
 $AUTOMAKE
 
-grep '@am__include@ .*/xtra\.P' Makefile.in
+grep '@am__include@ .*/xtra\.Po' Makefile.in
+grep '^am__depfiles_remade =.*/xtra.Po' Makefile.in
 
 :
diff --git a/t/lex-depend-cxx.sh b/t/lex-depend-cxx.sh
index 2abb101..eee2f5c 100644
--- a/t/lex-depend-cxx.sh
+++ b/t/lex-depend-cxx.sh
@@ -82,6 +82,11 @@ $AUTOCONF
 # using slow dependency extractors.
 ./configure --enable-dependency-tracking
 
+# For debugging.
+for f in $(find . -name '*.Po'); do
+  cat $f
+done
+
 $MAKE test-deps-exist
 $MAKE
 
diff --git a/t/lex-depend-grep.sh b/t/lex-depend-grep.sh
index 4a6473b..be9be29 100644
--- a/t/lex-depend-grep.sh
+++ b/t/lex-depend-grep.sh
@@ -40,7 +40,7 @@ $AUTOMAKE -a
 $EGREP '([mj]oe|_[01234]|include|\.P)' Makefile.in # For debugging.
 
 for x in joe moe _0 _1 _2 _3 _4; do
-  grep "include.*$x\.Po" Makefile.in
+  $EGREP '\$\(DEPDIR\)/'"$x"'\.Po( |$)' Makefile.in
 done
 
 :
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index 9363ee3..5085780 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -41,7 +41,6 @@ t/java-nobase.sh \
 t/objext-pr10128.sh \
 t/remake-timing-bug-pr8365.sh \
 t/lex-subobj-nodep.sh \
-t/subobj-indir-pr13928.sh \
 t/subobj-vpath-pr13928.sh \
 t/remake-am-pr10111.sh \
 t/remake-m4-pr10111.sh \
@@ -391,6 +390,7 @@ t/depend3.sh \
 t/depend4.sh \
 t/depend5.sh \
 t/depend6.sh \
+t/depend-postproc.sh \
 t/deprecated-acinit.sh \
 t/destdir.sh \
 t/dir-named-obj-is-bad.sh \
@@ -866,7 +866,6 @@ t/posixsubst-programs.sh \
 t/posixsubst-scripts.sh \
 t/posixsubst-sources.sh \
 t/posixsubst-tests.sh \
-t/postproc.sh \
 t/ppf77.sh \
 t/pr2.sh \
 t/pr9.sh \
diff --git a/t/subobj-indir-pr13928.sh b/t/subobj-indir-pr13928.sh
index 22cb7f5..3ccd037 100644
--- a/t/subobj-indir-pr13928.sh
+++ b/t/subobj-indir-pr13928.sh
@@ -38,7 +38,9 @@ END
 mkdir s
 echo 'int main(void) { return 0; }' > s/foo.c
 
-$ACLOCAL && $AUTOCONF && $AUTOMAKE -a || fatal_ "autotools failed"
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
 
 ./configure
 $MAKE
diff --git a/t/subobj11b.sh b/t/subobj11b.sh
index 5ebb42a..613fa26 100644
--- a/t/subobj11b.sh
+++ b/t/subobj11b.sh
@@ -56,9 +56,9 @@ END
 $ACLOCAL
 $AUTOMAKE -a
 
-# Be lax in the regexp, to account for automake conditionals, the
-# use of @am__include@, and similar stuff.
-grep 'include.*//.*foobar' Makefile.in && exit 1
+grep '\.P' Makefile.in # For debugging.
+
+grep '//.*foobar\.P' Makefile.in && exit 1
 
 # These checks depend on automake internals, but presently this is
 # the only way to test the code path we are interested in.
@@ -71,12 +71,12 @@ for x in zardoz0 zardoz1 path/to/zardoz2 another/path/to/zardoz3; do
   esac
   # Be a little lax in the regexp, to account for automake conditionals,
   # quoting, and similar stuff.
-  grep "^[^/]*am__include[^/]*//server/$d\\\$(DEPDIR)/$b\\.[^/]*$" Makefile.in
+  grep "[ ]//server/$d\\\$(DEPDIR)/$b\\.Po" Makefile.in
 done
 
 # Sanity checks.
 for i in 0 1 2 3 4 5 6 7 8 9; do
-  grep "am__include.*/foobar$i\\." Makefile.in
+  grep "\$(DEPDIR)/foobar$i\\.Po" Makefile.in
 done
 
 :
diff --git a/t/subobj11c.sh b/t/subobj11c.sh
index a80d760..f5e8340 100644
--- a/t/subobj11c.sh
+++ b/t/subobj11c.sh
@@ -43,6 +43,6 @@ $AUTOMAKE -a
 #
 # FIXME: Are we sure this is the most sensible output in our situation?
 #
-grep '^[^/]*am__include[^/]*//\$(DEPDIR)/zardoz\.[^/]*$' Makefile.in
+grep 'am__depfiles_remade =.* //\$(DEPDIR)/zardoz\.Po' Makefile.in
 
 :
--
2.1.3


Reply | Threaded
Open this post in threaded view
|

[PATCH 3/4] compile: don't place built object files in $(srcdir), ever ...

Stefano Lattarini
In reply to this post by Stefano Lattarini
... even when a source file is specified as '$(srdir)/foo.c' or
'$(top_srcdir)/bar.c'. And ditto for dependency-tracking makefile
fragments (those under '.deps' directories).

Such issues used to occur when the 'subdir-objects' option was given.

This change should fix the second and last part of automake bug#13928.
See also bug#16375 and bug#15293.

* NEWS: Update.
* bin/automake.in (handle_single_transform): Make sure object files
and dependency-tracking makefile fragments coming from source like
'$(srcdir)/foo.c' and '$(top_srcdir)/bar.c' are placed respectively
under $(builddir) and $(top_builddir).
* t/subobj-vpath-pr13928.sh: Enhance to expose even more aspects
of the bug we've just fixed.
* t/subobj-pr13928-more-langs.sh: New test, similar to the one above,
but with non-C languages as well.
* t/list-of-tests.mk (XFAIL_TESTS): Remove 'subobj-vpath-pr13928.sh',
it's now supposed to pass.
(handwritten_TESTS): Add 'subobj-pr13928-more-langs.sh'.

Signed-off-by: Stefano Lattarini <[hidden email]>
---
 NEWS                           |  21 ++++++-
 bin/automake.in                |  50 ++++++++++-----
 t/list-of-tests.mk             |   2 +-
 t/subobj-pr13928-more-langs.sh | 138 +++++++++++++++++++++++++++++++++++++++++
 t/subobj-vpath-pr13928.sh      |  89 ++++++++++++++++++++++----
 5 files changed, 269 insertions(+), 31 deletions(-)
 create mode 100644 t/subobj-pr13928-more-langs.sh

diff --git a/NEWS b/NEWS
index a930049..eb3bc6f 100644
--- a/NEWS
+++ b/NEWS
@@ -67,8 +67,8 @@ New in 1.16:
 * Bugs fixed:
 
   - Automatic dependency tracking has been fixed to work also when the
-    subdir-object option is used and some 'foo_SOURCES' definition contains
-    unexpanded references to make variables, as in, e.g.:
+    'subdir-object' option is used and some 'foo_SOURCES' definition
+    contains unexpanded references to make variables, as in, e.g.:
 
         a_src = sources/libs/aaa
         b_src = sources/bbb
@@ -78,7 +78,7 @@ New in 1.16:
     tracking information will be correctly placed under the directories
     named 'sources/libs/aaa/.deps' and 'sources/bbb/.deps', rather than
     mistakenly under directories named (literally!) '$(src_a)/.deps' and
-    '$(src_b)/.deps' (this was automake bug#13928).
+    '$(src_b)/.deps' (this was the first part of automake bug#13928).
 
     Notice that in order to fix this bug we had to slightly change the
     semantics of how config.status bootstraps the makefile fragments
@@ -88,6 +88,21 @@ New in 1.16:
     using a private target that is only meant to bootstrap the required
     makefile fragments.
 
+  - The 'subdir-object' option no longer causes object files corresponding
+    to source files specified with an explicit '$(srcdir)' component to be
+    placed in the source tree rather than in the build tree.
+
+    For example, if Makefile.am contains:
+
+        AUTOMAKE_OPTIONS = subdir-objects
+        foo_SOURCES = $(srcdir)/foo.c $(srcdir)/s/bar.c $(top_srcdir)/baz.c
+
+    then "make all" will create 'foo.o' and 's/bar.o' in $(builddir) rather
+    than in $(srcdir), and will create 'baz.o' in $(top_builddir) rather
+    than in $(top_srcdir).
+
+    This was the second part of automake bug#13928.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 New in 1.15:
diff --git a/bin/automake.in b/bin/automake.in
index f19be92..d8ecca5 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -1617,9 +1617,9 @@ sub handle_single_transform
  my $renamed = 0;
  my ($linker, $object);
 
- # This records whether we've seen a derived source file (e.g.
- # yacc output).
- my $derived_source = 0;
+        # This records whether we've seen a derived source file (e.g., yacc
+        # or lex output).
+        my $derived_source;
 
  # This holds the 'aggregate context' of the file we are
  # currently examining.  If the file is compiled with
@@ -1667,17 +1667,36 @@ sub handle_single_transform
     # Now extract linker and other info.
     $linker = $lang->linker;
 
-    my $this_obj_ext;
-    if (defined $source_extension)
-    {
- $this_obj_ext = $source_extension;
- $derived_source = 1;
-    }
-    else
-    {
- $this_obj_ext = $obj;
-    }
-    $object = $base . $this_obj_ext;
+            my $this_obj_ext;
+            if (defined $source_extension)
+              {
+                $this_obj_ext = $source_extension;
+                $derived_source = 1;
+              }
+            else
+              {
+                $this_obj_ext = $obj;
+                $derived_source = 0;
+                # Don't ever place built object files in $(srcdir),
+                # even when sources are specified explicitly as (say)
+                # '$(srcdir)/foo.c' or '$(top_srcdir)/foo.c'.
+                # See automake bug#13928.
+                my @d = split '/', $directory;
+                if (@d > 0 && option 'subdir-objects')
+                  {
+                    my $d = $d[0];
+                    if ($d eq '$(srcdir)' or $d eq '${srcdir}')
+                      {
+                        shift @d;
+                      }
+                    elsif ($d eq '$(top_srcdir)' or $d eq '${top_srcdir}')
+                      {
+                        $d[0] = '$(top_builddir)';
+                      }
+                    $directory = join '/', @d;
+                  }
+              }
+            $object = $base . $this_obj_ext;
 
     if ($have_per_exec_flags)
     {
@@ -1710,8 +1729,7 @@ sub handle_single_transform
  $renamed = 1;
     }
 
-    # If rewrite said it was ok, put the object into a
-    # subdir.
+    # If rewrite said it was ok, put the object into a subdir.
     if ($directory ne '')
     {
               if ($r == LANG_SUBDIR)
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index 5085780..ddf5fdf 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -41,7 +41,6 @@ t/java-nobase.sh \
 t/objext-pr10128.sh \
 t/remake-timing-bug-pr8365.sh \
 t/lex-subobj-nodep.sh \
-t/subobj-vpath-pr13928.sh \
 t/remake-am-pr10111.sh \
 t/remake-m4-pr10111.sh \
 $(perl_fake_XFAIL_TESTS)
@@ -1063,6 +1062,7 @@ t/subobj-clean-pr10697.sh \
 t/subobj-clean-lt-pr10697.sh \
 t/subobj-indir-pr13928.sh \
 t/subobj-vpath-pr13928.sh \
+t/subobj-pr13928-more-langs.sh \
 t/subpkg.sh \
 t/subpkg2.sh \
 t/subpkg3.sh \
diff --git a/t/subobj-pr13928-more-langs.sh b/t/subobj-pr13928-more-langs.sh
new file mode 100644
index 0000000..323e248
--- /dev/null
+++ b/t/subobj-pr13928-more-langs.sh
@@ -0,0 +1,138 @@
+#! /bin/sh
+# Copyright (C) 2015 Free Software Foundation, Inc.
+#
+# This program 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.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Expose part of automake bug#13928, also for non-C languages: if the
+# subdir-objects option is in use and a source file is listed in a
+# _SOURCES variable with a leading $(srcdir) component, Automake will
+# generate a Makefile that tries to create the corresponding object
+# file in $(srcdir) as well.
+
+required='cc c++ fortran77 fortran'
+. test-init.sh
+
+cat >> configure.ac <<'END'
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_F77
+AC_PROG_FC
+AM_CONDITIONAL([OBVIOUS], [:])
+AC_CONFIG_FILES([sub/Makefile])
+AC_OUTPUT
+END
+
+cat > Makefile.am <<'END'
+AUTOMAKE_OPTIONS = subdir-objects
+SUBDIRS = sub
+
+LESS = m/o/r/e
+
+noinst_PROGRAMS = test test2
+test_SOURCES = $(srcdir)/test.f90
+
+test2_SOURCES = $(indir)
+
+indir = ${indir2} $(empty)
+indir2 =
+if OBVIOUS
+indir2 += ${srcdir}/$(LESS)///test.f
+else
+endif
+
+test-objs:
+ ls -la @srcdir@ .
+        :
+ test ! -f @srcdir@/test.$(OBJEXT)
+ test -f test.$(OBJEXT)
+ test ! -f @srcdir@/m/o/r/e/test.$(OBJEXT)
+ test -f m/o/r/e/test.$(OBJEXT)
+        :
+ test ! -f @srcdir@/bar.$(OBJEXT)
+ test -f bar.$(OBJEXT)
+ test ! -f @srcdir@/baz.$(OBJEXT)
+ test -f baz.$(OBJEXT)
+        :
+ test ! -d @srcdir@/$(DEPDIR)
+ test ! -d @srcdir@/m/o/r/e/$(DEPDIR)
+ test -d $(DEPDIR)
+ test -d m/o/r/e/$(DEPDIR)
+
+check-local: test-objs
+END
+
+mkdir sub
+cat > sub/Makefile.am <<'END'
+AUTOMAKE_OPTIONS = subdir-objects
+bin_PROGRAMS = foo
+foo = baz
+foo_SOURCES = foo.h \
+      $(top_srcdir)/bar.cc \
+              ${top_srcdir}/$(foo).c
+END
+
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+
+mkfiles='Makefile.in sub/Makefile.in'
+$EGREP '(test|ba[rz])\.|DEPDIR|dirstamp|srcdir' $mkfiles # For debugging.
+$EGREP '\$.(top_)?srcdir./(test|ba[rz]|\$.foo.)\.[o$]' $mkfiles && exit 1
+$FGREP '\$.(top_)?srcdir./.*$(am__dirstamp)' $mkfiles && exit 1
+$FGREP '\$.(top_)?srcdir./.*$(DEPDIR)' $mkfiles && exit 1
+
+cat > test.f90 <<'EOF'
+      program foo
+      stop
+      end
+EOF
+
+mkdir -p m/o/r/e
+cp test.f90 m/o/r/e/test.f
+
+cat > sub/foo.h <<'END'
+#ifdef __cplusplus
+extern "C"
+#endif
+int foo (void);
+END
+
+cat > bar.cc <<'END'
+#include "foo.h"
+#include <iostream>
+int main (void)
+{
+  std::cout << "OK!" << "\n";
+  return foo ();
+}
+END
+
+cat > baz.c <<'END'
+#include "foo.h"
+int foo (void)
+{
+  return 0;
+}
+END
+
+mkdir build
+cd build
+../configure
+
+$MAKE
+$MAKE test-objs
+$MAKE distcheck
+
+:
diff --git a/t/subobj-vpath-pr13928.sh b/t/subobj-vpath-pr13928.sh
index 8c3a6c5..24eff1d 100644
--- a/t/subobj-vpath-pr13928.sh
+++ b/t/subobj-vpath-pr13928.sh
@@ -22,39 +22,106 @@
 required=cc
 . test-init.sh
 
-cat >> configure.ac << 'END'
+cat >> configure.ac <<'END'
 AC_PROG_CC
 AM_PROG_CC_C_O
+AM_CONDITIONAL([OBVIOUS], [:])
+AC_CONFIG_FILES([sub/Makefile])
 AC_OUTPUT
 END
 
 cat > Makefile.am <<'END'
 AUTOMAKE_OPTIONS = subdir-objects
-noinst_PROGRAMS = test
+SUBDIRS = sub
+
+LESS = more
+
+noinst_PROGRAMS = test test2
 test_SOURCES = $(srcdir)/test.c
+
+test2_SOURCES = $(indir)
+
+indir =
+if OBVIOUS
+indir += ${srcdir}/$(LESS)/test.c
+else
+endif
+
 test-objs:
- test ! -f '@srcdir@/test.$(OBJEXT)'
+ ls -la @srcdir@ .
+        :
+ test ! -f @srcdir@/test.$(OBJEXT)
  test -f test.$(OBJEXT)
+ test ! -f @srcdir@/more/test.$(OBJEXT)
+ test -f more/test.$(OBJEXT)
+        :
+ test ! -f @srcdir@/bar.$(OBJEXT)
+ test -f bar.$(OBJEXT)
+ test ! -f @srcdir@/baz.$(OBJEXT)
+ test -f baz.$(OBJEXT)
+        :
+ test ! -d @srcdir@/$(DEPDIR)
+ test ! -d @srcdir@/more/$(DEPDIR)
+ test -d $(DEPDIR)
+ test -d more/$(DEPDIR)
+
+check-local: test-objs
+END
+
+mkdir sub
+cat > sub/Makefile.am <<'END'
+AUTOMAKE_OPTIONS = subdir-objects
+bin_PROGRAMS = foo
+foo_SOURCES = foo.h \
+      $(top_srcdir)/bar.c \
+              ${top_srcdir}/baz.c
+END
+
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+
+mkfiles='Makefile.in sub/Makefile.in'
+$EGREP '(test|ba[rz])\.|DEPDIR|dirstamp|srcdir' $mkfiles # For debugging.
+$EGREP '\$.(top_)?srcdir./(test|ba[rz])\.[o$]' $mkfiles && exit 1
+$FGREP '\$.(top_)?srcdir./.*$(am__dirstamp)' $mkfiles && exit 1
+$FGREP '\$.(top_)?srcdir./.*$(DEPDIR)' $mkfiles && exit 1
+
+cat > test.c <<'END'
+int main (void)
+{
+  return 0;
+}
 END
 
-$ACLOCAL && $AUTOCONF && $AUTOMAKE -a || fatal_ "autotools failed"
+mkdir more
+cp test.c more/test.c
 
-$EGREP 'test\.|DEPDIR|dirstamp|srcdir' Makefile.in || : # For debugging.
-$EGREP '\$.srcdir./test\.[o$]' Makefile.in && exit 1
-$FGREP '$(srcdir)/$(am__dirstamp)' Makefile.in && exit 1
-$FGREP '$(srcdir)/$(DEPDIR)' Makefile.in && exit 1
+echo 'int foo (void);' > sub/foo.h
 
-cat > test.c << 'END'
+cat > bar.c <<'END'
+#include "foo.h"
 int main (void)
 {
+  return foo ();
+}
+END
+
+cat > baz.c <<'END'
+#include "foo.h"
+int foo (void)
+{
   return 0;
 }
 END
 
-mkdir build && cd build || fatal "preparation of build directory failed"
-../configure || fatal_ "./configure failed"
+mkdir build
+cd build
+../configure
 
 $MAKE
 $MAKE test-objs
+$MAKE distcheck
 
 :
--
2.1.3


Reply | Threaded
Open this post in threaded view
|

[PATCH 4/4] deps: fix corner-case "make distclean" bug

Stefano Lattarini
In reply to this post by Stefano Lattarini
Assume we have package satisfying the following conditions:
  (1) automatic dependency tracking is enabled;
  (2) the 'subdir-objects' Automake option is enabled;
  (3) the package uses a recursive make setup.

Also assume that:
  (a) a subdir Makefile declares a foo_SOURCES variable containing
      a source file in the parent directory;
  (b) that parent Makefile declare a compiled program itself.

Then BSD and Solaris make used to fail when running "make distclean",
because the 'distclean' target of the subdir Makefile removed the
whole '.deps' directory before the parent Makefile was done with the
included '.Po' makefile fragments in that directory. This issue was
revealed by failures in the 'subobj-vpath-pr13928.sh' test when those
make implementations were used.

We fix the issue by ensuring the 'distclean' target of any Makefile
only removed the '.Po' makefile fragments included by it, rather than
the whole '.deps' directory where such files resides.

This change should be the last step in fixing automake bug#13928
for good.

* bin/automake.in (handle_languages), lib/am/depend.am: Adjust
to implement the new 'distclean' logic.
* t/pr224.sh: Adjust to avoid a spurious failure.
* PLANS/subdir-objects.txt: Update.

Signed-off-by: Stefano Lattarini <[hidden email]>
---
 PLANS/subdir-objects.txt | 10 +++-------
 bin/automake.in          | 20 ++++++++++----------
 lib/am/depend.am         |  7 ++++---
 t/pr224.sh               |  4 ++--
 4 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/PLANS/subdir-objects.txt b/PLANS/subdir-objects.txt
index 3cf6101..c849e33 100644
--- a/PLANS/subdir-objects.txt
+++ b/PLANS/subdir-objects.txt
@@ -5,9 +5,6 @@ We want to make the behaviour currently enabled by the 'subdir-objects'
 the default one, and in fact the *only* one, in Automake 2.0.
 See automake bug#13378: <http://debbugs.gnu.org/13378>.
 
-Sadly, **THIS IS IMPOSSIBLE** until automake bug#13928 is resolved:
-http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13928
-
 Details
 -------
 
@@ -53,11 +50,10 @@ We also make sure to avoid the warning when it would be irrelevant, i.e.,
 if all source files sit in "current" directory (thanks to Peter Johansson
 for suggesting this).
 
-For some automake 1.x (*before* 2.0 can be released)
-----------------------------------------------------
+For automake 1.16 (*before* 2.0 can be released)
+------------------------------------------------
 
-Find a proper way to fix the blocking automake bug#13928:
-http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13928
+Submit the pending patch series that fixes http://debbugs.gnu.org/13928
 
 For automake 2.0
 ----------------
diff --git a/bin/automake.in b/bin/automake.in
index d8ecca5..21cccbe 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -1242,14 +1242,16 @@ sub handle_languages ()
                              INTERNAL);
             define_variable ('am__maybe_remake_depfiles', 'depfiles', INTERNAL);
             define_variable ('am__depfiles_remade', "@dep_files", INTERNAL);
-            # Generate each 'include' directive individually.  Several make
-            # implementations (IRIX 6, Solaris 10, FreeBSD 8) will fail to
-            # properly include several files resulting from a variable
-            # expansion. Just Generating many separate includes seems thus
-            # safest.
             $output_rules .= "\n";
+            my @dist_rms;
             foreach my $depfile (@dep_files)
               {
+                push @dist_rms, "\t-rm -f $depfile";
+                # Generate each 'include' directive individually.  Several
+                # make implementations (IRIX 6, Solaris 10, FreeBSD 8) will
+                # fail to properly include several files resulting from a
+                # variable expansion. Just Generating many separate includes
+                # seems thus safest.
                 $output_rules .= subst ('AMDEP_TRUE') .
                                  subst ('am__include') .
                                  " " .
@@ -1262,11 +1264,9 @@ sub handle_languages ()
 
             require_conf_file ("$am_file.am", FOREIGN, 'depcomp');
 
-            # Compute the set of directories to remove in distclean-depend.
-            my @dep_dirs = uniq (map { dirname ($_) } @dep_files);
-            $output_rules .= file_contents ('depend',
-                                            new Automake::Location,
-                                            DEPDIRS => "@dep_dirs");
+            $output_rules .= file_contents (
+                'depend', new Automake::Location,
+                'DISTRMS' => join ("\n", @dist_rms));
           }
       }
     else
diff --git a/lib/am/depend.am b/lib/am/depend.am
index 0b226b6..3813996 100644
--- a/lib/am/depend.am
+++ b/lib/am/depend.am
@@ -27,8 +27,9 @@ am--depfiles: $(am__depfiles_remade)
 ## erase them in -am or -recursive rules; that would prevent any other
 ## rules from being recursive (for instance multilib clean rules are
 ## recursive).
+if %?DISTRMS%
 distclean:
- -rm -rf %DEPDIRS%
-
+ %DISTRMS%
 maintainer-clean:
- -rm -rf %DEPDIRS%
+ %DISTRMS%
+endif
diff --git a/t/pr224.sh b/t/pr224.sh
index fcea148..1961786 100644
--- a/t/pr224.sh
+++ b/t/pr224.sh
@@ -56,8 +56,8 @@ cd build
 ../configure
 
 $MAKE
-test -d foo/.deps
+test -f foo/.deps/main.Po
 $MAKE distclean
-test -d foo/.deps && exit 1
+test ! -e foo/.deps/main.Po
 
 :
--
2.1.3