Package: make
Version: 3.81-8.2
Severity: important
Tags: patch

Hi,
When presented with a very very long command line (e.g. WebKit's linking
of libWebCore.la in current git), make fails to execute the command as
it doesn't split the command line to fit within the limits.

There are a number of workarounds discussed upstream[0], none of which
are particularly pleasant, but I've attached what seems to be the
preferred option, as used by Gentoo and others.  I'm using this package
locally and it fixes the problem.

Cheers,
Daniel

[0]: http://thread.gmane.org/gmane.comp.gnu.make.bugs/4219

-- System Information:
Debian Release: wheezy/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.6.0-rc5+ (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages make depends on:
ii  libc6  2.13-35

make recommends no packages.

Versions of packages make suggests:
pn  make-doc  <none>

-- no debconf information
diff -u make-dfsg-3.81/job.c make-dfsg-3.81/job.c
--- make-dfsg-3.81/job.c
+++ make-dfsg-3.81/job.c
@@ -29,6 +29,15 @@
 
 #include <string.h>
 
+#if defined(__linux__) /* defined (HAVE_LINUX_BINFMTS_H) && defined (HAVE_SYS_USER_H) */
+#include <sys/user.h>
+#include <unistd.h>
+#ifndef PAGE_SIZE
+#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
+#endif
+#include <linux/binfmts.h>
+#endif
+
 /* Default shell to use.  */
 #ifdef WINDOWS32
 #include <windows.h>
@@ -2697,9 +2706,19 @@
 #endif
     unsigned int line_len = strlen (line);
 
+#ifdef MAX_ARG_STRLEN
+    static char eval_line[] = "eval\\ \\\"set\\ x\\;\\ shift\\;\\ ";
+#define ARG_NUMBER_DIGITS 5
+#define EVAL_LEN (sizeof(eval_line)-1 + shell_len + 4 \
+                 + (7 + ARG_NUMBER_DIGITS) * 2 * line_len / (MAX_ARG_STRLEN - 2))
+#else
+#define EVAL_LEN 0
+#endif
     char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1)
-				      + (line_len * 2) + 1);
+				      + (line_len*2) + 1 + EVAL_LEN);
+
     char *command_ptr = NULL; /* used for batch_mode_shell mode */
+    char *args_ptr;
 
 # ifdef __EMX__ /* is this necessary? */
     if (!unixy_shell)
@@ -2712,6 +2731,30 @@
     bcopy (minus_c, ap, sizeof (minus_c) - 1);
     ap += sizeof (minus_c) - 1;
     command_ptr = ap;
+
+#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN)
+    if (unixy_shell && line_len > MAX_ARG_STRLEN)
+      {
+	unsigned j;
+	memcpy (ap, eval_line, sizeof (eval_line) - 1);
+	ap += sizeof (eval_line) - 1;
+	for (j = 1; j <= 2 * line_len / (MAX_ARG_STRLEN - 2); j++)
+	  ap += sprintf (ap, "\\$\\{%u\\}", j);
+	*ap++ = '\\';
+	*ap++ = '"';
+	*ap++ = ' ';
+	/* Copy only the first word of SHELL to $0.  */
+	for (p = shell; *p != '\0'; ++p)
+	  {
+	    if (isspace ((unsigned char)*p))
+	      break;
+	    *ap++ = *p;
+	  }
+	*ap++ = ' ';
+      }
+#endif
+    args_ptr = ap;
+
     for (p = line; *p != '\0'; ++p)
       {
 	if (restp != NULL && *p == '\n')
@@ -2760,6 +2803,14 @@
           }
 #endif
 	*ap++ = *p;
+
+#if !defined (WINDOWS32) && defined (MAX_ARG_STRLEN)
+	if (unixy_shell && line_len > MAX_ARG_STRLEN && (ap - args_ptr > MAX_ARG_STRLEN - 2))
+	  {
+	    *ap++ = ' ';
+	    args_ptr = ap;
+	  }
+#endif
       }
     if (ap == new_line + shell_len + sizeof (minus_c) - 1)
       /* Line was empty.  */
diff -u make-dfsg-3.81/debian/changelog make-dfsg-3.81/debian/changelog
--- make-dfsg-3.81/debian/changelog
+++ make-dfsg-3.81/debian/changelog
@@ -1,3 +1,11 @@
+make-dfsg (3.81-8.3) unstable; urgency=low
+
+  * Apply upstream patch to allow extraordinarily long command lines, stolen
+    from Gentoo for convenience:
+    http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/sys-devel/make/files/make-3.81-long-cmdline.patch?revision=1.2
+
+ -- Daniel Stone <dan...@fooishbar.org>  Wed, 19 Sep 2012 08:10:12 +1000
+
 make-dfsg (3.81-8.2) unstable; urgency=low
 
   * Non-maintainer upload.

Reply via email to