Subject: bin/2118: Enable make to fetch system include makefiles from custom places
To: None <gnats-bugs@NetBSD.ORG>
From: Niklas Hallqvist <niklas@filippa.appli.se>
List: netbsd-bugs
Date: 02/23/1996 20:40:08
>Number:         2118
>Category:       bin
>Synopsis:       Enable make to fetch system include makefiles from custom places
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Feb 23 15:50:03 1996
>Last-Modified:
>Originator:     Niklas Hallqvist
>Organization:
	
>Release:        960212
>Environment:
System: OpenBSD filippa.appli.se 1.2 OpenBSD 1.2 (FILIPPA) #28: Mon Feb 19 00:15:28 MET 1996 root@filippa.appli.se:/u3/OpenBSD/src/sys/arch/amiga/compile/FILIPPA amiga


>Description:
	Our make requires the system makefiles to bin /usr/share/mk.  This
	is bad, as you can't build a system under a $DESTDIR environment using
	the $DESTDIR installed system makefiles.  There is also no way of
	layering the system makefiles with search paths.  Say you want to
	build something with a custom bsd.man.mk but the rest unchanged.

>How-To-Repeat:
	Try building a system into DESTDIR with some custome *.mk file in
	$DESTDIR/usr/share/mk.  Note that you cannot do it without changing
	the global /usr/share/mk file.

>Fix:
	My proposed solution is to add an option: -m that, if present,
	overrides the system include path: /usr/share/mk.  Multiple options
	can be given so that a search path is built, just like the -I
	option does for the non-system include search path.

	A nice usage for this is:

	DESTDIR=/foo/bar; export DESTDIR
	(cd share/mk; make install)
	MAKEFLAGS=-m$DESTDIR/usr/share/mk; export MAKEFLAGS
	make build

	Side note: PSD.doc/tutorial.ms is way out of date...
	I added documentation for the -m option, but didn't try to fix
	all the errors in there.

=== cd /u3/OpenBSD/src/usr.bin/make/
=== /usr/local/bin/cvs diff -c main.c make.1 make.h parse.c pathnames.h

Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/make/main.c,v
retrieving revision 1.4
diff -c -r1.4 main.c
*** main.c	1996/02/22 22:24:49	1.4
--- main.c	1996/02/23 17:34:56
***************
*** 161,169 ****
  
  	optind = 1;	/* since we're called more than once */
  #ifdef REMOTE
! # define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
  #else
