* Ralf Wildenhues wrote on Mon, Nov 01, 2010 at 10:18:55PM CET:
> 3) The rules to update Makefile, but also those to update and
> Makefile.in, are broken in some circumstances, too.
[...]
> I'm not sure how useful it is to fix (3).  It is not easy as a user to
> get GNU make to not update any of the dependencies of the Makefile file,
> thanks to its remaking feature (info make "Remaking Makefiles").  I'll
> reply with a patch for the 'Makefile' rule, but in order to expose that
> bug, you need to use something like this in a subdirectory of a package:
>   make -n Makefile AM_MAKEFLAGS="-n Makefile"
> 
> I don't think users go to this extent just to have `make -n' work, and
> they definitely won't get the above right on the first try; but then the
> rebuild will already have kicked in, making the issue moot for the
> second try.

Here it is.

Cheers,
Ralf

    Fix GNU `make -n Makefile' in subdirs to not touch the tree.
    
    * lib/am/configure.am (%MAKEFILE%): Split rule in nonrecursive
    and possibly-recursive parts, for GNU `make -n'.
    * tests/remakedry.test: New test.
    * tests/Makefile.am (TESTS): Update.
    * NEWS: Update.

diff --git a/NEWS b/NEWS
index 6bc0d6f..76e6543 100644
--- a/NEWS
+++ b/NEWS
@@ -48,7 +48,7 @@ Bugs fixed in 1.11.0a:
 
   - Rules generated by Automake now try harder to not change any files when
     `make -n' is invoked.  Fixes include compilation of Emacs Lisp, Vala, or
-    Yacc source files and the rule to update config.h.
+    Yacc source files and the rules to update config.h and a subdir Makefile.
 
 New in 1.11:
 
diff --git a/lib/am/configure.am b/lib/am/configure.am
index e9299d6..c10b377 100644
--- a/lib/am/configure.am
+++ b/lib/am/configure.am
@@ -1,5 +1,5 @@
 ## automake - create Makefile.in from Makefile.am
-## Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009  Free
+## Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010 Free
 ## Software Foundation, Inc.
 
 ## This program is free software; you can redistribute it and/or modify
@@ -75,12 +75,16 @@ endif %?TOPDIR_P%
 ?TOPDIR_P?         echo ' $(SHELL) ./config.status'; \
 ?TOPDIR_P?         $(SHELL) ./config.status;; \
 ?!TOPDIR_P?        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; 
\
+       esac
+## Split the nonrecursive part off, so GNU `make -n' will not execute it.
+       @case '$?' in \
+         *config.status*) ;;\
          *) \
 ## FIXME: $(am__depfiles_maybe) 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);; \
-       esac;
+       esac
 
 DIST_COMMON += %MAKEFILE-AM%
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9c81564..a9aca1e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -619,6 +619,7 @@ remake4.test \
 remake5.test \
 remake6.test \
 remake7.test \
+remakedry.test \
 regex.test \
 req.test \
 reqd.test \
diff --git a/tests/remakedry.test b/tests/remakedry.test
new file mode 100755
index 0000000..dab46f3
--- /dev/null
+++ b/tests/remakedry.test
@@ -0,0 +1,82 @@
+#! /bin/sh
+# Copyright (C) 2010 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/>.
+
+# Make sure GNU `make -n' doesn't trigger file updates when Makefile
+# is out of date.
+
+# The subdir rebuilding rules rely on GNU make automatically updating
+# the makefile and its prerequisites (through am--refresh).
+required=GNUmake
+. ./defs || Exit 1
+
+set -e
+
+cat >> configure.in << 'END'
+AC_CONFIG_FILES([sub/Makefile])
+AC_OUTPUT
+END
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub
+END
+mkdir sub
+: > sub/Makefile.am
+
+$ACLOCAL
+$AUTOMAKE
+$AUTOCONF
+./configure
+$MAKE
+
+# The toplevel rule is not problematic, as it is not recursive.
+$sleep
+touch Makefile.in
+$sleep
+$MAKE -n Makefile
+test `ls -1t Makefile Makefile.in | sed 1q` = Makefile.in
+$MAKE Makefile
+test `ls -1t Makefile Makefile.in | sed 1q` = Makefile
+
+$sleep
+touch config.status
+$sleep
+$MAKE -n Makefile
+test `ls -1t Makefile config.status | sed 1q` = config.status
+$MAKE Makefile
+test `ls -1t Makefile config.status | sed 1q` = Makefile
+
+# The subdir rules are fixed by separating the recursive part from the rest.
+cd sub
+$sleep
+touch Makefile.in
+$sleep
+$MAKE -n Makefile
+test `ls -1t Makefile Makefile.in | sed 1q` = Makefile.in
+$MAKE Makefile
+test `ls -1t Makefile Makefile.in | sed 1q` = Makefile
+cd ..
+
+$sleep
+touch config.status
+$sleep
+# Go through contortions to avoid GNU make's first, internal "rebuild Makefile
+# even in dry mode" cycle in the recursive (am--refresh) part.
+(cd sub && $MAKE -n Makefile AM_MAKEFLAGS="-n Makefile")
+test `ls -1t sub/Makefile config.status | sed 1q` = config.status
+(cd sub && $MAKE Makefile)
+test `ls -1t sub/Makefile config.status | sed 1q` = sub/Makefile
+
+:

Reply via email to