Make

From GameContractor

Jump to: navigation, search

This article concerns the GNU make program and specifically the 3.80 version of that program currently distributed with Cygwin.

The bug

Recently, while attempting to modify a project makefile I suddenly started to get the unlikely sounding error: virtual memory exhausted. I tracked this down to a bug reported in the eval function.

Despite the bug being tracked down and fixed several years ago it appears that these changes have yet to be incorporated into the latest version of Cygwin.

To see if your version of make exhibits this bug, create the following simple makefile:

e0 = $(foreach s,foobar,$(eval $s:))
e1 = $(foreach s,foobar, $(eval $s:))

all: ; @echo e0 == $(e0) e1 == $(e1)

If your version of make has the bug it will output:

e0 == e1 == f

whereas it should output:

e0 == e1 ==

The fix

To fix this bug you have to download the source to make, patch it, configure it, make it - the bugged make can still make the non-bugged make okay - and install it. To help shortcut the process I have included the fix here:

Index: variable.h
===================================================================
RCS file: /cvsroot/make/make/variable.h,v
retrieving revision 1.24
diff -u -B -b -r1.24 variable.h
--- variable.h	8 Aug 2002 00:11:19 -0000	1.24
+++ variable.h	25 Oct 2002 21:37:32 -0000
@@ -107,6 +107,8 @@
 extern char *expand_argument PARAMS ((char *str, char *end));
 extern char *variable_expand_string PARAMS ((char *line, char *string,
                                              long length));
+extern void install_variable_buffer PARAMS ((char **bufp, unsigned int *lenp));
+extern void restore_variable_buffer PARAMS ((char *buf, unsigned int len));
 
 /* function.c */
 extern int handle_function PARAMS ((char **op, char **stringp));
Index: expand.c
===================================================================
RCS file: /cvsroot/make/make/expand.c,v
retrieving revision 1.33
diff -u -B -b -r1.33 expand.c
--- expand.c	14 Oct 2002 21:54:04 -0000	1.33
+++ expand.c	25 Oct 2002 21:37:32 -0000
@@ -545,3 +545,28 @@
 
   return value;
 }
+
+/* Install a new variable_buffer context, returning the current one for
+   safe-keeping.  */
+
+void
+install_variable_buffer (char **bufp, unsigned int *lenp)
+{
+  *bufp = variable_buffer;
+  *lenp = variable_buffer_length;
+
+  variable_buffer = 0;
+  initialize_variable_output ();
+}
+
+/* Restore a previously-saved variable_buffer setting (free the current one).
+ */
+
+void
+restore_variable_buffer (char *buf, unsigned int len)
+{
+  free (variable_buffer);
+
+  variable_buffer = buf;
+  variable_buffer_length = len;
+}
Index: function.c
===================================================================
RCS file: /cvsroot/make/make/function.c,v
retrieving revision 1.71
diff -u -B -b -r1.71 function.c
--- function.c	14 Oct 2002 21:54:04 -0000	1.71
+++ function.c	25 Oct 2002 21:37:32 -0000
@@ -1196,7 +1196,17 @@
 static char *
 func_eval (char *o, char **argv, const char *funcname)
 {
+  char *buf;
+  unsigned int len;
+
+  /* Eval the buffer.  Pop the current variable buffer setting so that the
+     eval'd code can use its own without conflicting.  */
+
+  install_variable_buffer (&buf, &len);
+
   eval_buffer (argv[0]);
+
+  restore_variable_buffer (buf, len);
 
   return o;
 }

The short short version

If you can't be bothered with all that you can just download this version that I made. (Note: it may only work with my exact version of Cygwin... and Windows... and exact GPS coordinates...)

Personal tools