! # define OPTFLAGS "BD:I:PSd:ef:ij:knqrst"
  #endif
  rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
  		switch(c) {
--- 161,169 ----
  
  	optind = 1;	/* since we're called more than once */
  #ifdef REMOTE
! # define OPTFLAGS "BD:I:L:PSd:ef:ij:km:nqrst"
  #else
! # define OPTFLAGS "BD:I:PSd:ef:ij:km:nqrst"
  #endif
  rearg:	while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
  		switch(c) {
***************
*** 274,279 ****
--- 274,284 ----
  			keepgoing = TRUE;
  			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
  			break;
+ 		case 'm':
+ 			Dir_AddDir(sysIncPath, optarg);
+ 			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
+ 			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+ 			break;
  		case 'n':
  			noExecute = TRUE;
  			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
***************
*** 399,404 ****
--- 404,413 ----
  	char cdpath[MAXPATHLEN + 1];
  	struct utsname utsname;
      	char *machine = getenv("MACHINE");
+ 	Lst sysMkPath;			/* Path of sys.mk */
+ 	char *cp = NULL, *start;
+ 					/* avoid faults on read-only strings */
+ 	static char syspath[] = _PATH_DEFSYSPATH;
  
  #ifdef RLIMIT_NOFILE
  	/*
***************
*** 601,613 ****
  	} else
  		Var_Set(".TARGETS", "", VAR_GLOBAL);
  
  	/*
! 	 * Read in the built-in rules first, followed by the specified makefile,
! 	 * if it was (makefile != (char *) NULL), or the default Makefile and
! 	 * makefile, in that order, if it wasn't.
  	 */
! 	 if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
! 		Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
  
  	if (!Lst_IsEmpty(makefiles)) {
  		LstNode ln;
--- 610,650 ----
  	} else
  		Var_Set(".TARGETS", "", VAR_GLOBAL);
  
+ 
+ 	/*
+ 	 * If no user-supplied system path was given (through the -m option)
+ 	 * add the directories from the DEFSYSPATH (more than one may be given
+ 	 * as dir1:...:dirn) to the system include path.
+ 	 */
+ 	if (Lst_IsEmpty(sysIncPath)) {
+ 		for (start = syspath; *start != '\0'; start = cp) {
+ 			for (cp = start; *cp != '\0' && *cp != ':'; cp++) 
+ 				continue;
+ 			if (*cp == '\0') {
+ 				Dir_AddDir(sysIncPath, start);
+ 			} else {
+ 				*cp++ = '\0';
+ 				Dir_AddDir(sysIncPath, start);
+ 			}
+ 		}
+ 	}
+ 
  	/*
! 	 * Read in the built-in rules first, followed by the specified
! 	 * makefile, if it was (makefile != (char *) NULL), or the default
! 	 * Makefile and makefile, in that order, if it wasn't.
  	 */
! 	if (!noBuiltins) {
! 		LstNode ln;
! 
! 		sysMkPath = Lst_Init (FALSE);
! 		Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
! 		if (Lst_IsEmpty(sysMkPath))
! 			Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
! 		ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
! 		if (ln != NILLNODE)
! 			Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
! 	}
  
  	if (!Lst_IsEmpty(makefiles)) {
  		LstNode ln;
***************
*** 745,751 ****
  ReadMakefile(fname)
  	char *fname;		/* makefile to read */
  {
! 	extern Lst parseIncPath, sysIncPath;
  	FILE *stream;
  	char *name, path[MAXPATHLEN + 1];
  
--- 782,788 ----
  ReadMakefile(fname)
  	char *fname;		/* makefile to read */
  {
! 	extern Lst parseIncPath;
  	FILE *stream;
  	char *name, path[MAXPATHLEN + 1];
  
***************
*** 990,996 ****
  {
  	(void)fprintf(stderr,
  "usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
!             [-I directory] [-j max_jobs] [variable=value]\n");
  	exit(2);
  }
  
--- 1027,1033 ----
  {
  	(void)fprintf(stderr,
  "usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
!             [-I directory] [-j max_jobs] [-m directory] [variable=value]\n");
  	exit(2);
  }
  
Index: make.1
===================================================================
RCS file: /cvs/src/usr.bin/make/make.1,v
retrieving revision 1.4
diff -c -r1.4 make.1
*** make.1	1995/12/17 13:42:00	1.4
--- make.1	1996/02/23 17:35:44
***************
*** 47,52 ****
--- 47,53 ----
  .Op Fl I Ar directory
  .Bk -words
  .Op Fl j Ar max_jobs
+ .Op Fl m Ar directory
  .Ek
  .Op Ar variable=value
  .Op Ar target ...
***************
*** 130,137 ****
  Multiple makefile's may be specified, and are read in the order specified.
  .It Fl I Ar directory
  Specify a directory in which to search for makefiles and included makefiles.
! The system makefile directory is automatically included as part of this
! list.
  .It Fl i
  Ignore non-zero exit of shell commands in the makefile.
  Equivalent to specifying
--- 131,139 ----
  Multiple makefile's may be specified, and are read in the order specified.
  .It Fl I Ar directory
  Specify a directory in which to search for makefiles and included makefiles.
! The system makefile directory (or directories, see the
! .Fl m
! option) is automatically included as part of this list.
  .It Fl i
  Ignore non-zero exit of shell commands in the makefile.
  Equivalent to specifying
***************
*** 146,151 ****
--- 148,161 ----
  .It Fl k
  Continue processing after errors are encountered, but only on those targets
  that do not depend on the target whose creation caused the error.
+ .It Fl m Ar directory
+ Specify a directory in which to search for sys.mk and makefiles included
+ via the <...> style.  Multiple directories can be added to form a search path.
+ This path will override the default system include path: /usr/share/mk.
+ Furthermore the system include path will be appended to the search path used
+ for "..."-style inclusions (see the
+ .Fl I
+ option).
  .It Fl n
  Display the commands that would have been executed, but do not actually
  execute them.
Index: make.h
===================================================================
RCS file: /cvs/src/usr.bin/make/make.h,v
retrieving revision 1.3
diff -c -r1.3 make.h
*** make.h	1996/02/22 22:24:50	1.3
--- make.h	1996/02/23 17:36:04
***************
*** 326,331 ****
--- 326,333 ----
  
  extern Boolean	oldVars;    	/* Do old-style variable substitution */
  
+ extern Lst	sysIncPath;	/* The system include path. */
+ 
  /*
   * debug control:
   *	There is one bit per module.  It is up to the module what debug
Index: parse.c
===================================================================
RCS file: /cvs/src/usr.bin/make/parse.c,v
retrieving revision 1.4
diff -c -r1.4 parse.c
*** parse.c	1996/02/22 22:24:51	1.4
--- parse.c	1996/02/23 17:38:23
***************
*** 2644,2673 ****
  void
  Parse_Init ()
  {
- 	char *cp = NULL, *start;
- 					/* avoid faults on read-only strings */
- 	static char syspath[] = _PATH_DEFSYSPATH;
-     
      mainNode = NILGNODE;
      parseIncPath = Lst_Init (FALSE);
      sysIncPath = Lst_Init (FALSE);
      includes = Lst_Init (FALSE);
      targCmds = Lst_Init (FALSE);
- 
-     /*
-      * Add the directories from the DEFSYSPATH (more than one may be given
-      * as dir1:...:dirn) to the system include path.
-      */
-     for (start = syspath; *start != '\0'; start = cp) {
- 	for (cp = start; *cp != '\0' && *cp != ':'; cp++) 
- 	    continue;
- 	if (*cp == '\0') {
- 	    Dir_AddDir(sysIncPath, start);
- 	} else {
- 	    *cp++ = '\0';
- 	    Dir_AddDir(sysIncPath, start);
- 	}
-     }
  }
  
  void
--- 2644,2654 ----
Index: pathnames.h
===================================================================
RCS file: /cvs/src/usr.bin/make/pathnames.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 pathnames.h
*** pathnames.h	1995/10/18 08:45:43	1.1.1.1
--- pathnames.h	1996/02/23 17:38:24
***************
*** 38,42 ****
  
  #define	_PATH_OBJDIR		"obj"
  #define	_PATH_DEFSHELLDIR	"/bin"
! #define	_PATH_DEFSYSMK		"/usr/share/mk/sys.mk"
  #define	_PATH_DEFSYSPATH	"/usr/share/mk"
--- 38,42 ----
  
  #define	_PATH_OBJDIR		"obj"
  #define	_PATH_DEFSHELLDIR	"/bin"
! #define	_PATH_DEFSYSMK		"sys.mk"
  #define	_PATH_DEFSYSPATH	"/usr/share/mk"
=== cd /u3/OpenBSD/src/usr.bin/make/PSD.doc/
=== /usr/local/bin/cvs diff -c tutorial.ms

Index: tutorial.ms
===================================================================
RCS file: /cvs/src/usr.bin/make/PSD.doc/tutorial.ms,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 tutorial.ms
*** tutorial.ms	1995/10/18 08:45:44	1.1.1.1
--- tutorial.ms	1996/02/23 17:42:51
***************
*** 1271,1276 ****
--- 1271,1285 ----
  will turn it off, and vice versa. Note that this locking will not
  prevent \fIyou\fP from invoking PMake twice in the same place \*- if
  you own the lock file, PMake will warn you about it but continue to execute.
+ .IP "\fB\-m\fP \fIdirectory\fP"
+ .Ix 0 def flags -m
+ Tells PMake another place to search for included makefiles via the <...>
+ style.  Several
+ .B \-m
+ options can be given to form a search path.  If this construct is used the
+ default system makefile search path is completely overridden.
+ To be explained in chapter 3, section 3.2.
+ .Rm 2 3.2
  .IP \fB\-n\fP
  .Ix 0 def flags -n
  This flag tells PMake not to execute the commands needed to update the
***************
*** 1911,1921 ****
  .DE
  The difference between the two is where PMake searches for the file:
  the first way, PMake will look for
! the file only in the system makefile directory (to find out what that
! directory is, give PMake the
  .B \-h
  flag).
  .Ix 0 ref flags -h
  For files in double-quotes, the search is more complex:
  .RS
  .IP 1)
--- 1920,1934 ----
  .DE
  The difference between the two is where PMake searches for the file:
  the first way, PMake will look for
! the file only in the system makefile directory (or directories)
! (to find out what that directory is, give PMake the
  .B \-h
  flag).
  .Ix 0 ref flags -h
+ The system makefile directory search path can be overridden via the
+ .B \-m
+ option.
+ .Ix 0 ref flags -m
  For files in double-quotes, the search is more complex:
  .RS
  .IP 1)

>Audit-Trail:
>Unformatted: