automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] recursion: support user-defined recursive targets


From: Stefano Lattarini
Subject: [RFC] recursion: support user-defined recursive targets
Date: Fri, 29 Jun 2012 19:46:21 +0200

The user can now define his own recursive targets that recurse
in the directories specified in $(SUBDIRS).  That can be done by
specifying the name of such targets in invocations of the new
'AM_EXTRA_RECURSIVE_TARGETS' m4 macro.

The API goes like this:

    $ cat configure.ac
    AC_INIT([pkg-name], [1.0]
    AM_INIT_AUTOMAKE
    AM_EXTRA_RECURSIVE_TARGETS([foo])
    AC_CONFIG_FILES([Makefile sub/Makefile])
    AC_OUTPUT

    $ cat Makefile.am
    SUBDIRS = sub
    foo-local:
        @echo This will be run by "make foo".

    $ cat sub/Makefile.am
    foo-local:
        @echo This too will be run by a "make foo" issued either in
        @echo the 'sub/' directory or in the top-level directory.

Like for the "default" recursive targets (e.g., 'all' and 'check'),
the user-defined recursive targets descend in the $(SUBDIRS) in a
depth-first fashion, and process '.' last (unless that is explicitly
specified in $(SUBDIRS)).

* NEWS, doc/automake.texi: Document the new feature.
* automake.in (@extra_recursive_targets): New global variable.
(scan_autoconf_traces): Trace macro '_AM_EXTRA_RECURSIVE_TARGETS'.
(handle_user_recursion): New subroutine; among other things, it defines
the new internal '$(am__extra_recursive_targets)' make variable, and
the '*-am', '*-local' and '*-recursive' targets associated with the
user-specified user recursive targets.
(generate_makefile): Call the new subroutine.
* lib/am/subdirs.am (am__recursive_targets): New internal make variable,
listing all of '$(RECURSIVE_TARGETS)', '$(RECURSIVE_CLEAN_TARGETS)' and
'$(am__extra_recursive_targets)' together.
(AM_RECURSIVE_TARGETS): Adjust the definition of this variable ...
(.PHONY, .MAKE): ... and the list of dependencies of these special targets
to take advantage of the new '$(am__recursive_targets)' variable.
($(am__recursive_targets)): New targets, superseding ...
($(RECURSIVE_TARGETS), $(RECURSIVE_CLEAN_TARGETS)): ... these, and
inheriting their rules.  This way, the rules to handle recursion for
built-in recursive targets (e.g., 'all', 'dvi', 'clean') and for user
defined recursive targets are the same.
* m4/extra-recurs.m4: New file, contain definition of new macro
'AM_EXTRA_RECURSIVE_TARGETS' and '_AM_EXTRA_RECURSIVE_TARGETS'.
These macros are basically dummy, only used for tracing by automake.
* m4/Makefile.am (dist_automake_ac_DATA): Update.
* t/recurs-user.sh: New test.
* t/recurs-user2.sh: Likewise.
* t/recurs-user-deeply-nested.sh: Likewise.
* t/recurs-user-indir.sh: Likewise.
* t/recurs-user-k.sh: Likewise.
* t/recurs-user-many.sh: Likewise.
* t/recurs-user-no-subdirs.sh: Likewise.
* t/recurs-user-no-top-level.sh: Likewise.
* t/recurs-user-override.sh: Likewise.
* t/recurs-user-phony.sh: Likewise.
* t/recurs-user-wrap.sh: Likewise.
* t/remake-recurs-user.sh: Likewise.
* t/list-of-tests.mk: Update.

Signed-off-by: Stefano Lattarini <address@hidden>
---

 Before getting to write the documentation, I'd like to hear some comments
 on this patch.  So, reviews, criticism and suggestions are welcome.

 Regards,
   Stefano

 -*-*-*-

 Makefile.am                    |    1 +
 NEWS                           |    7 +++
 automake.in                    |   35 ++++++++++++++
 lib/am/subdirs.am              |   17 ++++---
 m4/extra-recurs.m4             |   17 +++++++
 t/list-of-tests.mk             |   12 +++++
 t/recurs-user-deeply-nested.sh |   97 +++++++++++++++++++++++++++++++++++++
 t/recurs-user-indir.sh         |   99 ++++++++++++++++++++++++++++++++++++++
 t/recurs-user-keep-going.sh    |   95 ++++++++++++++++++++++++++++++++++++
 t/recurs-user-many.sh          |   73 ++++++++++++++++++++++++++++
 t/recurs-user-no-subdirs.sh    |   52 ++++++++++++++++++++
 t/recurs-user-no-top-level.sh  |   50 +++++++++++++++++++
 t/recurs-user-override.sh      |   68 ++++++++++++++++++++++++++
 t/recurs-user-phony.sh         |   64 +++++++++++++++++++++++++
 t/recurs-user-wrap.sh          |   59 +++++++++++++++++++++++
 t/recurs-user.sh               |   81 +++++++++++++++++++++++++++++++
 t/recurs-user2.sh              |  103 ++++++++++++++++++++++++++++++++++++++++
 t/remake-recurs-user.sh        |   89 ++++++++++++++++++++++++++++++++++
 18 files changed, 1012 insertions(+), 7 deletions(-)
 create mode 100644 m4/extra-recurs.m4
 create mode 100755 t/recurs-user-deeply-nested.sh
 create mode 100755 t/recurs-user-indir.sh
 create mode 100755 t/recurs-user-keep-going.sh
 create mode 100755 t/recurs-user-many.sh
 create mode 100755 t/recurs-user-no-subdirs.sh
 create mode 100755 t/recurs-user-no-top-level.sh
 create mode 100755 t/recurs-user-override.sh
 create mode 100755 t/recurs-user-phony.sh
 create mode 100755 t/recurs-user-wrap.sh
 create mode 100755 t/recurs-user.sh
 create mode 100755 t/recurs-user2.sh
 create mode 100755 t/remake-recurs-user.sh

diff --git a/Makefile.am b/Makefile.am
index 9e5512e..829c31f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -266,6 +266,7 @@ dist_automake_ac_DATA = \
   m4/depend.m4 \
   m4/depout.m4 \
   m4/dmalloc.m4 \
+  m4/extra-recurs.m4 \
   m4/gcj.m4 \
   m4/init.m4 \
   m4/install-sh.m4 \
diff --git a/NEWS b/NEWS
index 54acc7a..08ca231 100644
--- a/NEWS
+++ b/NEWS
@@ -81,6 +81,13 @@ New in 1.13:
     script to avoid such issues; a simple example is provided in the
     "CVS and generated files" chapter of the automake manual.
 
+* Recursive targets:
+
+  The user can now define his own recursive targets that recurse
+  in the directories specified in $(SUBDIRS).  This can be done by
+  specifying the name of such targets in invocations of the new
+  'AM_EXTRA_RECURSIVE_TARGETS' m4 macro.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 New in 1.12.2:
diff --git a/automake.in b/automake.in
index 11e750d..b7b03f3 100644
--- a/automake.in
+++ b/automake.in
@@ -362,6 +362,9 @@ my $ac_gettext_location;
 # Whether AM_GNU_GETTEXT_INTL_SUBDIR has been seen.
 my $seen_gettext_intl = 0;
 
+# The arguments of the AM_EXTRA_RECURSIVE_TARGETS call (if any).
+my @extra_recursive_targets = ();
+
 # Lists of tags supported by Libtool.
 my %libtool_tags = ();
 # 1 if Libtool uses LT_SUPPORTED_TAG.  If it does, then it also
@@ -4546,6 +4549,32 @@ sub handle_all ($)
       }
 }
 
