[net.sources] VPATH for 4.2bsd make

eager@amd.UUCP (Mike Eager) (11/28/84)

Updates to 4.2bsd make to provide VPATH support --

These updates add a new macro name VPATH, which acts similar to the System V
VPATH support.  No guarantee that they are fully identically.

VPATH is set to a path list of directories separated by colons.  When make 
searches for a file as a result of a dependency relation, it will first search
the current directory and then each of the directories on the VPATH list.  If
the file is found, the actual path to the file will be used, rather than just
the filename.

This may be used to produce modifications of a base version of a program by
creating a development directory, pointing to the base directory with VPATH,
and making the modifications in the development directory.  Files which are
in the base directory will be found as needed.  Be sure to use -I to point
to the base library for includes.

A Makefile for make is included below which illustrates the use of VPATH.
Create a new version of make using the existing Makefile and then the updated
Makefile can be used.

-- Mike Eager
   amd!eager
------------------------------------------------------------------------------

diff -c /usr/src/bin/make/Makefile ./Makefile
*** /usr/src/bin/make/Makefile	Wed Feb  9 14:21:54 1983
--- ./Makefile	Fri Oct  5 10:33:00 1984
***************
*** 1,6
  # Description file for the Make command
  # Makefile 4.3 82/10/19
  
  OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o 
  LIBES= 
  LINT=	lint -ps

--- 1,7 -----
  # Description file for the Make command
  # Makefile 4.3 82/10/19
  
+ VPATH=.:/usr/src/bin/make
  OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o 
  LIBES= 
  LINT=	lint -ps
***************
*** 4,10
  OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o 
  LIBES= 
  LINT=	lint -ps
! CFLAGS=	-O -DASCARCH
  
  all:	make
  

--- 5,11 -----
  OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o 
  LIBES= 
  LINT=	lint -ps
! CFLAGS=	-O -DASCARCH -I. -I/usr/src/bin/make 
  
  all:	make
  
diff -c /usr/src/bin/make/defs ./defs
*** /usr/src/bin/make/defs	Fri Jul  1 23:27:09 1983
--- ./defs	Mon Sep 24 00:02:50 1984
***************
*** 67,72
  	{
  	struct nameblock *nxtnameblock;
  	char *namep;
  	struct lineblock *linep;
  	int done:3;
  	int septype:3;

--- 67,73 -----
  	{
  	struct nameblock *nxtnameblock;
  	char *namep;
+ 	char *alias;
  	struct lineblock *linep;
  	int done:3;
  	int septype:3;
diff -c /usr/src/bin/make/doname.c ./doname.c
*** /usr/src/bin/make/doname.c	Mon Apr  4 16:26:10 1983
--- ./doname.c	Thu Oct  4 15:49:26 1984
***************
*** 52,58
  tdep = 0;
  implcom = 0;
  explcom = 0;
! ptime = exists(p->namep);
  ptime1 = 0;
  didwork = NO;
  p->done = 1;	/* avoid infinite loops */

--- 52,58 -----
  tdep = 0;
  implcom = 0;
  explcom = 0;
! ptime = exists(p); 
  ptime1 = 0;
  didwork = NO;
  p->done = 1;	/* avoid infinite loops */
***************
*** 122,127
  	pnamep = suffp->depname->namep;
  	if(suffix(p->namep , pnamep , prefix))
  		{
  		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
  		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
  		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)

--- 122,128 -----
  	pnamep = suffp->depname->namep;
  	if(suffix(p->namep , pnamep , prefix))
  		{
+ 
  		srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL);
  		for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock)
  		    for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock)
***************
*** 136,142
  if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
  				if(td > tdep) tdep = td;
  				setvar("*", prefix);
! 				setvar("<", copys(sourcename));
  				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
  					if(implcom = lp2->shp) break;
  				goto endloop;

--- 137,144 -----
  if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td);
  				if(td > tdep) tdep = td;
  				setvar("*", prefix);
! 				if (p2->alias) setvar("<", copys(p2->alias));
! 				else setvar("<", copys(p2->namep));
  				for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
  					if(implcom = lp2->shp) break;
  				goto endloop;
***************
*** 161,167
  	else if(p->septype == 0)
  		if(p1=srchname(".DEFAULT"))
  			{
! 			setvar("<", p->namep);
  			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
  				if(implcom = lp2->shp)
  					{

--- 163,170 -----
  	else if(p->septype == 0)
  		if(p1=srchname(".DEFAULT"))
  			{
! 			if (p->alias) setvar("<", p->alias);
! 			else setvar("<", p->namep);
  			for(lp2 = p1->linep ; lp2 ; lp2 = lp2->nxtlineblock)
  				if(implcom = lp2->shp)
  					{
***************
*** 178,184
  			fatal1(" Don't know how to make %s", p->namep);
  
  	setvar("@", (char *) NULL);
! 	if(noexflag || (ptime = exists(p->namep)) == 0)
  		ptime = prestime();
  	}
  

--- 181,187 -----
  			fatal1(" Don't know how to make %s", p->namep);
  
  	setvar("@", (char *) NULL);
! 	if(noexflag || (ptime = exists(p)) == 0)
  		ptime = prestime();
  	}
  
***************
*** 205,210
  struct varblock *varptr();
  int ign, nopr;
  char string[OUTMAX];
  
  ++ndocoms;
  if(questflag)

--- 208,214 -----
  struct varblock *varptr();
  int ign, nopr;
  char string[OUTMAX];
+ char string2[OUTMAX];
  
  ++ndocoms;
  if(questflag)
***************
*** 221,227
  
  else for( ; q ; q = q->nxtshblock )
  	{
! 	subst(q->shbp,string);
  
  	ign = ignerr;
  	nopr = NO;

--- 225,232 -----
  
  else for( ; q ; q = q->nxtshblock )
  	{
! 	subst(q->shbp,string2);
! 	fixname(string2, string);
  
  	ign = ignerr;
  	nopr = NO;
diff -c /usr/src/bin/make/files.c ./files.c
*** /usr/src/bin/make/files.c	Thu Jun 30 08:29:14 1983
--- ./files.c	Thu Oct  4 15:49:58 1984
***************
*** 131,136
  	0 };
  
  #include "defs"
  
  
  TIMETYPE exists(filename)

--- 131,137 -----
  	0 };
  
  #include "defs"
+ #include <sys/stat.h>
  
  
  
***************
*** 133,140
  #include "defs"
  
  
! TIMETYPE exists(filename)
! char *filename;
  {
  #include <sys/stat.h>
  struct stat buf;

--- 134,143 -----
  #include <sys/stat.h>
  
  
! 
! TIMETYPE 
! exists(pname)
! struct nameblock *pname;
  {
  struct stat buf;
  register char *s, *filename;
***************
*** 136,142
  TIMETYPE exists(filename)
  char *filename;
  {
- #include <sys/stat.h>
  struct stat buf;
  register char *s;
  TIMETYPE lookarch();

--- 139,144 -----
  exists(pname)
  struct nameblock *pname;
  {
  struct stat buf;
  register char *s, *filename;
  TIMETYPE lookarch();
***************
*** 138,144
  {
  #include <sys/stat.h>
  struct stat buf;
! register char *s;
  TIMETYPE lookarch();
  
  for(s = filename ; *s!='\0' && *s!='(' ; ++s)

--- 140,146 -----
  struct nameblock *pname;
  {
  struct stat buf;
! register char *s, *filename;
  TIMETYPE lookarch();
  extern char *findfl();
  
***************
*** 140,145
  struct stat buf;
  register char *s;
  TIMETYPE lookarch();
  
  for(s = filename ; *s!='\0' && *s!='(' ; ++s)
  	;

--- 142,148 -----
  struct stat buf;
  register char *s, *filename;
  TIMETYPE lookarch();
+ extern char *findfl();
  
  filename = pname->namep;
  
***************
*** 141,146
  register char *s;
  TIMETYPE lookarch();
  
  for(s = filename ; *s!='\0' && *s!='(' ; ++s)
  	;
  

--- 144,151 -----
  TIMETYPE lookarch();
  extern char *findfl();
  
+ filename = pname->namep;
+ 
  for(s = filename ; *s!='\0' && *s!='(' ; ++s)
  	;
  
***************
*** 148,153
  	return(lookarch(filename));
  
  if (stat(filename, &buf) < 0)
  	return(0);
  else	return(buf.st_mtime);
  }

--- 153,166 -----
  	return(lookarch(filename));
  
  if (stat(filename, &buf) < 0)
+ {
+ 	s = findfl(filename);
+ 	if(s != (char *)-1)
+ 	{
+ 		pname->alias = copys(s);
+ 		if(stat(pname->alias, &buf) == 0)
+ 			return(buf.st_mtime);
+ 	}
  	return(0);
  }
  else	return(buf.st_mtime);
***************
*** 149,154
  
  if (stat(filename, &buf) < 0)
  	return(0);
  else	return(buf.st_mtime);
  }
  

--- 162,168 -----
  			return(buf.st_mtime);
  	}
  	return(0);
+ }
  else	return(buf.st_mtime);
  }
  
***************
*** 181,187
  struct depblock *thisdbl;
  struct dirhdr *od;
  struct pattern *patp;
! 
  struct direct *dptr;
  
  

--- 195,202 -----
  struct depblock *thisdbl;
  struct dirhdr *od;
  struct pattern *patp;
! struct varblock *cp, *varptr();
! char *path, pth[100], *strcpy();
  struct direct *dptr;
  
  
***************
*** 203,209
  
  if(endir==0)
  	{
- 	dirname = ".";
  	dirpref = "";
  	filepat = pat;
  	}

--- 218,223 -----
  
  if(endir==0)
  	{
  	dirpref = "";
  	filepat = pat;
  	cp = varptr("VPATH");
***************
*** 206,211
  	dirname = ".";
  	dirpref = "";
  	filepat = pat;
  	}
  else	{
  	dirname = pat;

--- 220,233 -----
  	{
  	dirpref = "";
  	filepat = pat;
+ 	cp = varptr("VPATH");
+ 	if (*cp->varval == 0) path = ".";
+ 	else {
+ 	       path = pth; 
+ 	       *path = '\0';
+ 	       if (*cp->varval != '.') strcpy(pth,".:");
+ 	       strcat(pth, cp->varval);
+ 	       }
  	}
  else	{
  	*endir = '\0';
***************
*** 208,214
  	filepat = pat;
  	}
  else	{
- 	dirname = pat;
  	*endir = '\0';
  	dirpref = concat(dirname, "/", temp);
  	filepat = endir+1;

--- 230,235 -----
  	       }
  	}
  else	{
  	*endir = '\0';
  	path = strcpy(pth, pat);
  	dirpref = concat(pat, "/", temp);
***************
*** 210,216
  else	{
  	dirname = pat;
  	*endir = '\0';
! 	dirpref = concat(dirname, "/", temp);
  	filepat = endir+1;
  	}
  

--- 231,238 -----
  	}
  else	{
  	*endir = '\0';
! 	path = strcpy(pth, pat);
! 	dirpref = concat(pat, "/", temp);
  	filepat = endir+1;
  	}
  
***************
*** 214,219
  	filepat = endir+1;
  	}
  
  dirf = NULL;
  cldir = NO;
  

--- 236,249 -----
  	filepat = endir+1;
  	}
  
+ while (*path) {			/* Loop thru each VPATH directory */
+   dirname = path;
+   for (; *path; path++)
+     if (*path == ':') {
+       *path++ = '\0';
+       break;
+       }
+ 
  dirf = NULL;
  cldir = NO;
  
***************
*** 274,279
  	closedir(dirf);
  	dirf = NULL;
  }
  return(thisdbl);
  }
  

