Subject: bug#18744: Problem with am__is_gnu_make: Arg list too long

From: Stefano Lattarini <[email-masked]>
Date: Fri, 19 Dec 2014 18:12:14 +0100

tags 18744 + patch
close 18744
stop

Reference: http://debbugs.gnu.org/18744

Should be fixed by the attached patch.

Thanks,
   Stefano
>From ff40472d4f5ad85c27c6f5a9c5dc2beaeca41c85 Mon Sep 17 00:00:00 2001
Message-Id: <ff40472d4[email-masked]>
From: Stefano Lattarini <[email-masked]>
Date: Fri, 19 Dec 2014 15:10:09 +0100
Subject: [PATCH] Improve detection of GNU make, avoiding "Arg list too long"
 errors.

Such errors could take place when the main makefile included too many
sub-makefiles, making $(MAKEFILE_LIST) too long and causing the
recipes $(am__is_gnu_make) to exceed the shell's command-line length
limits.  This is not a theoretical issue: it could happen for projects
having lots of C/C++ sources and using automatic dependency tracking,
which created an included .Po sub-makefile for each of such sources.

Fixes http://debbugs.gnu.org/18744

* lib/am/header-vars.am (am__is_gnu_make): Fix the logic to avoid
the use of $(MAKEFILE_LIST).
* NEWS: Update.

Signed-off-by: Stefano Lattarini <[email-masked]>
---
 NEWS                  |  5 +++++
 lib/am/header-vars.am | 35 +++++++++++++++++++++++++++++++----
 2 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/NEWS b/NEWS
index 626d295..9f35bbc 100644
--- a/NEWS
+++ b/NEWS
@@ -111,6 +111,11 @@ New in 1.14.2:
   - The expansion of AM_INIT_AUTOMAKE ends once again with a trailing
     newline (bug#16841). Regression introduced in Automake 1.14.
 
+  - The code used to detect whether the currently used make is GNU make
+    or not not (relying on the private macro 'am__is_gnu_make') no longer
+    risk causing "Arg list too long" for projects using automatic
+    dependency tracking and having a ton of source files (bug#18744).
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 New in 1.14.1:
diff --git a/lib/am/header-vars.am b/lib/am/header-vars.am
index d25efa6..a0ca3fc 100644
--- a/lib/am/header-vars.am
+++ b/lib/am/header-vars.am
@@ -1,5 +1,5 @@
 ## automake - create Makefile.in from Makefile.am
-## Copyright (C) 1994-2013 Free Software Foundation, Inc.
+## Copyright (C) 1994-2014 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
@@ -27,9 +27,36 @@ VPATH = @srcdir@
 ## DESTDIR =
 
 ## Shell code that determines whether we are running under GNU make.
-## This is somewhat of an hack, and might be improved, but is good
-## enough for now.
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+##
+## Why the this needs to be so convoluted?
+##
+## (1) We can't unconditionally use make functions or special variables
+##     starting with a dot, as that cause non-GNU implmentations to
+##     crash hard.
+##
+## (2) We can't use $(MAKE_VERSION) here, as it also defined in some
+##     non-GNU make implementations (e.g., FreeBSD make).  But at least
+##     BSD make does *not* define the $(CURDIR) variable -- it uses
+##     $(.CURDIR) instead.
+##
+## (3) We can't use $(MAKEFILE_LIST) here, as in some situations it
+##     might cause to die with "Arg list too long" (see automake
+##     bug#18744).
+##
+## (4) We can't use $(MAKE_HOST) unconditionally, as it is only
+##     defined in GNU make 4.0 or later.
+##
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 
 ## Shell code that determines whether the current make instance is
 ## running with a given one-letter option (e.g., -k, -n) that takes
-- 
2.1.3