+# Generate helper targets for user recursion, where needed.
+sub handle_user_recursion ()
+{
+  return unless @extra_recursive_targets;
+
+  define_pretty_variable ('am__extra_recursive_targets', TRUE, INTERNAL,
+                          map { "$_-recursive" } @extra_recursive_targets);
+  my $aux = var ('SUBDIRS') ? 'recursive' : 'am';
+  foreach my $target (@extra_recursive_targets)
+    {
+      # This allows the default target's rules to be overridden in
+      # Makefile.am.
+      user_phony_rule ($target);
+      depend ("$target", "$target-$aux");
+      depend ("$target-am", "$target-local");
+      # Every user-defined recursive target 'foo' *must* have a valid
+      # associated 'foo-local' rule; we define it as an empty rule by
+      # default, so that the user can transparently extend it in his
+      # own Makefile.am.
+      pretty_print_rule ("$target-local:");
+      # $target-recursive might as well be undefined, so do not add
+      # it here; it's taken care of in subdirs.am anyway.
+      depend (".PHONY", "$target-am", "$target-local");
+    }
+}
+
 
 # &do_check_merge_target ()
 # -------------------------
@@ -5163,6 +5192,7 @@ sub scan_autoconf_traces ($)
                AC_SUBST_TRACE => 1,
                AM_AUTOMAKE_VERSION => 1,
                AM_CONDITIONAL => 2,