--- 304,310 -----
  	closedir(dirf);
  	dirf = NULL;
  }
+ } /* End of VPATH loop */
  return(thisdbl);
  }
  
***************
*** 532,535
  	if(*a++ != *b++)
  		return(NO);
  return(YES);
  }

--- 563,645 -----
  	if(*a++ != *b++)
  		return(NO);
  return(YES);
+ }
+ 
+ 
+ /*
+  *	findfl(name)	(like execvp, but does path search and finds files)
+  */
+ static char fname[128];
+ 
+ char *execat();
+ 
+ char *findfl(name)
+ register char *name;
+ {
+ 	register char *p;
+ 	register struct varblock *cp;
+ 	struct stat buf;
+ 
+ 	for (p = name; *p; p++) 
+ 		if(*p == '/') return(name);
+ 
+ 	cp = varptr("VPATH");
+ 	if(*cp->varval == 0)
+ 		p = ":";
+ 	else
+ 		p = cp->varval;
+ 
+ 	do
+ 	{
+ 		p = execat(p, name, fname);
+ 		if(stat(fname,&buf) >= 0)
+ 			return(fname);
+ 	} while (p);
+ 	return((char *)-1);
+ }
+ 
+ char *execat(s1, s2, si)
+ register char *s1, *s2;
+ char *si;
+ {
+ 	register char *s;
+ 
+ 	s = si;
+ 	while (*s1 && *s1 != ':' && *s1 != '-')
+ 		*s++ = *s1++;
+ 	if (si != s)
+ 		*s++ = '/';
+ 	while (*s2)
+ 		*s++ = *s2++;
+ 	*s = '\0';
+ 	return(*s1? ++s1: 0);
+ }
+ 
+ 
+ /* copy s to d, changing file names to file aliases */
+ fixname(s, d)
+ char *s, *d;
+ {
+ 	register char *r, *q;
+ 	struct nameblock *pn;
+ 	char name[100];
+ 
+ 	while (*s) {
+ 		if (isspace(*s)) *d++ = *s++;
+ 		else {
+ 			r = name;
+ 			while (*s) {
+ 				if (isspace(*s)) break; 
+ 				*r++ = *s++;
+ 				}
+ 			*r = '\0';
+  		
+ 			if (((pn = srchname(name)) != 0) && (pn->alias))
+ 				q = pn->alias;
+ 			else q = name;
+ 	
+ 			while (*q) *d++ = *q++;
+ 			}
+ 		}
+ 	*d = '\0';
  }
diff -c /usr/src/bin/make/gcos.c ./gcos.c
*** /usr/src/bin/make/gcos.c	Tue Jun  8 21:15:46 1982
--- ./gcos.c	Sun Sep 23 23:21:26 1984
***************
*** 137,144
  	catsiz = i;
  	}
  
!  exists( cp ) char *cp; {
! 	char *s, name[13];
  	int i, *p, bcd[2];
  
  /*

--- 137,145 -----
  	catsiz = i;
  	}
  
!  exists( p ) 
!  struct nameblock *p; {
! 	char *s, *cp, name[13];
  	int i, *p, bcd[2];
  
  /*
***************
*** 147,152
     at t=1 (long time ago); otherwise, assume it
     does not exist
  */
  
  for(s=cp ; *s ; ++s)
  	if(*s == '/')

--- 148,155 -----
     at t=1 (long time ago); otherwise, assume it
     does not exist
  */
+ 
+ cp = p->namep;
  
  for(s=cp ; *s ; ++s)
  	if(*s == '/')