Subject: Problem with am__is_gnu_make: Arg list too long

From: "Daniel Richard G." <[email-masked]>
Date: Wed, 15 Oct 2014 22:57:29 -0400

Hello gnus,

I was hacking on libarchive for compatibility with an older Tru64
system, in conjuction with Automake 1.14.1, when I encountered a problem
during "gmake check":

[...]
gmake  check-TESTS
gmake[2]: Entering directory `/tmp/libarchive-3.1.2/_build'
gmake[3]: Entering directory `/tmp/libarchive-3.1.2/_build'
../build/autoconf/test-driver: line 107: 23320 Segmentation fault      "$@" >$log_file 2>&1
FAIL: libarchive_test
FAIL: bsdtar_test
FAIL: bsdcpio_test
FAIL: bsdcat_test
gmake[3]: execvp: bash: Arg list too long
gmake[3]: *** [test-suite.log] Error 127
gmake[3]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake[2]: *** [check-TESTS] Error 2
gmake[2]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake[1]: *** [check-am] Error 2
gmake[1]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake: *** [check] Error 2

Where was that "Arg list too long" error coming from? I removed some
leading "@" specifiers from some makefile recipe lines, and got this:

[...]
FAIL: libarchive_test
FAIL: bsdtar_test
FAIL: bsdcpio_test
FAIL: bsdcat_test
bases='libarchive_test.log bsdtar_test.log bsdcpio_test.log bsdcat_test.log'; bases=`for i in $bases; do echo $i; done | sed 's/\.log$//'`; bases=`echo $bases`; \
	am__f_ok () { test -f "$1" && test -r "$1"; }; \
	redo_bases=`for i in $bases; do \
	              am__f_ok $i.trs && am__f_ok $i.log || echo $i; \
	            done`; \
	if test -n "$redo_bases"; then \
	  redo_logs=`for i in $redo_bases; do echo $i.log; done`; \
	  redo_results=`for i in $redo_bases; do echo $i.trs; done`; \
	  if (target_option=n; case ${target_option-} in ?) ;; *) echo "am__make_running_with_option: internal error: invalid" "target option '${target_option-}' specified" >&2; exit 1;; esac; has_opt=no; sane_makeflags=$MAKEFLAGS; if test -n ' Makefile cat/.deps/bsdcat-bsdcat.Po cat/.deps/bsdcat-cmdline.Po cat/test/.deps/bsdcat_test-main.Po cat/test/.deps/bsdcat_test-test_0.Po cat/test/.deps/bsdcat_test-test_empty_gz.Po cat/test/.deps/bsdcat_test-test_empty_lz4.Po cat/test/.deps/bsdcat_test-test_empty_xz.Po cat/test/.deps/bsdcat_test-test_error.Po cat/test/.deps/bsdcat_test-test_error_mixed.Po cat/test/.deps/bsdcat_test-test_expand_Z.Po cat/test/.deps/bsdcat_test-test_expand_bz2.Po cat/test/.deps/bsdcat_test-test_expand_gz.Po cat/test/.deps/bsdcat_test-test_expand_lz4.Po cat/test/.deps/bsdcat_test-test_expand_mixed.Po cat/test/.deps/bsdcat_test-test_expand_plain.Po cat/test/.deps/bsdcat_test-test_expand_xz.Po cat/test/.deps/bsdcat_test-test_help.Po cat/test/.deps/bsdcat_test-test_version.Po cpio/.deps/bsdcpio-cmdline.Po cpio/.deps/bsdcpio-cpio.Po cpio/.deps/bsdcpio-cpio_windows.Po cpio/.deps/bsdcpio_test-cmdline.Po cpio/test/.deps/bsdcpio_test-main.Po cpio/test/.deps/bsdcpio_test-test_0.Po cpio/test/.deps/bsdcpio_test-test_basic.Po [...]

That last "if test -n" statement includes what appears to be every *.Po
and *.Plo file in the entire project---not helped, perhaps, by the fact
that this project has a bazillion source files and only a single top-
level makefile. Not only that, the output showed *two* full instances of
this list in the same recipe line, presumably resulting from two
expansions of the same problematic construct.

This appeared to be $(am__make_dryrun) at first, but nested within was
$(am__make_running_with_option), and in turn $(am__is_gnu_make):

    am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'

To confirm that this was the problem, I added the following rule to the
makefile...

    print-makefile-list:
            : $(MAKEFILE_LIST)

...and then tried

    $ gmake print-makefile-list
    :  Makefile cat/.deps/bsdcat-bsdcat.Po cat/.deps/bsdcat-cmdline.Po cat/test/.deps/bsdcat_test-main.Po cat/test/.deps/bsdcat_test-test_0.Po cat/test/.deps/bsdcat_test-test_empty_gz.Po [...]

Yep, those *.Po/*.Plo files are makefile fragments that get include'd,
so it makes sense that we end up with a huge MAKEFILE_LIST. If I change
am__is_gnu_make to...

    am__is_gnu_make = test -n '$(MAKE_VERSION)' && test -n '$(MAKELEVEL)'

...given that MAKE_VERSION appears to be a shorter example of a GNU-Make-
only variable, then things work as they should:

[...]
gmake[5]: Nothing to be done for `all-am'.
gmake[5]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake[4]: Leaving directory `/tmp/libarchive-3.1.2/_build'
============================================================================
Testsuite summary for libarchive 3.1.2
============================================================================
# TOTAL: 4
# PASS:  0
# SKIP:  0
# XFAIL: 0
# FAIL:  4
# XPASS: 0
# ERROR: 0
============================================================================
See ./test-suite.log
Please report to [email-masked]
============================================================================
gmake[3]: *** [test-suite.log] Error 1
gmake[3]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake[2]: *** [check-TESTS] Error 2
gmake[2]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake[1]: *** [check-am] Error 2
gmake[1]: Leaving directory `/tmp/libarchive-3.1.2/_build'
gmake: *** [check] Error 2

(At least as far as the test infrastructure is concerned!)

--Daniel

-- 
Daniel Richard G. || [email-masked]
My ASCII-art .sig got a bad case of Times New Roman.