+               _AM_EXTRA_RECURSIVE_TARGETS => 1,
                AM_GNU_GETTEXT => 0,
                AM_GNU_GETTEXT_INTL_SUBDIR => 0,
                AM_INIT_AUTOMAKE => 0,
@@ -5323,6 +5353,10 @@ sub scan_autoconf_traces ($)
        {
          $configure_cond{$args[1]} = $where;
        }
+      elsif ($macro eq '_AM_EXTRA_RECURSIVE_TARGETS')
+       {
+         push @extra_recursive_targets, split (' ', $args[1]);
+       }
       elsif ($macro eq 'AM_GNU_GETTEXT')
        {
          $seen_gettext = $where;
@@ -7998,6 +8032,7 @@ sub generate_makefile ($$)
   handle_data;
   handle_headers;
   handle_subdirs;
+  handle_user_recursion;
   handle_tags;
   handle_minor_options;
   # Must come after handle_programs so that %known_programs is up-to-date.
diff --git a/lib/am/subdirs.am b/lib/am/subdirs.am
index 3fc2888..005483a 100644
--- a/lib/am/subdirs.am
+++ b/lib/am/subdirs.am
@@ -17,13 +17,17 @@
 RECURSIVE_TARGETS += all-recursive check-recursive installcheck-recursive
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
   distclean-recursive maintainer-clean-recursive
+
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+
 ## All documented targets which invoke 'make' recursively, or depend
-## on targets that do so.
-AM_RECURSIVE_TARGETS += $(RECURSIVE_TARGETS:-recursive=) \
-  $(RECURSIVE_CLEAN_TARGETS:-recursive=)
+## on targets that do so.  GNUmakefile from gnulib depends on this.
+AM_RECURSIVE_TARGETS += $(am__recursive_targets:-recursive=)
 
-.PHONY: $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS)
-.MAKE: $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS)
+.PHONY .MAKE: $(am__recursive_targets)
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run 'make' without going through this Makefile.
@@ -32,7 +36,7 @@ AM_RECURSIVE_TARGETS += $(RECURSIVE_TARGETS:-recursive=) \
 #     (which will cause the Makefiles to be regenerated when you run 'make');
 # (2) otherwise, pass the desired values on the 'make' command line.
 
-$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS):
+$(am__recursive_targets):
 ## Using $failcom allows "-k" to keep its natural meaning when running a
 ## recursive rule.
        @fail= failcom='exit 1'; \
@@ -66,7 +70,6 @@ $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS):
          $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
        fi; test -z "$$fail"
 
-
 mostlyclean: mostlyclean-recursive
 clean: clean-recursive
 distclean: distclean-recursive
diff --git a/m4/extra-recurs.m4 b/m4/extra-recurs.m4
new file mode 100644
index 0000000..7b7ecc7
--- /dev/null
+++ b/m4/extra-recurs.m4
@@ -0,0 +1,17 @@
+# AM_EXTRA_RECURSIVE_TARGETS                                -*- Autoconf -*-
+
+# Copyright (C) 2012 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_EXTRA_RECURSIVE_TARGETS
+# --------------------------
+# Define the list of user recursive targets.  This macro exists only to
+# be traced by Automake, which will ensure that a proper definition of
+# user-defined recursive targets (and associated rules) is propagated
+# into all the generated Makefiles.
+AC_DEFUN([AM_EXTRA_RECURSIVE_TARGETS], [_$0(m4_flatten([$1]))])
+# TODO: We should really reject non-literal arguments here...
+m4_define([_AM_EXTRA_RECURSIVE_TARGETS], [])
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index 4b16822..919b6f0 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -884,6 +884,17 @@ t/python-dist.sh \
 t/python-vars.sh \
 t/python-virtualenv.sh \
 t/python-pr10995.sh \
