Subject: make(1) hack to get NetBSD tools working on Mac OS X
To: None <tech-toolchain@netbsd.org>
From: Jason R Thorpe <thorpej@wasabisystems.com>
List: tech-toolchain
Date: 03/13/2003 09:46:48
--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

So, yesterday I managed to get the tools finally building on a Mac OS X
host.

The biggest problem is that ARG_MAX is only 64K on OS X (vs. 256K on many
other modern systems).  This presents a problem, since bootstrapping the
tools causes many make variables to be set on the command line, meaning
that we blow ARG_MAX pretty quickly.

My solution to this was to cause make(1) to not export variables set on
the command line to the environment (as required by POSIX).  It's important
to note that when a variable is set on the command line, like so:

	make FOO=foo

the environment actually gets two copies of the variable:

FOO=foo
MAKEFLAGS="FOO=foo"

My patch only eliminates the former; command line settings of variables
still override settings in the Makefile (which is required for proper
operation when e.g. building the tools).

This modified behavior is only enabled if the -X option is specified to
make(1), so there are a few other patches to set this option for OS X
in various places.

Note that I'm not entirely happy with the patch to build.sh; the -X is only
necessary when building in src/tools, so if someone could clue me in how to
set the flag when we descend into src/tools or when we build from there
directly, that'd be keen.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>

--RnlQjJ0d97Da+TV1
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=make-noenv-patch

Index: build.sh
===================================================================
RCS file: /cvsroot/src/build.sh,v
retrieving revision 1.94
diff -c -r1.94 build.sh
*** build.sh	2003/03/07 01:22:16	1.94
--- build.sh	2003/03/13 17:33:46
***************
*** 88,94 ****
  
  	# Set defaults.
  	toolprefix=nb
! 	MAKEFLAGS=
  	makeenv=
  	makewrapper=
  	runcmd=
--- 88,100 ----
  
  	# Set defaults.
  	toolprefix=nb
! 	# Mac OS X has a silly ARG_MAX (64K).  -X prevents make(1) from
! 	# exporting variables in the environment redundantly.
! 	if [ "${uname_s}" = "Darwin" ]; then
! 		MAKEFLAGS=-X
! 	else
! 		MAKEFLAGS=
! 	fi
  	makeenv=
  	makewrapper=
  	runcmd=
Index: tools/Makefile.gnuhost
===================================================================
RCS file: /cvsroot/src/tools/Makefile.gnuhost,v
retrieving revision 1.17
diff -c -r1.17 Makefile.gnuhost
*** tools/Makefile.gnuhost	2003/02/07 01:52:51	1.17
--- tools/Makefile.gnuhost	2003/03/13 17:33:46
***************
*** 52,58 ****
  CONFIGURE_ARGS+=--prefix=${TOOLDIR} --disable-shared
  
  .ifndef _NOWRAPPER
! MAKE_ARGS:=	-f ${.PARSEDIR}/Makefile.gnuwrap ${MAKE_ARGS}
  .else
  MAKE_ARGS+=	_NOWRAPPER=1
  .endif
--- 52,65 ----
  CONFIGURE_ARGS+=--prefix=${TOOLDIR} --disable-shared
  
  .ifndef _NOWRAPPER
! # Some systems have a small ARG_MAX.  On such systems, prevent Make
! # variables set on the command line from being exported in the
! # environment (they will still be set in MAKEOVERRIDES).
! BUILD_OSTYPE!=	uname -s
! .if ${BUILD_OSTYPE} == "Darwin"
! __noenvexport=	-X
! .endif
! MAKE_ARGS:=	${__noenvexport} -f ${.PARSEDIR}/Makefile.gnuwrap ${MAKE_ARGS}
  .else
  MAKE_ARGS+=	_NOWRAPPER=1
  .endif
Index: tools/Makefile.gnuwrap
===================================================================
RCS file: /cvsroot/src/tools/Makefile.gnuwrap,v
retrieving revision 1.8
diff -c -r1.8 Makefile.gnuwrap
*** tools/Makefile.gnuwrap	2001/11/22 08:20:07	1.8
--- tools/Makefile.gnuwrap	2003/03/13 17:33:46
***************
*** 20,26 ****
  
  # Make sure this file gets re-loaded recursively.
  .ifndef _NOWRAPPER
  _GNUWRAPPER:=	${.PARSEDIR}/${.PARSEFILE}
! MAKE:=		${MAKE} -f ${_GNUWRAPPER}
  .endif
  .endif
--- 20,33 ----
  
  # Make sure this file gets re-loaded recursively.
  .ifndef _NOWRAPPER
+ # Some systems have a small ARG_MAX.  On such systems, prevent Make
+ # variables set on the command line from being exported in the
+ # environment (they will still be set in MAKEOVERRIDES).
+ BUILD_OSTYPE!=  uname -s
+ .if ${BUILD_OSTYPE} == "Darwin"
+ __noenvexport=  -X
+ .endif
  _GNUWRAPPER:=	${.PARSEDIR}/${.PARSEFILE}
