NetBSD (and other BSD) `make -jN' without `-B' - reuses shells between multiple commands in one rule (without resetting the working directory, environment variables etc),
- sprinkles "--- $target ---" status messages through the output, - does not route standard error of sub processes (sub makes as well as rule commands) correctly: all appears on stdout, except the stderr of the outermost `make' process. I'm not sure if the latter is intentional (feature or limitation), but the general behavior is documented in <http://netbsd.gw.com/cgi-bin/man-cgi?make++NetBSD-current>. Anyway, running MAKE='pmake -j1' pmake -j3 check in the Automake tree shows lots of failures. I've gone over them briefly. Most are due to the stderr issue, thus do not point to bugs outside the testsuite; I do not intend to address them at this point (the status messages have already been addressed in an earlier commit). However, there are also a couple of issues in Automake proper, which are addressed with the patches below, pushed to master. Patch for Autoconf manual coming up. Note that the Debian freebsd-make -jN has more issues which I could however not reproduce on a real NetBSD; guess that's due to Debian packaging an older version of the tool. Cheers, Ralf Cope with parallel BSD make -jN semantics. When BSD `make -jN' is used without `-B' which enables backwards compatible semantics, it may reuse the same shell for several commands within a rule; so ensure we do not leave it in a different directory, nor `exit 0' early in a multi-command rule. * lib/am/distdir.am (distcheck): After running `distcleancheck', change back to original working directory. * lib/am/remake-hdr.am (%CONFIG_HIN%): Run autoheader in a subshell. * lib/am/mans.am (uninstall-man%SECTION%): Do not `exit 0' early in a rule that consists of several shell invocations. Parallel NetBSD `make -jN' without `-B' will use only one shell for all commands, but won't respawn one after `exit 0'. Fixes notrans.test failure. * tests/makej2.test: New test. * tests/Makefile.am: Update. diff --git a/lib/am/distdir.am b/lib/am/distdir.am index 43af361..a3c91b3 100644 --- a/lib/am/distdir.am +++ b/lib/am/distdir.am @@ -464,6 +464,9 @@ distcheck: dist ## create very long directory names. && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ ?DISTCHECK-HOOK? && $(MAKE) $(AM_MAKEFLAGS) distcheck-hook \ +## Parallel BSD make may not start a new shell for each command in a recipe, +## so be sure to `cd' back to the original directory after this. + && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ ?GETTEXT? --with-included-gettext \ @@ -501,7 +504,10 @@ distcheck: dist && $(MAKE) $(AM_MAKEFLAGS) dist \ ## Make sure to remove the dists we created in the test build directory. && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ +## Cater to parallel BSD make (see above). + && cd "$$am__cwd" \ + || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ diff --git a/lib/am/mans.am b/lib/am/mans.am index 1828c5d..cf66e4f 100644 --- a/lib/am/mans.am +++ b/lib/am/mans.am @@ -119,9 +119,9 @@ if %?NOTRANS_MANS% ?HAVE_NOTRANS? sed -n '/\.%SECTION%[a-z]*$$/p'; \ ## Extract basename of manpage, change the extension if needed. } | sed 's,.*/,,;s,\.[^%SECTION%][0-9a-z]*$$,.%SECTION%,'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(man%SECTION%dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man%SECTION%dir)" && rm -f $$files + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man%SECTION%dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man%SECTION%dir)" && rm -f $$files; } endif %?NOTRANS_MANS% if %?TRANS_MANS% ## Handle MANS without notrans_ prefix @@ -136,7 +136,7 @@ if %?TRANS_MANS% ## transform, and change the extension if needed. } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^%SECTION%][0-9a-z]*$$,%SECTION%,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(man%SECTION%dir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(man%SECTION%dir)" && rm -f $$files + test -z "$$files" || { \ + echo " ( cd '$(DESTDIR)$(man%SECTION%dir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(man%SECTION%dir)" && rm -f $$files; } endif %?TRANS_MANS% diff --git a/lib/am/remake-hdr.am b/lib/am/remake-hdr.am index c1bc42f..c87572b 100644 --- a/lib/am/remake-hdr.am +++ b/lib/am/remake-hdr.am @@ -1,6 +1,6 @@ ## automake - create Makefile.in from Makefile.am ## Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2003, 2004, 2005, -## 2008 Free Software Foundation, Inc. +## 2008, 2009 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 @@ -35,7 +35,8 @@ ## by autoheader. if %?FIRST% %CONFIG_HIN%: %MAINTAINER-MODE% $(am__configure_deps) %FILES% - $(am__cd) $(top_srcdir) && $(AUTOHEADER) +## Cater to parallel BSD make. + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) ## Whenever $(AUTOHEADER) has run, we must make sure that ## ./config.status will rebuild config.h. The dependency from %STAMP% ## on %CONFIG_H_DEPS% (which contains config.hin) is not enough to diff --git a/tests/Makefile.am b/tests/Makefile.am index d700608..5d5a290 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -422,6 +422,7 @@ lzma.test \ maintclean.test \ make.test \ makej.test \ +makej2.test \ maken.test \ maken2.test \ maken3.test \ diff --git a/tests/makej2.test b/tests/makej2.test new file mode 100755 index 0000000..e89afec --- /dev/null +++ b/tests/makej2.test @@ -0,0 +1,46 @@ +#! /bin/sh +# Copyright (C) 2009 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 3, 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/>. + +# Test to make sure known BSD `make -jN' issues are fixed: +# without -B, it may reuse the same shell for separate commands in a +# rule, which can lead to interesting results. + +. ./defs || Exit 1 + +set -e + +cat >>configure.in <<'END' +AC_OUTPUT +END + +cat > Makefile.am << 'END' +test-distdir-removed: + test ! -d $(distdir) +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE + +mkdir build +cd build +../configure "--prefix=`pwd`/inst" + +$MAKE -j2 || Exit 77 +$MAKE -j2 distcheck +$MAKE test-distdir-removed + +Exit 0