[CC:ing bug-autoconf for Yet Another BSD make Bug, in case someone
 cares to documenting it ...]

When BSD make is run in parallel mode, it apparently strips any leading
directory component from the automatic variable '$*' (of course, against
what POSIX mandates).  This is causing FreeBSD 9.0 make and NetBSD 5.1
make to spuriously fail with automake-generated test harnesses if subdir
tests are present *and* make is being run in parallel mode.  This issue
affects also the Automake own testsuite.

The attached patch should work around the problem.

I will test this patch more properly in the next few days, and apply it
if it causes no regression.  I'm posting it here in case anyone can spare
some time to eyeball it, give early feedback, or even test the patch.

Regards,
  Stefano
>From 3115f7a37445fd404b0de300894a790d1ce0cb68 Mon Sep 17 00:00:00 2001
Message-Id: <3115f7a37445fd404b0de300894a790d1ce0cb68.1329570443.git.stefano.lattar...@gmail.com>
From: Stefano Lattarini <stefano.lattar...@gmail.com>
Date: Sat, 18 Feb 2012 13:59:26 +0100
Subject: [PATCH] parallel-tests: fix another BSD parallel make issue

When BSD make is run in parallel mode, it apparently strips any
leading directory component from the automatic variable '$*' (of
course, against what POSIX mandates).  This was causing FreeBSD 9.0
make and NetBSD 5.1 make to spuriously fail with automake-generated
test harnesses if subdir tests were present *and* make was being
run in parallel mode.  This issue affected also the Automake own
testsuite.

* lib/am/check2.am (am__set_b): New internal variable.
(%OBJ%, %EXT%.log, %EXT%$(EXEEXT).log): Use it to work around
the described BSD make issue.
* tests/parallel-tests3.test: Enhanced to expose the bug.
* tests/parallel-tests-subdir.test: Enhance a little, since we
are at it.
---
 lib/am/check2.am                 |   33 +++++++++++++++++++++++++++++----
 tests/parallel-tests-subdir.test |    2 ++
 tests/parallel-tests3.test       |   33 ++++++++++++++++++++++-----------
 3 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/lib/am/check2.am b/lib/am/check2.am
index a14e775..9847a44 100644
--- a/lib/am/check2.am
+++ b/lib/am/check2.am
@@ -14,11 +14,32 @@
 ## You should have received a copy of the GNU General Public License
 ## along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+if %?FIRST%
+## When BSD make is run in parallel mode, it apparently strips any
+## leading directory component from the automatic variable '$*' (of
+## course, against what POSIX mandates).  Try to detect and work
+## around this incompatibility.
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+endif %?FIRST%
+
 ## From a test file to a .log and .trs file.
 ?GENERIC?%EXT%.log:
 ?!GENERIC?%OBJ%: %SOURCE%
-	@p='%SOURCE%'; $(am__check_pre) %DRIVER% --test-name "$$f" \
-	--log-file '%BASE%.log' --trs-file '%BASE%.trs' \
+	@p='%SOURCE%'; \
+## Another hack to support BSD make in parallel mode.
+?!GENERIC?	b='%BASE%'; \
+?GENERIC?	$(am__set_b); \
+	$(am__check_pre) %DRIVER% --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) %DRIVER_FLAGS% -- %COMPILE% \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
 
@@ -28,8 +49,12 @@
 ## conflict with the previous one.
 if %am__EXEEXT%
 ?GENERIC?%EXT%$(EXEEXT).log:
-	@p='%SOURCE%'; $(am__check_pre) %DRIVER% --test-name "$$f" \
-	--log-file '%BASE%.log' --trs-file '%BASE%.trs' \
+	@p='%SOURCE%'; \
+	## Another hack to support BSD make in parallel mode.
+?!GENERIC?	b='%BASE%'; \
+?GENERIC?	$(am__set_b); \
+	$(am__check_pre) %DRIVER% --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) %DRIVER_FLAGS% -- %COMPILE% \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
 endif %am__EXEEXT%
diff --git a/tests/parallel-tests-subdir.test b/tests/parallel-tests-subdir.test
index 81de2f0..7e7e031 100755
--- a/tests/parallel-tests-subdir.test
+++ b/tests/parallel-tests-subdir.test
@@ -44,6 +44,8 @@ $MAKE check
 find . # For debugging.
 test -f test-suite.log
 test -f dir1/foo.log
+test -f dir1/foo.trs
 test -f dir2/dir3/foo.log
+test -f dir2/dir3/foo.trs
 
 :
diff --git a/tests/parallel-tests3.test b/tests/parallel-tests3.test
index 3e6e189..f146d0f 100755
--- a/tests/parallel-tests3.test
+++ b/tests/parallel-tests3.test
@@ -18,13 +18,15 @@
 # - concurrent parallel execution
 
 am_parallel_tests=yes
-required=GNUmake
 . ./defs || Exit 1
 
 case $MAKE in
   *\ -j*) skip_ "\$MAKE contains \`-j'";;
 esac
 
+using_gmake || echo "all:" | $MAKE -f - -j4 all \
+  || skip_ "can't run make in parallel mode"
+
 cat >> configure.in << 'END'
 AC_OUTPUT
 END
@@ -33,16 +35,25 @@ cat > Makefile.am << 'END'
 TESTS =
 END
 
-for i in 1 2 3 4 5 6 7 8; do
-  echo "TESTS += foo$i.test" >> Makefile.am
-  unindent >foo$i.test <<'END'
-    #! /bin/sh
-    echo "this is $0"
-    # Creative quoting below to please maintainer-check.
-    sleep '1'
-    exit 0
+cat > x <<'END'
+#! /bin/sh
+echo "this is $0"
+# Creative quoting below to please maintainer-check.
+sleep '1'
+exit 0
 END
-  chmod a+x foo$i.test
+chmod a+x ./x
+
+mkdir sub
+for i in 1 2 3; do
+  echo "TESTS += foo$i.test" >> Makefile.am
+  cp x foo$i.test
+  echo "TESTS += zap$i" >> Makefile.am
+  cp x zap$i
+  echo "TESTS += sub/bar$i.test" >> Makefile.am
+  cp x sub/bar$i.test
+  echo "TESTS += sub/mu$i" >> Makefile.am
+  cp x sub/mu$i
 done
 
 $ACLOCAL
@@ -71,7 +82,7 @@ cd ..
 # still be ongoing when the parallel one has terminated.
 kill -0 $!
 cat parallel/stdout
-test `grep -c '^PASS:' parallel/stdout` -eq 8
+test `grep -c '^PASS:' parallel/stdout` -eq 12
 
 # Wait long enough so that there are no open files any more when the
 # post-test cleanup runs.  But exit after we've waited for two minutes
-- 
1.7.9

Reply via email to