! MAKE:=		${MAKE} ${__noenvexport} -f ${_GNUWRAPPER}
  .endif
  .endif
Index: usr.bin/make/main.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/main.c,v
retrieving revision 1.86
diff -c -r1.86 main.c
*** usr.bin/make/main.c	2003/02/26 08:59:12	1.86
--- usr.bin/make/main.c	2003/03/13 17:33:47
***************
*** 141,146 ****
--- 141,147 ----
  Boolean			checkEnvFirst;	/* -e flag */
  Boolean			parseWarnFatal;	/* -W flag */
  Boolean			jobServer; 	/* -J flag */
+ Boolean			varNoExportEnv;	/* -X flag */
  static Boolean		jobsRunning;	/* TRUE if the jobs might be running */
  static const char *	tracefile;
  static char *		Check_Cwd_av(int, char **, int);
***************
*** 178,186 ****
  
  	optind = 1;	/* since we're called more than once */
  #ifdef REMOTE
! # define OPTFLAGS "BD:I:J:L:NPST:V:Wd:ef:ij:km:nqrst"
  #else
! # define OPTFLAGS "BD:I:J:NPST:V:Wd:ef:ij:km:nqrst"
  #endif
  rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
  		switch(c) {
--- 179,187 ----
  
  	optind = 1;	/* since we're called more than once */
  #ifdef REMOTE
! # define OPTFLAGS "BD:I:J:L:NPST:V:WXd:ef:ij:km:nqrst"
  #else
! # define OPTFLAGS "BD:I:J:NPST:V:WXd:ef:ij:km:nqrst"
  #endif
  rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != -1) {
  		switch(c) {
***************
*** 260,265 ****
--- 261,270 ----
  			break;
  		case 'W':
  			parseWarnFatal = TRUE;
+ 			break;
+ 		case 'X':
+ 			varNoExportEnv = TRUE;
+ 			Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
  			break;
  		case 'd': {
  			char *modules = optarg;
Index: usr.bin/make/make.1
===================================================================
RCS file: /cvsroot/src/usr.bin/make/make.1,v
retrieving revision 1.74
diff -c -r1.74 make.1
*** usr.bin/make/make.1	2003/02/25 10:35:47	1.74
--- usr.bin/make/make.1	2003/03/13 17:33:48
***************
*** 41,47 ****
  .Nd maintain program dependencies
  .Sh SYNOPSIS
  .Nm
! .Op Fl BeikNnqrstW
  .Bk -words
  .Op Fl D Ar variable
  .Ek
--- 41,47 ----
  .Nd maintain program dependencies
  .Sh SYNOPSIS
  .Nm
! .Op Fl BeikNnqrstWX
  .Bk -words
  .Op Fl D Ar variable
  .Ek
***************
*** 233,243 ****
--- 233,257 ----
  with a blank line for each null or undefined variable.
  .It Fl W
  Treat any warnings during makefile parsing as errors.
+ .It Fl X
+ Don't export variables passed on the command line to the environment
+ individually.
+ Variables passed on the command line are still exported
+ via the
+ .Va MAKEFLAGS
+ environment variable.
+ This option may be useful on systems which have a small limit on the
+ size of command arguments.
  .It Ar variable=value
  Set the value of the variable
  .Ar variable
  to
  .Ar value .
+ Normally, all values passed on the command line are also exported to
+ sub-makes in the environment.
+ The
+ .Fl X
+ flag disables this behavior.
  .El
  .Pp
  There are seven different types of lines in a makefile: file dependency
Index: usr.bin/make/make.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/make.h,v
retrieving revision 1.44
diff -c -r1.44 make.h
*** usr.bin/make/make.h	2002/06/15 18:24:57	1.44
--- usr.bin/make/make.h	2003/03/13 17:33:49
***************
*** 336,341 ****
--- 336,344 ----
  extern Boolean	parseWarnFatal;	/* TRUE if makefile parsing warnings are
  				 * treated as errors */
  
+ extern Boolean	varNoExportEnv;	/* TRUE if we should not export variables
+ 				 * set on the command line to the env. */
+ 
  extern GNode    *DEFAULT;    	/* .DEFAULT rule */
  
  extern GNode    *VAR_GLOBAL;   	/* Variables defined in a global context, e.g
Index: usr.bin/make/var.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/var.c,v
retrieving revision 1.70
diff -c -r1.70 var.c
*** usr.bin/make/var.c	2002/06/15 18:24:58	1.70
--- usr.bin/make/var.c	2003/03/13 17:33:53
***************
*** 471,477 ****
       */
      if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
  
! 	setenv(name, val, 1);
  
  	Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
      }
--- 471,484 ----
       */
      if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
  
! 	/*
! 	 * If requested, don't export these in the environment
! 	 * individually.  We still put them in MAKEOVERRIDES so
! 	 * that the command-line settings continue to override
! 	 * Makefile settings.
! 	 */
! 	if (varNoExportEnv != TRUE)
! 	    setenv(name, val, 1);
  
  	Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
      }

--RnlQjJ0d97Da+TV1--