+t/recurs-user.sh \
+t/recurs-user2.sh \
+t/recurs-user-deeply-nested.sh \
+t/recurs-user-indir.sh \
+t/recurs-user-keep-going.sh \
+t/recurs-user-many.sh \
+t/recurs-user-no-subdirs.sh \
+t/recurs-user-no-top-level.sh \
+t/recurs-user-override.sh \
+t/recurs-user-phony.sh \
+t/recurs-user-wrap.sh \
 t/relativize.tap \
 t/remake.sh \
 t/remake1a.sh \
@@ -907,6 +918,7 @@ t/remake11.sh \
 t/remake12.sh \
 t/remake-all-1.sh \
 t/remake-all-2.sh \
+t/remake-recurs-user.sh \
 t/remake-subdir-from-subdir.sh \
 t/remake-subdir-gnu.sh \
 t/remake-subdir.sh \
diff --git a/t/recurs-user-deeply-nested.sh b/t/recurs-user-deeply-nested.sh
new file mode 100755
index 0000000..6591695
--- /dev/null
+++ b/t/recurs-user-deeply-nested.sh
@@ -0,0 +1,97 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that recursion on user-defined targets can be made to work
+# with "deeply" nested uses of $(SUBDIRS).
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES([
+    sub1/Makefile
+    sub1/sub2/Makefile
+    sub1/sub2/sub3/Makefile
+    sub1/sub2/sub3/sub4/Makefile
+])
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_OUTPUT
+END
+
+dirs='sub1 sub1/sub2 sub1/sub2/sub3 sub1/sub2/sub3/sub4'
+
+mkdir $dirs
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub1
+
+foo-local:
+       cp sub1/foo foo
+MOSTLYCLEANFILES = foo
+
+.PHONY: test
+test:
+       echo 'It works!' > exp
+       diff exp foo
+       diff exp sub1/foo
+       test ! -f sub1/sub2/foo
+       test ! -f sub1/sub2/sub3/foo
+       diff exp sub1/sub2/sub3/sub4/foo
+       rm -f exp
+
+all-local: foo
+check-local: test
+END
+
+cat > sub1/Makefile.am <<'END'
+SUBDIRS = sub2
+foo-local:
+       test ! -f sub2/sub3/foo
+       cp sub2/sub3/sub4/foo foo
+MOSTLYCLEANFILES = foo
+END
+
+# Here we deliberately lack an explicit definition the 'foo-local'
+# target; that shouldn't stop 'foo' recursion into subdirectory
+# 'sub3/sub4'.
+echo SUBDIRS = sub3 > sub1/sub2/Makefile.am
+echo SUBDIRS = sub4 > sub1/sub2/sub3/Makefile.am
+
+cat > sub1/sub2/sub3/sub4/Makefile.am <<'END'
+foo-local:
+       echo 'It works!' > foo
+MOSTLYCLEANFILES = foo
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+for d in $dirs; do
+  $FGREP foo-am $d/Makefile.in || Exit 1
+  case $d in
+    */sub4);;
+    *) $FGREP foo-recursive $d/Makefile.in || Exit 1;;
+  esac
+done
+
+./configure
+
+$MAKE foo
+$MAKE test
+
+$MAKE distcheck
+
+:
diff --git a/t/recurs-user-indir.sh b/t/recurs-user-indir.sh
new file mode 100755
index 0000000..e8bfb56
--- /dev/null
+++ b/t/recurs-user-indir.sh
@@ -0,0 +1,99 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that user recursion works with various types of indirections
+# *involved in the definition of the '*-local' targets*: make macros,
+# AC_SUBST'd strings, automake-time file inclusions, automake
+# conditionals...
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES([
+    sub1/Makefile
+    sub1/subsub/Makefile
+    sub2/Makefile
+    sub2/subsub/Makefile
+])
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_SUBST([FOO_LOCAL], [foo-local])
+AM_CONDITIONAL([COND], [:])
+AC_OUTPUT
+END
+
+mkdir sub1 sub1/subsub sub2 sub2/subsub
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub1 sub2
+AM_FOO_LOCAL = foo-local
+
+$(AM_FOO_LOCAL):
+       pwd && : > foo
+CLEANFILES = foo
+
+all-local: foo
+check-local:
+       test -f foo
+       test -f sub1/foo
+       test -f sub1/subsub/foo
+       test -f sub2/foo
+       test -f sub2/subsub/foo
+       test ! -r sub2/subsub/bar
+END
+
+cat > sub1/Makefile.am <<'END'
+SUBDIRS = subsub
address@hidden@:
+       pwd && : > foo
+CLEANFILES = foo
+END
+
+cat > sub1/subsub/Makefile.am <<'END'
+$(FOO_LOCAL):
+       pwd && : > foo
+CLEANFILES = foo
+END
+
+cat > sub2/Makefile.am <<'END'
+include $(srcdir)/bar.am
+include $(srcdir)/baz.am
+CLEANFILES = foo
+END
+
+echo 'SUBDIRS = subsub' > sub2/bar.am
+echo 'foo-local: ; pwd && : > foo' > sub2/baz.am
+
+cat > sub2/subsub/Makefile.am <<'END'
+if COND
+foo-local:
+       pwd && : > foo
+CLEANFILES = foo
+else !COND
+foo-local:
+       pwd && : > bar
+endif !COND
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+$MAKE check
+$MAKE distcheck
+
+:
diff --git a/t/recurs-user-keep-going.sh b/t/recurs-user-keep-going.sh
new file mode 100755
index 0000000..7114252
--- /dev/null
+++ b/t/recurs-user-keep-going.sh
@@ -0,0 +1,95 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that user recursion works with "make -k".
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_CONFIG_FILES([
+    sub1/Makefile
+    sub1/subsub1/Makefile
+    sub2/Makefile
+    sub2/subsub2/Makefile
+    sub3/Makefile
+])
+FAIL='@echo "FAIL $@ in `pwd`"; exit 1'
+PASS='@echo "PASS $@ in `pwd`"; : > foo'
+AC_SUBST([FAIL])
+AC_SUBST([PASS])
+AC_OUTPUT
+END
+
+mkdir sub1 sub1/subsub1 sub2 sub2/subsub2 sub3
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub1 . sub2 sub3
+foo-local:; @FAIL@
+END
+
+cat > sub1/Makefile.am <<'END'
+SUBDIRS = subsub1
+foo-local:; @PASS@
+END
+
+cat > sub2/Makefile.am <<'END'
+SUBDIRS = subsub2
+foo-local:; @FAIL@
+END
+
+echo 'foo-local:; @FAIL@' > sub1/subsub1/Makefile.am
+echo 'foo-local:; @PASS@' > sub2/subsub2/Makefile.am
+echo 'foo-local:; @PASS@' > sub3/Makefile.am
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+cat > exp <<END
+./sub1/foo
+./sub2/subsub2/foo
+./sub3/foo
+END
+
+as_expected ()
+{
+  find . -name foo > t || { cat t; Exit 1; }
+  LC_ALL=C sort t > got
+  cat exp
+  cat got
+  diff exp got
+}
+
+# Without "-k", we fail in 'sub1/subsub1', and do nothing else.
+# So, no 'foo' file gets created.
+$MAKE foo && Exit 1
+find . -name foo | grep . && Exit 1
+
+if using_gmake; then
+  $MAKE -k foo && Exit 1
+  as_expected
+  $MAKE --keep-going foo && Exit 1
+  as_expected
+else
+  # Don't trust the exit status of 'make -k' for non-GNU makes.
+  $MAKE -k foo || :
+  as_expected
+fi
+
+:
diff --git a/t/recurs-user-many.sh b/t/recurs-user-many.sh
new file mode 100755
index 0000000..d6bfeda
--- /dev/null
+++ b/t/recurs-user-many.sh
@@ -0,0 +1,73 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that many user-defined recursive targets can be supported
+# at once, and that calls to 'AM_EXTRA_RECURSIVE_TARGETS' are
+# cumulative.
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES([sub/Makefile])
+## NOTE: extra white spaces, tabs, newlines and backslashes in the
+## lines below: on purpose.
+AM_EXTRA_RECURSIVE_TARGETS([ foo  \
+       bar  ])
+AC_SUBST([CLEANFILES], ['foo bar baz'])
+AC_OUTPUT
+# Yes, this appears after AC_OUTPUT.  So what?
+AM_EXTRA_RECURSIVE_TARGETS([baz])
+END
+
+mkdir sub
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub
+foo-local:
+       : > foo
+bar-local:
+       echo x > bar
+baz-local: ; touch baz
+check-local: foo bar baz
+       ls -l . sub ;: For debugging.
+       test -f foo
+       test -f bar
+       test -f baz
+       test -f sub/foo
+       test -f sub/bar
+       test -f sub/baz
+END
+
+cat > sub/Makefile.am <<'END'
+foo-local bar-local baz-local:
+       touch `echo $@ | sed 's/-local$$//'`
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+for t in foo bar baz; do
+  $FGREP "$t-am" Makefile.in
+  $FGREP "$t-am" sub/Makefile.in
+done
+
+./configure
+
+$MAKE check
+$MAKE distcheck
+
+:
diff --git a/t/recurs-user-no-subdirs.sh b/t/recurs-user-no-subdirs.sh
new file mode 100755
index 0000000..7092d82
--- /dev/null
+++ b/t/recurs-user-no-subdirs.sh
@@ -0,0 +1,52 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that user recursion can be made to work even when $(SUBDIRS)
+# is empty or undefined.
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_OUTPUT
+END
+
+$ACLOCAL
+$AUTOCONF
+
+# First try with undefined $(SUBDIRS).
+cat > Makefile.am <<'END'
+all-local: foo
+foo-local:
+       : > bar
+MOSTLYCLEANFILES = bar
+END
+$AUTOMAKE
+./configure
+$MAKE foo
+test -f bar
+
+$MAKE distclean
+test ! -r bar # Sanity check.
+
+# Now try with empty but defined $(SUBDIRS).
+echo SUBDIRS = >> Makefile.am
+$AUTOMAKE
+./configure
+$MAKE foo
+test -f bar
+
+:
diff --git a/t/recurs-user-no-top-level.sh b/t/recurs-user-no-top-level.sh
new file mode 100755
index 0000000..70a3112
--- /dev/null
+++ b/t/recurs-user-no-top-level.sh
@@ -0,0 +1,50 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that user recursion works even for targets that don't exist
+# in the top-level Makefile.
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES([sub/Makefile])
+AM_EXTRA_RECURSIVE_TARGETS([foo-bar])
+AC_OUTPUT
+END
+
+mkdir sub
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub
+all-local: foo-bar
+END
+
+cat > sub/Makefile.am <<'END'
+foo-bar-local:
+       : > foo-bar
+MOSTLYCLEANFILES = foo-bar
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+$MAKE foo-bar
+test -f sub/foo-bar
+
+:
diff --git a/t/recurs-user-override.sh b/t/recurs-user-override.sh
new file mode 100755
index 0000000..382d9d1
--- /dev/null
+++ b/t/recurs-user-override.sh
@@ -0,0 +1,68 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that override of user-defined recursive targets work as
+# expected.
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES([sub/Makefile])
+AM_EXTRA_RECURSIVE_TARGETS([foobar zardoz])
+AC_OUTPUT
+END
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub
+all-local: foobar zardoz
+foobar:
+       : > foobar.out
+MOSTLYCLEANFILES = foobar.out
+check-local:
+       test -f foobar.out
+       test ! -r sub/foobar.out
+       test -f sub/zardoz.out
+       test ! -r sub/baz.out
+END
+
+mkdir sub
+cat > sub/Makefile.am <<'END'
+foobar foobar-local:
+       : > foobar.out
+zardoz-local:
+       : > baz.out
+zardoz:
+       : > zardoz.out
+MOSTLYCLEANFILES = zardoz.out
+END
+
+$ACLOCAL
+$AUTOCONF
+
+AUTOMAKE_fails
+grep '^Makefile\.am:3:.*user target.*foobar' stderr
+grep '^Makefile\.am:.*foobar-local.*instead of foobar$' stderr
+grep '^sub/Makefile\.am:5:.*user target.*zardoz' stderr
+grep '^sub/Makefile\.am:.*zardoz-local.*instead of zardoz$' stderr
+
+$AUTOMAKE -Wno-override
+
+./configure
+
+$MAKE check
+$MAKE distcheck
+
+:
diff --git a/t/recurs-user-phony.sh b/t/recurs-user-phony.sh
new file mode 100755
index 0000000..1390ad6
--- /dev/null
+++ b/t/recurs-user-phony.sh
@@ -0,0 +1,64 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that user-defined recursive targets and their associate
+# '-local', '-am' and '-recursive' targets are declared as phony.
+
+# Require GNU make, because some vendo makes (e.g., Solaris) doesn't
+# truly respect .PHONY.
+required=GNUmake
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES([sub/Makefile])
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_OUTPUT
+END
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub
+foo-local:
+       echo 'GOOD!' > foo
+END
+
+mkdir sub
+cat > sub/Makefile.am <<'END'
+foo-local:
+       echo 'GOOD!' > foo
+END
+
+dummy_files='
+  foo
+  foo-local
+  foo-am
+  foo-recursive
+  sub/foo
+  sub/foo-local
+  sub/foo-am
+'
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+./configure
+
+touch $dummy_files
+
+$MAKE foo
+grep 'GOOD!' foo
+grep 'GOOD!' sub/foo
+
+:
diff --git a/t/recurs-user-wrap.sh b/t/recurs-user-wrap.sh
new file mode 100755
index 0000000..8b13c3c
--- /dev/null
+++ b/t/recurs-user-wrap.sh
@@ -0,0 +1,59 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that rules generated by user recursion are apt to be wrapped
+# by other makefiles.
+
+required=GNUmake
+. ./defs || Exit 1
+
+cat >> configure.ac << 'END'
+AM_EXTRA_RECURSIVE_TARGETS([extra])
+AC_CONFIG_FILES([src/Makefile])
+AC_OUTPUT
+END
+
+mkdir src
+echo SUBDIRS = src > Makefile.am
+echo 'bar: ; : > $@ ' > src/Makefile.am
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+$MAKE extra
+test ! -f extra-local
+test ! -f src/bar
+
+cat > GNUmakefile << 'END'
+.DEFAULT_GOAL = all
+extra-local:
+       : > $@
+include ./Makefile
+END
+
+cat > src/GNUmakefile << 'END'
+include ./Makefile
+extra-local: bar
+END
+
+$MAKE extra
+test -f extra-local
+test -f src/bar
+
+:
diff --git a/t/recurs-user.sh b/t/recurs-user.sh
new file mode 100755
index 0000000..1786358
--- /dev/null
+++ b/t/recurs-user.sh
@@ -0,0 +1,81 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Basic checks on user-defined recursive rules.
+# Check that user recursion respect $(SUBDIRS) order,
+# and proceeds in a depth-first fashion.
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_CONFIG_FILES([
+    sub1/Makefile
+    sub2/Makefile
+    sub3/Makefile
+    sub3/deeper/Makefile
+])
+AC_OUTPUT
+END
+
+mkdir sub1 sub2 sub3 sub3/deeper
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub1 . sub3 sub2
+foo-local:
+       echo '.' >> $(top_builddir)/got
+.PHONY: test
+test: foo
+       cat $(srcdir)/exp
+       cat ./got
+       diff $(srcdir)/exp ./got
+check-local: test
+MOSTLYCLEANFILES = got
+EXTRA_DIST = exp
+END
+
+for i in 1 2 3; do
+  cat > sub$i/Makefile.am <<END
+foo-local:
+       echo 'sub$i' >> \$(top_builddir)/got
+END
+done
+
+echo SUBDIRS = deeper >> sub3/Makefile.am
+
+cat >> sub3/deeper/Makefile.am <<'END'
+foo-local:
+       echo sub3/deeper >> $(top_builddir)/got
+END
+
+cat >> exp <<'END'
+sub1
+.
+sub3/deeper
+sub3
+sub2
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+$MAKE test
+$MAKE distcheck
+
+:
diff --git a/t/recurs-user2.sh b/t/recurs-user2.sh
new file mode 100755
index 0000000..26ffbea
--- /dev/null
+++ b/t/recurs-user2.sh
@@ -0,0 +1,103 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Check that user recursion can be made to work when $(SUBDIRS) are
+# not "strictly" nested, as in e.g.:
+#    SUBDIRS = src external/lib external/tests
+# with no Makefile in 'external'.
+
+. ./defs || Exit 1
+
+cat >> configure.ac <<'END'
+AC_CONFIG_FILES(
+    sub1/Makefile
+    sub2/Makefile
+dnl There's deliberately no 'sub3/Makefile'.
+    sub3/subsub/Makefile
+    sub4/Makefile
+    sub4/subsub/Makefile
+)
+AM_EXTRA_RECURSIVE_TARGETS([foo])
+AC_OUTPUT
+END
+
+mkdir sub1 sub2 sub3 sub4 sub3/subsub sub4/subsub
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub1 sub2 sub3/subsub sub4 sub4/subsub
+
+foo-local:
+       echo _rootdir_ >foo
+MOSTLYCLEANFILES = foo
+
+.PHONY: test
+test: foo
+       grep _rootdir_ foo
+       grep ':sub1:' sub1/foo
+       grep ',sub1,' sub1/bar
+       test ! -r sub2/foo
+       test ! -r sub3/foo
+       grep '%sub3/subsub%' sub3/subsub/quux
+       test ! -r sub3/subsub/foo
+       test ! -r sub4/foo
+       grep '=sub4/subsub=' sub4/subsub/foo
+
+check-local: test
+END
+
+# A 'foo-local' target with dependencies shouldn't cause problems.
+cat > sub1/Makefile.am <<'END'
+foo-local: bar
+       sed 's/,/:/g' bar >foo
+bar:
+       echo ',sub1,' >$@
+MOSTLYCLEANFILES = foo bar
+END
+
+# The lack of a 'foo' target here shouldn't cause any error in
+# automake nor in make.
+: > sub2/Makefile.am
+
+# The lack of file 'sub3/Makefile.am' shouldn't cause any problem either.
+rm -f sub23/Makefile.am
+
+# A 'foo-local' creating a file != 'foo' shouldn't cause any problem.
+cat > sub3/subsub/Makefile.am <<'END'
+foo-local:
+       echo '%sub3/subsub%' >quux
+MOSTLYCLEANFILES = quux
+END
+
+# No 'foo-local' nor 'foo' target here ...
+: > sub4/Makefile.am
+# ... should not cause errors, nor cause the 'foo-local' target
+# here not to be executed.
+cat > sub4/subsub/Makefile.am <<'END'
+foo-local:
+       echo '=sub4/subsub=' >foo
+MOSTLYCLEANFILES = foo
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+$MAKE test
+$MAKE distcheck
+
+:
diff --git a/t/remake-recurs-user.sh b/t/remake-recurs-user.sh
new file mode 100755
index 0000000..f0aeba6
--- /dev/null
+++ b/t/remake-recurs-user.sh
@@ -0,0 +1,89 @@
+#! /bin/sh
+# Copyright (C) 2012 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/>.
+
+# Remake rules and user-defined recursive rules.
+
+. ./defs || Exit 1
+
+cat >> configure.ac << 'END'
+m4_include([extra-targets.m4])
+AC_CONFIG_FILES([sub/Makefile])
+AC_OUTPUT
+END
+
+echo 'AM_EXTRA_RECURSIVE_TARGETS([foo])' > extra-targets.m4
+
+cat > Makefile.am << 'END'
+SUBDIRS = sub
+all-local: foo
+foo-local:
+       : > foo
+bar-local:
+       : > bar
+MOSTLYCLEANFILES = foo
+END
+
+mkdir sub
+cat > sub/Makefile.am << 'END'
+foo-local:
+       : > foo2
+MOSTLYCLEANFILES = foo2
+bar-local: later-target
+END
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+
+$MAKE
+test -f foo
+test -f sub/foo2
+test ! -f bar
+test ! -f sub/zardoz
+$MAKE distcheck
+
+$sleep
+
+echo 'AM_EXTRA_RECURSIVE_TARGETS([bar])' >> extra-targets.m4
+
+cat >> Makefile.am <<'END'
+MOSTLYCLEANFILES += bar oof
+all-local: bar
+foo-local: oof
+oof:
+       : > $@
+END
+
+echo 'include $(srcdir)/more.am' >> sub/Makefile.am
+
+cat > sub/more.am << 'END'
+later-target:
+       : > zardoz
+DISTCLEANFILES = zardoz
+END
+
+using_gmake || $MAKE Makefile
+$MAKE
+test -f foo
+test -f oof
+test -f sub/foo2
+test -f bar
+test -f sub/zardoz
+$MAKE distcheck
+
+:
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]