gww@beatnix.UUCP (Gary Winiger) (03/13/88)
Subject: Make(1) does not support file inclusion +Fix Index: bin/make/{Makefile,defs,gram.y,main.c,misc.c} man1/make.1 4.3BSD Description: 4.3BSD make does not support file inclusion. Other makes do. Repeat-By: Use a System V.3 or SunOS makefile with a include directive. Fix: Elxsi received a large third party package that used the SunOS make include directive. Rather than redo all the makefiles, Luong Nguyen-Duy made the following additions to 4.3 make. The attached code solves this problem at Elxsi. Gary.. {ucbvax!sun,uunet,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww --------- cut --------- snip --------- :.,$w diff ------------- Index: /usr/src/etc/make/Makefile *** /tmp/,RCSt1000738 Fri Aug 7 14:07:03 1987 --- Makefile Fri Aug 7 14:05:57 1987 *************** *** 1,6 **** ! # $Header: Makefile,v 1.1 86/12/11 12:53:09 gww Exp $ ENIX BSD # # $Log: Makefile,v $ # Revision 1.1 86/12/11 12:53:09 gww # Initial revision # --- 1,9 ---- ! # $Header: Makefile,v 1.2 87/08/07 14:05:43 gww Exp $ ENIX BSD # # $Log: Makefile,v $ + # Revision 1.2 87/08/07 14:05:43 gww + # Add include Files feature. + # # Revision 1.1 86/12/11 12:53:09 gww # Initial revision # *************** *** 12,18 **** 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 --- 15,22 ---- OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o LIBES= LINT= lint -ps ! DFLAGS= -DINCLUDES ! CFLAGS= -O -DASCARCH ${DFLAGS} -I. -I/usr/src/bin/make all: make *************** *** 20,25 **** --- 24,35 ---- ${CC} -o make ${CFLAGS} ${OBJECTS} ${LIBES} ${OBJECTS}: defs + + .y.c: + /lib/cpp -P -E ${DFLAGS} $*.y >y.tab.y + ${YACC} y.tab.y + rm -f y.tab.y + mv y.tab.c $*.c clean: -rm -f *.o gram.c make a.out errs Index: /usr/src/etc/make/defs *** /tmp/,RCSt1000738 Fri Aug 7 14:07:07 1987 --- defs Fri Aug 7 14:06:02 1987 *************** *** 1,6 **** ! /* $Header: defs,v 1.1 86/12/11 12:53:11 gww Exp $ ENIX BSD * * $Log: defs,v $ * Revision 1.1 86/12/11 12:53:11 gww * Initial revision * --- 1,9 ---- ! /* $Header: defs,v 1.2 87/08/07 14:05:58 gww Exp $ ENIX BSD * * $Log: defs,v $ + * Revision 1.2 87/08/07 14:05:58 gww + * Add include Files feature. + * * Revision 1.1 86/12/11 12:53:11 gww * Initial revision * *************** *** 139,141 **** --- 142,157 ---- int *ckalloc(); struct nameblock *srchname(), *makename(); TIMETYPE exists(); + + #ifdef INCLUDES + struct include_stack + { + FILE *file; + int lineno; + char *nextc; + }; + #define MAX_INCLUDES 20 + extern push(); + extern empty_stack(); + extern FILE *pop(); + #endif INCLUDES Index: /usr/src/etc/make/gram.y *** /tmp/,RCSt1000738 Fri Aug 7 14:07:10 1987 --- gram.y Fri Aug 7 14:06:05 1987 *************** *** 1,15 **** %{#include "defs" /* * $Log: gram.y,v $ * Revision 1.1 86/12/11 12:53:18 gww * Initial revision * */ ! static char *ERcsId = "$Header: gram.y,v 1.1 86/12/11 12:53:18 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)gram.y 4.1 (Berkeley) 81/02/28"; %} %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER %union { struct shblock *yshblock; --- 1,22 ---- %{#include "defs" /* * $Log: gram.y,v $ + * Revision 1.2 87/08/07 14:06:03 gww + * Add include Files feature. + * * Revision 1.1 86/12/11 12:53:18 gww * Initial revision * */ ! static char *ERcsId = "$Header: gram.y,v 1.2 87/08/07 14:06:03 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)gram.y 4.1 (Berkeley) 81/02/28"; %} + #ifdef INCLUDES + %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER INCLUDE + #else %term NAME SHELLINE START MACRODEF COLON DOUBLECOLON GREATER + #endif INCLUDES %union { struct shblock *yshblock; *************** *** 43,48 **** --- 50,58 ---- ; comline: START + #ifdef INCLUDES + | INCLUDE + #endif INCLUDES | MACRODEF | START namelist deplist shellist = { while( --nlefts >= 0) *************** *** 272,278 **** if((c = text[0]) == '\t') return( retsh(text) ); ! if(isalpha(c) || isdigit(c) || c==' ' || c=='.') for(p=text+1; *p!='\0'; ) if(*p == ':') --- 282,293 ---- if((c = text[0]) == '\t') return( retsh(text) ); ! #ifdef INCLUDES ! else if((strncmp(text, "include ", 8) == 0) || ! (strncmp(text, "include\t", 8) == 0)) ! return(do_include(text+8)); ! #endif INCLUDES ! if(isalpha(c) || isdigit(c) || c==' ' || c=='.') for(p=text+1; *p!='\0'; ) if(*p == ':') *************** *** 312,314 **** --- 327,366 ---- return(START); goto again; } + + + + #ifdef INCLUDES + do_include (text) + char *text; + { + register char *p; + register char *pend; + char filename[MAXPATHLEN]; + + /* skip leading white space */ + + for (; *text == ' ' || *text == '\t'; text++) + continue; + + /* get file name */ + + subst(text, filename); /* Substitute for macros */ + + if(dbgflag) printf("Include file: %s\n", filename); + + if (rddescf(filename)) + fatal1("could not do include %s\n", filename); + + return(INCLUDE); + } + #endif INCLUDES Index: /usr/src/etc/make/main.c *** /tmp/,RCSt1000738 Fri Aug 7 14:07:14 1987 --- main.c Fri Aug 7 14:06:09 1987 *************** *** 1,10 **** /* * $Log: main.c,v $ * Revision 1.1 86/12/11 12:53:21 gww * Initial revision * */ ! static char *ERcsId = "$Header: main.c,v 1.1 86/12/11 12:53:21 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)main.c 4.8 (Berkeley) 86/01/09"; # include "defs" /* --- 1,13 ---- /* * $Log: main.c,v $ + * Revision 1.2 87/08/07 14:06:06 gww + * Add include Files feature. + * * Revision 1.1 86/12/11 12:53:21 gww * Initial revision * */ ! static char *ERcsId = "$Header: main.c,v 1.2 87/08/07 14:06:06 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)main.c 4.8 (Berkeley) 86/01/09"; # include "defs" /* *************** *** 280,285 **** --- 283,292 ---- char *descfile; { FILE * k; + #ifdef INCLUDES + extern int yylineno; + extern char *zznextc; + #endif INCLUDES /* read and parse description */ *************** *** 309,315 **** --- 316,338 ---- return( rdd1(stdin) ); if( (k = fopen(descfile,"r")) != NULL) + #ifdef INCLUDES + { + if(fin != NULL) { + push(fin, yylineno, zznextc); + } + if(rdd1(k)) { + fatal("rddescf(), could not make %s ", descfile); + } + else { + if(!empty_stack()) + fin = pop(); + return(0); + } + } + #else return( rdd1(k) ); + #endif INCLUDES return(1); } Index: /usr/src/etc/make/misc.c *** /tmp/,RCSt1000738 Fri Aug 7 14:07:20 1987 --- misc.c Fri Aug 7 14:06:13 1987 *************** *** 1,10 **** /* * $Log: misc.c,v $ * Revision 1.1 86/12/11 12:53:23 gww * Initial revision * */ ! static char *ERcsId = "$Header: misc.c,v 1.1 86/12/11 12:53:23 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)misc.c 4.3 (Berkeley) 85/08/30"; #include "defs" --- 1,13 ---- /* * $Log: misc.c,v $ + * Revision 1.2 87/08/07 14:06:10 gww + * Add include Files feature. + * * Revision 1.1 86/12/11 12:53:23 gww * Initial revision * */ ! static char *ERcsId = "$Header: misc.c,v 1.2 87/08/07 14:06:10 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)misc.c 4.3 (Berkeley) 85/08/30"; #include "defs" *************** *** 345,347 **** --- 348,391 ---- *--qbufp = '\0'; return(qbuf); } + + #ifdef INCLUDES + struct include_stack stack[MAX_INCLUDES]; + static int top = -1; + + push (file, lineno, nextc) + FILE *file; + int lineno; + char *nextc; + { + if ( top < MAX_INCLUDES-1 ) { + top++; + stack[top].file = file; + stack[top].lineno = lineno; + stack[top].nextc = nextc; + } + else fatal1("include depth > %d\n", MAX_INCLUDES); + } + + FILE * + pop() + { + extern int yylineno; + extern char *zznextc; + + if (top == -1) { + fatal("pop() trying to pop null include stack\n"); + } + else { + yylineno = stack[top].lineno; + zznextc = stack[top].nextc; + return(stack[top--].file); + } + } + + + int empty_stack() + { + return( (top == -1) ? 1 : 0 ); + } + #endif INCLUDES Index: /usr/man/man1/make.1 *** /tmp/,RCSt1000941 Fri Aug 7 15:01:47 1987 --- make.1 Fri Aug 7 15:01:20 1987 *************** *** 1,6 **** ! .\" $Header: make.1,v 1.1 86/12/12 16:17:38 gww Exp $ ENIX BSD .\" .\" $Log: make.1,v $ .\" Revision 1.1 86/12/12 16:17:38 gww .\" Initial revision .\" --- 1,9 ---- ! .\" $Header: make.1,v 1.2 87/08/07 15:01:04 gww Exp $ ENIX BSD .\" .\" $Log: make.1,v $ + .\" Revision 1.2 87/08/07 15:01:04 gww + .\" Add include support. + .\" .\" Revision 1.1 86/12/12 16:17:38 gww .\" Initial revision .\" *************** *** 233,238 **** --- 236,254 ---- unless the target is a directory or depends on the special name `.PRECIOUS'. .PP + Files may be included within a + .I makefile + similarly to the + .I #include + directive of the C preprocessor. + If the first seven characters of a line in a + .I makefile + are `include' and the eighth is either a blank or tab, the remainder of + the line is interpreted as the path name of the file to be included. + Marco substitutions are done on the `include' line before the path name + is interpreted. + Includes may be nested up to 20 deep. + .PP Other options: .TP .B \-i *************** *** 281,283 **** --- 297,303 ---- .PP `VPATH' is intended to act like the System V `VPATH' support, but there is no guarantee that it functions identically. + .PP + `Include' is intended to act like the System V `include' support, + but there is no guarantee that it functions identically. + `include' does not follow `VPATH's.
gww@beatnix.UUCP (Gary Winiger) (03/13/88)
Subject: Make(1) does not function in conjunction with RCS +Fix Index: bin/make/{Makefile,defs,doname.c,files.c,main.c,misc.c}, man1/make.1 4.3BSD Description: Make doesn't work in conjunction with RCS as System V works in conjunction with SCCS. Repeat-By: Try to make a target when not all the files are checked out. Fix: In 1984 a rework of the 4.1 make by Charles LaBrec (crl@purdue) was distributed on the Usenix 84.1 distribution tape. Over the years I have pointed numerous people to this distribution when they asked about a make that worked with RCS. There were two problems with this: It is 4.1 make; It couldn't be distributed generally because all of make was reformatted and that meant that diffs wouldn't be of any use. When I faced the problem at Elxsi of not being able to use make in conjunction with RCS files not checked out, I went to the 84.1 tape and got Charles' work. Since I wanted to use 4.3 make (with the Elxsi extension for include), I couldn't just take the make from that tape. I decided that rather than put the 4.3 make into Charles' make, I'd put Charles' work into 4.3 make. I preserved the obnoxious formatting of 4.3 make and now offer those context diffs for others to use. The attached code solves this problem at Elxsi. Gary.. {ucbvax!sun,uunet,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww --------- cut --------- snip --------- :.,$w diff ------------- Index: Makefile *** /tmp/,RCSt1005798 Fri Aug 14 13:41:13 1987 --- Makefile Fri Aug 14 13:39:05 1987 *************** *** 1,6 **** ! # $Header: Makefile,v 1.2 87/08/07 14:05:43 gww Exp $ ENIX BSD # # $Log: Makefile,v $ # Revision 1.2 87/08/07 14:05:43 gww # Add include Files feature. # --- 1,9 ---- ! # $Header: Makefile,v 1.3 87/08/14 13:38:54 gww Exp $ ENIX BSD # # $Log: Makefile,v $ + # Revision 1.3 87/08/14 13:38:54 gww + # Add RCS and RCSROOT support. + # # Revision 1.2 87/08/07 14:05:43 gww # Add include Files feature. # *************** *** 15,21 **** OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o LIBES= LINT= lint -ps ! DFLAGS= -DINCLUDES CFLAGS= -O -DASCARCH ${DFLAGS} -I. -I/usr/src/bin/make all: make --- 18,24 ---- OBJECTS=ident.o main.o doname.o misc.o files.o dosys.o gram.o LIBES= LINT= lint -ps ! DFLAGS= -DINCLUDES -DRCS -DRCSROOT CFLAGS= -O -DASCARCH ${DFLAGS} -I. -I/usr/src/bin/make all: make Index: defs *** /tmp/,RCSt1005809 Fri Aug 14 13:41:31 1987 --- defs Fri Aug 14 13:39:09 1987 *************** *** 1,6 **** ! /* $Header: defs,v 1.2 87/08/07 14:05:58 gww Exp $ ENIX BSD * * $Log: defs,v $ * Revision 1.2 87/08/07 14:05:58 gww * Add include Files feature. * --- 1,9 ---- ! /* $Header: defs,v 1.3 87/08/14 13:39:07 gww Exp $ ENIX BSD * * $Log: defs,v $ + * Revision 1.3 87/08/14 13:39:07 gww + * Add RCS and RCSROOT support. + * * Revision 1.2 87/08/07 14:05:58 gww * Add include Files feature. * *************** *** 69,74 **** --- 72,91 ---- extern char *prompt; extern int nopdir; extern char junkname[ ]; + #ifdef RCS + #define RCS_SUF ",v" /* suffix of RCS files */ + extern int coflag; /* auto-checkout flag */ + extern int rmflag; /* auto-remove flag */ + extern struct shblock *co_cmd; /* auto-checkout shell command */ + extern char RCSdir[BUFSIZ]; /* name of RCS dir */ + extern char *RCSsuf; /* suffix of RCS files */ + extern int dotRCS; /* true if ./RCS exists */ + #ifdef RCSROOT + extern int rootRCS; /* true if RCSROOT exists */ + #endif RCSROOT + extern int sighvalue; /* true if SIGHUP ignored */ + extern int sigtvalue; /* true if SIGTERM ignored */ + #endif RCS *************** *** 80,85 **** --- 97,105 ---- struct lineblock *linep; int done:3; int septype:3; + #ifdef RCS + char *RCSnamep; /* name of RCS file, if needed */ + #endif RCS TIMETYPE modtime; }; *************** *** 138,143 **** --- 158,167 ---- char *datap; }; + #ifdef RCS + extern struct chain *rmchain; + #endif RCS + char *copys(), *concat(), *subst(); int *ckalloc(); struct nameblock *srchname(), *makename(); *************** *** 155,157 **** --- 179,185 ---- extern empty_stack(); extern FILE *pop(); #endif INCLUDES + #ifdef RCS + TIMETYPE getrcs(); + char *ncat(); + #endif RCS Index: doname.c *** /tmp/,RCSt1005815 Fri Aug 14 13:42:02 1987 --- doname.c Fri Aug 14 13:39:13 1987 *************** *** 1,10 **** /* * $Log: doname.c,v $ * Revision 1.1 86/12/11 12:53:12 gww * Initial revision * */ ! static char *ERcsId = "$Header: doname.c,v 1.1 86/12/11 12:53:12 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)doname.c 4.8 (Berkeley) 85/09/18"; #include "defs" #include <strings.h> --- 1,13 ---- /* * $Log: doname.c,v $ + * Revision 1.2 87/08/14 13:39:10 gww + * Add RCS and RCSROOT support. + * * Revision 1.1 86/12/11 12:53:12 gww * Initial revision * */ ! static char *ERcsId = "$Header: doname.c,v 1.2 87/08/14 13:39:10 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)doname.c 4.8 (Berkeley) 85/09/18"; #include "defs" #include <strings.h> *************** *** 20,30 **** --- 23,43 ---- */ extern char *sys_siglist[]; + #ifdef RCS + extern char *ctime(); + #endif RCS + #ifndef RCS doname(p, reclevel, tval) + #else + doname(p, reclevel, tval, ochain) + #endif !RCS register struct nameblock *p; int reclevel; TIMETYPE *tval; + #ifdef RCS + struct chain **ochain; + #endif RCS { int errstat; int okdel1; *************** *** 40,45 **** --- 53,62 ---- char *pnamep, *p1namep, *cp; char *mkqlist(); struct chain *qchain, *appendq(); + #ifdef RCS + struct chain *cochain; + int setimpl; /* set implicit vars */ + #endif RCS if(p == 0) { *************** *** 55,60 **** --- 72,86 ---- if(p->done > 0) { + #ifdef RCS + /* + * if we want to check-out RCS files, and we have previously + * determined that we can, then append it to the previous + * level's cochain. + */ + if (p->RCSnamep) + *ochain = appendq(*ochain, p->namep); + #endif RCS *tval = p->modtime; return(p->done == 3); } *************** *** 63,69 **** --- 89,100 ---- tdep = 0; implcom = 0; explcom = 0; + #ifndef RCS ptime = exists(p); + #else + cochain = NULL; + ptime = exists(p, ochain); + #endif RCS ptime1 = 0; didwork = NO; p->done = 1; /* avoid infinite loops */ *************** *** 86,94 **** --- 117,131 ---- td = 0; for(q = lp->depp ; q ; q = q->nxtdepblock) { + #ifndef RCS errstat += doname(q->depname, reclevel+1, &td1); if(dbgflag) printf("TIME(%s)=%ld\n", q->depname->namep, td1); + #else + errstat += doname(q->depname, reclevel+1, &td1, &cochain); + if(dbgflag) + printf("TIME(%s)=%s", q->depname->namep, ctime(&td1)+4); + #endif !RCS if(td1 > td) td = td1; if(ptime < td1) qchain = appendq(qchain, q->depname->namep); *************** *** 104,111 **** --- 141,155 ---- setvar("?", mkqlist(qchain) ); qchain = NULL; if( !questflag ) + #ifdef RCS + if (cochain) + co(cochain); + #endif RCS errstat += docom(lp->shp); setvar("@", (char *) NULL); + #ifdef RCS + cochain = NULL; + #endif RCS okdel = okdel1; ptime1 = prestime(); didwork = YES; *************** *** 127,132 **** --- 171,179 ---- /* Look for implicit dependents, using suffix rules */ + #ifdef RCS + setimpl = 0; + #endif RCS for(lp = sufflist ; lp ; lp = lp->nxtlineblock) for(suffp = lp->depp ; suffp ; suffp = suffp->nxtdepblock) { *************** *** 134,140 **** --- 181,193 ---- if(suffix(p->namep , pnamep , prefix)) { + #ifndef RCS srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL); + #else + srchdir( concat(prefix,"*",temp) , NO, (struct depblock *) NULL, + YES); + srchRCS(temp); + #endif !RCS for(lp1 = sufflist ; lp1 ; lp1 = lp1->nxtlineblock) for(suffp1=lp1->depp ; suffp1 ; suffp1 = suffp1->nxtdepblock) { *************** *** 142,155 **** --- 195,222 ---- if( (p1=srchname(concat(p1namep, pnamep ,concsuff))) && (p2=srchname(concat(prefix, p1namep ,sourcename))) ) { + #ifndef RCS errstat += doname(p2, reclevel+1, &td); + #else + if (dbgflag) + printf("Found implicit match\n"); + setimpl++; + errstat += doname(p2, reclevel+1, &td, + &cochain); + #endif !RCS if(ptime < td) qchain = appendq(qchain, p2->namep); + #ifndef RCS if(dbgflag) printf("TIME(%s)=%ld\n", p2->namep, td); + #else + if(dbgflag) printf("TIME(%s)=%s", p2->namep, ctime(&td)+4); + #endif !RCS if(td > tdep) tdep = td; + #ifndef RCS setvar("*", prefix); if (p2->alias) setvar("<", copys(p2->alias)); else setvar("<", copys(p2->namep)); + #endif !RCS for(lp2=p1->linep ; lp2 ; lp2 = lp2->nxtlineblock) if(implcom = lp2->shp) break; goto endloop; *************** *** 164,173 **** --- 231,264 ---- endloop: + #ifdef RCS + if (dbgflag) { + printf("CO(%s): %s\n", p->namep, mkqlist(cochain)); + fflush(stdout); + } + if (p->RCSnamep && (explcom || implcom)) { + if (keepgoing) { + errstat++; + printf("%s has both an RCS file and rules\n", p->namep); + } else + fatal1("%s has both an RCS file and rules", p->namep); + } + #endif RCS if(errstat==0 && (ptime<tdep || (ptime==0 && tdep==0) ) ) { ptime = (tdep>0 ? tdep : prestime() ); + #ifdef RCS + if (cochain) + co(cochain); + if (setimpl) { + setvar("*", prefix); + if (p2->alias) + setvar("<", copys(p2->alias)); + else + setvar("<", copys(p2->namep)); + } + #endif RCS setvar("@", p->namep); setvar("?", mkqlist(qchain) ); if(explcom) *************** *** 195,201 **** --- 286,296 ---- fatal1(" Don't know how to make %s", p->namep); setvar("@", (char *) NULL); + #ifndef RCS if(noexflag || (ptime = exists(p)) == 0) + #else + if(noexflag || (ptime = exists(p, (struct chain **)NULL)) == 0) + #endif !RCS ptime = prestime(); } *************** *** 206,217 **** --- 301,322 ---- printf("`%s' is up to date.\n", p->namep); if(questflag && reclevel==0) + #ifndef RCS exit(ndocoms>0 ? -1 : 0); + #else + quit(ndocoms>0 ? -1 : 0); + #endif !RCS p->done = (errstat ? 3 : 2); if(ptime1 > ptime) ptime = ptime1; p->modtime = ptime; *tval = ptime; + #ifdef RCS + if (dbgflag) { + printf("%s: errstat = %d\n", p->namep, errstat); + fflush(stdout); + } + #endif RCS return(errstat); } *************** *** 320,326 **** --- 425,435 ---- case '*': case '?': case '[': + #ifndef RCS if( p = srchdir(s1 , YES, q->nxtdepblock) ) + #else + if( p = srchdir(s1 , YES, q->nxtdepblock, YES) ) + #endif !RCS { q->nxtdepblock = p; q->depname = 0; Index: files.c *** /tmp/,RCSt1005820 Fri Aug 14 13:42:21 1987 --- files.c Fri Aug 14 13:39:20 1987 *************** *** 1,5 **** --- 1,8 ---- /* * $Log: files.c,v $ + * Revision 1.4 87/08/14 13:39:14 gww + * Add RCS and RCSROOT support. + * * Revision 1.3 86/12/12 17:27:34 gww * Don't dereference null pointer when VPATH is not defined. * *************** *** 11,17 **** * Initial revision * */ ! static char *ERcsId = "$Header: files.c,v 1.3 86/12/12 17:27:34 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)files.c 4.12 (Berkeley) 86/01/09"; #include <fcntl.h> --- 14,20 ---- * Initial revision * */ ! static char *ERcsId = "$Header: files.c,v 1.4 87/08/14 13:39:14 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)files.c 4.12 (Berkeley) 86/01/09"; #include <fcntl.h> *************** *** 27,32 **** --- 30,41 ---- #else ".SUFFIXES : .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p", #endif + #ifdef RCS + "CO=co", + "COFLAGS=-q", + "RM=rm", + "RMFLAGS=-f", + #endif RCS "YACC=yacc", "YACCR=yacc -r", "YACCE=yacc -e", *************** *** 34,40 **** "LEX=lex", "LFLAGS=", "CC=cc", ! #if defined(vax) || defined(sun) "AS=as", #else "AS=as -", --- 43,49 ---- "LEX=lex", "LFLAGS=", "CC=cc", ! #if defined(vax) || defined(sun) || defined(elxsi) "AS=as", #else "AS=as -", *************** *** 55,60 **** --- 64,77 ---- "CMFLAGS=", #endif + #ifdef RCS + ".CO :", + "\t$(CO) $(COFLAGS) $@", + + ".CLEANUP :", + "\t$(RM) $(RMFLAGS) $?", + #endif RCS + ".c.o :", "\t$(CC) $(CFLAGS) -c $<", *************** *** 152,159 **** --- 169,183 ---- TIMETYPE + #ifndef RCS exists(pname) + #else + exists(pname, ch) + #endif !RCS struct nameblock *pname; + #ifdef RCS + struct chain **ch; + #endif RCS { struct stat buf; register char *s, *filename; *************** *** 176,182 **** --- 200,216 ---- pname->alias = copys(s); if(stat(pname->alias, &buf) == 0) return(buf.st_mtime); + #ifdef RCS + if (coflag && ch) + return(getrcs(pname, pname->alias, ch)); + else + return(0); + #endif RCS } + #ifdef RCS + if (coflag && ch) + return(getrcs(pname, filename, ch)); + #endif RCS return(0); } else return(buf.st_mtime); *************** *** 197,206 **** --- 231,247 ---- + #ifndef RCS struct depblock *srchdir(pat, mkchain, nextdbl) + #else + struct depblock *srchdir(pat, mkchain, nextdbl, die) + #endif !RCS register char *pat; /* pattern to be matched in directory */ int mkchain; /* nonzero if results to be remembered */ struct depblock *nextdbl; /* final value for chain */ + #ifdef RCS + int die; /* fatal error if we can't open dir */ + #endif RCS { DIR *dirf; register int i; *************** *** 214,219 **** --- 255,263 ---- struct varblock *cp, *varptr(); char *path, pth[BUFSIZ], *strcpy(); struct direct *dptr; + #ifdef RCS + char temp2[BUFSIZ], *RCSpref; + #endif RCS thisdbl = 0; *************** *** 259,264 **** --- 303,317 ---- *path++ = '\0'; break; } + #ifdef RCS + RCSpref = NULL; + if (coflag && !mkchain) { + if (suffix(dirname, RCSdir, temp2)) + RCSpref = temp2; + else + RCSpref = dirpref; + } + #endif RCS dirf = NULL; cldir = NO; *************** *** 277,283 **** dirf = opendir(dirname); if(nopdir >= MAXDIR) cldir = YES; ! else { ++nopdir; od = ALLOC(dirhdr); od->nxtopendir = firstod; --- 330,336 ---- dirf = opendir(dirname); if(nopdir >= MAXDIR) cldir = YES; ! else if(dirf != NULL) { ++nopdir; od = ALLOC(dirhdr); od->nxtopendir = firstod; *************** *** 290,298 **** --- 343,360 ---- if(dirf == NULL) { + #ifdef RCS + if (die) { + #endif RCS fprintf(stderr, "Directory %s: ", dirname); fatal("Cannot open"); } + #ifdef RCS + if (endir) + *endir = '/'; + return(NULL); + } + #endif RCS else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf)) { *************** *** 312,317 **** --- 374,396 ---- thisdbl->depname = q; nextdbl = thisdbl; } + #ifdef RCS + /* + * if RCSpref is non-null, it is the dirpref + * without the "RCS/". This, along with RCS_SUF + * is stripped so implicit rules can find the + * corresponding files + */ + if (!suffix(nbuf, RCSsuf, nbuf)) + continue; + if (RCSpref) + p1=ncat(fullname, RCSpref, -1); + else + p1 = fullname; + ncat(p1, nbuf, -1); + if (srchname(fullname) == NULL) + makename(copys(fullname)); + #endif RCS } } *************** *** 666,668 **** --- 745,905 ---- } *d = '\0'; } + #ifdef RCS + + extern char *rindex(); + extern struct chain *appendq(); + + /* + * Try to find an RCS file corresponding to 'filename', and return + * the modified time of the RCS file. + * If ch is non-null, then append it on the chain for later check-out + */ + TIMETYPE + getrcs(p, filename, ch) + struct nameblock *p; + register char *filename; + struct chain **ch; + { + struct stat sbuf; + char temp[BUFSIZ]; + register char *tail; + register char *s; + int headlen; + + if ((tail = rindex(filename, '/')) == NULL) { + headlen = 0; + tail = filename; + } else + headlen = ++tail - filename; + s = ncat(temp, filename, headlen); + s = ncat(s, RCSdir, -1); + *s++ = '/'; + s = ncat(s, tail, -1); + ncat(s, RCSsuf, -1); + if (stat(temp, &sbuf) < 0) { + concat(filename, RCSsuf, temp); + if (stat(temp, &sbuf) < 0) + return(0); + } + p->RCSnamep = copys(temp); + if (ch) + *ch = appendq(*ch, filename); + return(sbuf.st_mtime); + } + + /* + * Try to check-out the files specified in ch, if they do not + * already exist. If rmflag is true, mark successful attempts + * for automatic deletion. + * Try to make the modified time of the file the same as that of the + * RCS file. + */ + co(ch) + register struct chain *ch; + { + register struct nameblock *p; + register char *file; + char *RCSfile; + struct stat sbuf; + int i; + time_t tm[2]; + + for ( ; ch; ch = ch->nextp) { + if ((file=ch->datap) == NULL || (p=srchname(file)) == NULL) + continue; + if (stat(file, &sbuf) == 0) + continue; /* don't do it again */ + RCSfile = p->RCSnamep; + p->RCSnamep = NULL; + setvar("@", file); + setvar("<", RCSfile); + i = docom(co_cmd); + setvar("@", (char *) NULL); /* so it doesn't get deleted */ + if (i) + continue; /* docom() failed */ + /* + * since we succeeded, mark it for later deletion + */ + if (rmflag && !isprecious(file)) + rmchain = appendq(rmchain, file); + /* + * try to set modified time on file + */ + if (stat(RCSfile, &sbuf) == 0) { + tm[0] = time((time_t *) NULL); + tm[1] = sbuf.st_mtime; + utime(file, tm); + } + } + } + + /* + * delete the files listed in rmchain + */ + + rm () + { + register struct chain *q; + struct nameblock *p; + register struct lineblock *lp; + register struct shblock *sp; + static int once = 0; + + if (once || (q = rmchain) == NULL) /* only if we should */ + return; + once = 1; + if ((p = srchname(".CLEANUP")) == NULL) + return; + sp = NULL; + for (lp = p->linep; lp; lp = lp->nxtlineblock) + if (sp = lp->shp) + break; + if (sp == NULL) /* no or NULL .CLEANUP ? */ + return; + setvar("?", mkqlist(q)); + docom(sp); + } + + /* + * Do the srchdir for RCS files. For a pattern a/b, it searches + * a/RCS/b, without generating an error if it doesn't exist + */ + srchRCS(pat) + register char *pat; + { + char temp[BUFSIZ]; + int headlen; + register char *tail, *s; + + if ((tail = rindex(pat, '/')) == NULL) { + /* quick search for '.' */ + if (dotRCS) { + s = ncat(temp, RCSdir, -1); + *s++ = '/'; + ncat(s, pat, -1); + srchdir(temp, NO, (struct depblock *) NULL, NO); + #ifdef RCSROOT + } else if (rootRCS) { + s = ncat(temp, RCSdir, -1); + ncat(s, pat, -1); + srchdir(temp, NO, (struct depblock *) NULL, NO); + #endif RCSROOT + } + return; + #ifdef RCSROOT + } else if (rootRCS) { + s = ncat(temp, RCSdir, -1); + ncat(s, pat, -1); + #endif RCSROOT + } else { + tail++; + headlen = tail - pat; + s = ncat(temp, pat, headlen); + s = ncat(s, RCSdir, -1); + *s++ = '/'; + ncat(s, tail, -1); + } + srchdir(temp, NO, (struct depblock *) NULL, NO); + } + #endif RCS Index: main.c *** /tmp/,RCSt1005825 Fri Aug 14 13:42:36 1987 --- main.c Fri Aug 14 13:39:25 1987 *************** *** 1,5 **** --- 1,8 ---- /* * $Log: main.c,v $ + * Revision 1.3 87/08/14 13:39:21 gww + * Add RCS and RCSROOT support. + * * Revision 1.2 87/08/07 14:06:06 gww * Add include Files feature. * *************** *** 7,30 **** * Initial revision * */ ! static char *ERcsId = "$Header: main.c,v 1.2 87/08/07 14:06:06 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)main.c 4.8 (Berkeley) 86/01/09"; # include "defs" /* command make to update programs. ! Flags: 'd' print out debugging comments 'p' print out a version of the input graph 's' silent mode--don't print out commands 'f' the next argument is the name of the description file; "makefile" is the default 'i' ignore error codes from the shell 'S' stop after any command fails (normally do parallel work) 'n' don't issue, just print, commands 't' touch (update time of) files but don't issue command 'q' don't do anything, but check if object is up to date; returns exit code 0 if up to date, -1 if not */ struct nameblock *mainname = NULL; struct nameblock *firstname = NULL; struct lineblock *sufflist = NULL; --- 10,45 ---- * Initial revision * */ ! static char *ERcsId = "$Header: main.c,v 1.3 87/08/14 13:39:21 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)main.c 4.8 (Berkeley) 86/01/09"; # include "defs" /* command make to update programs. ! Flags: ! 'c' don't check out RCS files ! 'C' check out RCS files (default) ! 'd' print out debugging comments 'p' print out a version of the input graph 's' silent mode--don't print out commands 'f' the next argument is the name of the description file; "makefile" is the default 'i' ignore error codes from the shell + 'k' don't stop after any command fails (default) 'S' stop after any command fails (normally do parallel work) 'n' don't issue, just print, commands + 'r' don't use default rules 't' touch (update time of) files but don't issue command + 'u' don't unlink RCS working files + 'U' unlink RCS working files 'q' don't do anything, but check if object is up to date; returns exit code 0 if up to date, -1 if not */ + /* + * This version is based on the modifications made to the 4.1 make + * made by Charles LaBrec, Purdue University Physics Dept. + */ + struct nameblock *mainname = NULL; struct nameblock *firstname = NULL; struct lineblock *sufflist = NULL; *************** *** 32,37 **** --- 47,71 ---- struct pattern *firstpat = NULL; struct dirhdr *firstod = NULL; + #ifdef RCS + struct shblock *co_cmd = NULL; + struct chain *rmchain = NULL; + + #include <sys/stat.h> + + int rmflag = YES; + int coflag = YES; + char RCSdir[BUFSIZ] = "RCS"; + char *RCSsuf = RCS_SUF; + int dotRCS = NO; + #ifdef RCSROOT + int rootRCS = NO; + #endif RCSROOT + int sighvalue = 0; + int sigtvalue = 0; + extern char *getenv(), *getwd(); + #endif RCS + #include <signal.h> int sigivalue = 0; int sigqvalue = 0; *************** *** 73,78 **** --- 107,117 ---- int intrupt(); #endif char *op = options + 1; + #ifdef RCS + struct lineblock *lp; + struct stat sbuf; + struct chain *ch; + #endif RCS #ifdef METERFILE *************** *** 102,107 **** --- 141,156 ---- *op++ = c; switch (c) { + #ifdef RCS + case 'c': + coflag = NO; + break; + + case 'C': + coflag = YES; + break; + #endif RCS + case 'd': dbgflag = YES; break; *************** *** 142,147 **** --- 191,206 ---- questflag = YES; break; + #ifdef RCS + case 'u': + rmflag = NO; + break; + + case 'U': + rmflag = YES; + break; + #endif RCS + case 'f': op--; /* don't pass this one */ if(i >= argc-1) *************** *** 175,180 **** --- 234,250 ---- if(prtrflag) printdesc(NO); + #ifdef RCS + if (p = srchname(".CO")) { + for (lp = p->linep; lp; lp = lp->nxtlineblock) + if ((co_cmd = lp->shp) != NULL) + break; + if (co_cmd == NULL) + coflag = NO; + } else + coflag = NO; + #endif RCS + if( srchname(".IGNORE") ) ++ignerr; if( srchname(".SILENT") ) silflag = 1; if(p=srchname(".SUFFIXES")) sufflist = p->linep; *************** *** 183,191 **** --- 253,298 ---- #ifdef unix sigivalue = (int) signal(SIGINT, SIG_IGN) & 01; sigqvalue = (int) signal(SIGQUIT, SIG_IGN) & 01; + #ifdef RCS + sighvalue = (int) signal(SIGHUP, SIG_IGN) & 01; + sigtvalue = (int) signal(SIGTERM, SIG_IGN) & 01; + #endif RCS enbint(intrupt); #endif + #ifdef RCS + if (stat(RCSdir, &sbuf) == 0 && (sbuf.st_mode & S_IFMT) == S_IFDIR) + dotRCS = YES; /* fast check for ./RCS */ + #ifdef RCSROOT + /* NOTE: dotRCS == YES implies rootRCS == NO */ + else { + char pathname[BUFSIZ]; + char *rcsroot; + + if (rcsroot = getenv("RCSROOT")) { + strcpy(RCSdir, rcsroot); + strncat(RCSdir, getwd(pathname), BUFSIZ); + if ((stat(RCSdir, &sbuf) == 0) && + ((sbuf.st_mode & S_IFMT) == S_IFDIR)) { + strncat(RCSdir, "/", BUFSIZ); + rootRCS = YES; + } + } + if (!rootRCS) { + strcpy(RCSdir, "/RCS"); + strncat(RCSdir, getwd(pathname), BUFSIZ); + if ((stat(RCSdir, &sbuf) == 0) && + ((sbuf.st_mode & S_IFMT) == S_IFDIR)) { + strncat(RCSdir, "/", BUFSIZ); + rootRCS = YES; + } + else + RCSdir[0] = '\0'; + } + } + #endif RCSROOT + #endif RCS + nfargs = 0; for(i=1; i<argc; ++i) *************** *** 196,202 **** --- 303,314 ---- p = makename(s); } ++nfargs; + #ifndef RCS doname(p, 0, &tjunk); + #else + ch = NULL; + doname(p, 0, &tjunk, &ch); + #endif !RCS if(dbgflag) printdesc(YES); } *************** *** 209,222 **** --- 321,345 ---- if(mainname == 0) fatal("No arguments or description file"); else { + #ifndef RCS doname(mainname, 0, &tjunk); + #else + ch = NULL; + doname(mainname, 0, &tjunk, &ch); + #endif !RCS if(dbgflag) printdesc(YES); } + #ifndef RCS exit(0); + #else + quit(0); + #endif !RCS } + #ifndef RCS #include <sys/stat.h> + #endif !RCS #ifdef unix intrupt() *************** *** 238,244 **** --- 361,371 ---- if(junkname[0]) unlink(junkname); fprintf(stderr, "\n"); + #ifndef RCS exit(2); + #else + quit(2); + #endif !RCS } *************** *** 268,273 **** --- 395,406 ---- signal(SIGINT,k); if(sigqvalue == 0) signal(SIGQUIT,k); + #ifdef RCS + if(sighvalue == 0) + signal(SIGHUP,k); + if(sigtvalue == 0) + signal(SIGTERM,k); + #endif RCS } #endif Index: misc.c *** /tmp/,RCSt1005830 Fri Aug 14 13:42:51 1987 --- misc.c Fri Aug 14 13:39:54 1987 *************** *** 1,5 **** --- 1,8 ---- /* * $Log: misc.c,v $ + * Revision 1.3 87/08/14 13:39:26 gww + * Add RCS and RCSROOT support. + * * Revision 1.2 87/08/07 14:06:10 gww * Add include Files feature. * *************** *** 7,13 **** * Initial revision * */ ! static char *ERcsId = "$Header: misc.c,v 1.2 87/08/07 14:06:10 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)misc.c 4.3 (Berkeley) 85/08/30"; #include "defs" --- 10,16 ---- * Initial revision * */ ! static char *ERcsId = "$Header: misc.c,v 1.3 87/08/14 13:39:26 gww Exp $ ENIX BSD"; static char *sccsid = "@(#)misc.c 4.3 (Berkeley) 85/08/30"; #include "defs" *************** *** 274,283 **** --- 277,294 ---- if(s) fprintf(stderr, "Make: %s. Stop.\n", s); else fprintf(stderr, "\nStop.\n"); #ifdef unix + #ifndef RCS exit(1); + #else + quit(1); + #endif !RCS #endif #ifdef gcos + #ifndef RCS exit(0); + #else + quit(0); + #endif !RCS #endif } *************** *** 389,391 **** --- 400,439 ---- return( (top == -1) ? 1 : 0 ); } #endif INCLUDES + + #ifdef RCS + quit(val) + int val; + { + if (rmflag) { /* clean up co'ed files */ + touchflag = 0; /* don't try to touch anything */ + rm(); + } + exit(val); + } + + /* + * ncat copies n chars of string b at a, returning a pointer to the + * null terminating a. This way, it can be used to daisy-chain. + * If n < 0, all chars of b will be copied + */ + char * + ncat(a, b, n) + register char *a, *b; + register int n; + { + if (n < 0) { + while(*a++ = *b++) + ; + return(--a); + } else { + if (n != 0) + do { + if ((*a++ = *b++) == '\0') + return(--a); + } while (--n); + *a = '\0'; + return(a); + } + } + #endif RCS Index: /usr/man/man1/make.1 *** /tmp/,RCSt1005207 Thu Mar 10 15:48:37 1988 --- make.1e Thu Mar 10 15:47:58 1988 *************** *** 1,6 **** ! .\" $Header: make.1e,v 1.2 87/08/07 15:01:04 gww Exp $ ENIX BSD .\" .\" $Log: make.1e,v $ .\" Revision 1.2 87/08/07 15:01:04 gww .\" Add include support. .\" --- 1,9 ---- ! .\" $Header: make.1e,v 1.3 88/03/10 15:47:50 gww Exp $ ENIX BSD .\" .\" $Log: make.1e,v $ + .\" Revision 1.3 88/03/10 15:47:50 gww + .\" Add RCS support. + .\" .\" Revision 1.2 87/08/07 15:01:04 gww .\" Add include support. .\" *************** *** 149,155 **** is inferred. The default list is .IP ! \&.SUFFIXES: .out .o .c .e .r .f .y .l .s .p .PP The rule to create a file with suffix .I s2 --- 152,158 ---- is inferred. The default list is .IP ! \&.SUFFIXES: .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p .PP The rule to create a file with suffix .I s2 *************** *** 216,221 **** --- 219,226 ---- .PP Command lines are executed one at a time, each by its own shell. + The default shell is + .IR sh (1). A line is printed when it is executed unless the special target `.SILENT' is in *************** *** 249,256 **** --- 254,384 ---- is interpreted. Includes may be nested up to 20 deep. .PP + .I Make + functions in conjunction with RCS (Revision Control System). + Unless the \-c option is specified, + if the search for a file (called the working file) fails, + .I make + looks for a corresponding RCS file. + For example, if a file xxx does not exist, ./RCS/xxx,v, + then enviroment variable RCSROOT/\fIcurrent-directory\fP/xxx,v, + then /RCS/\fIcurrent-directory\fP/xxx,v, + and finally ./xxx,v are searched for in that order. + (When subdirectories are specified, e.g., xxx/yyy, xxx/RCS/yyy,v, + RCSROOT/\fIcurrent-directory\fP/xxx/yyy,v, + /RCS/\fIcurrent-directory\fP/xxx/yyy,v, + and xxx/yyy,v are tried.) + If the search is successful, the `last modified' time of the RCS file + is considered to be the modified time of the working file, and + .I make + remembers that the working file must be checked out. + When the time comes to actually make a target, each of these dependents + is retrieved from RCS using the target `.CO'. + The default rule is: + .RS + .HP + .PD 0 + .nf + \&.CO: + $(CO) $(COFLAGS) $@ + .fi + .RE + .PD + .PP + where by default + .PP + .RS + .nf + CO = co + COFLAGS = -q + .fi + .RE + .PP + Also, the special macro `$@' is set to the name of the working + file and `$<' to the name of the RCS file (in the spirit that + this is an implicit command). + Note, however, that `$?' and `$*' have no meaning here. + Furthermore, after the check-out is complete, + .I make + will try to set the modified time of `$@' to that of the RCS file + in accordance with its earlier assumption. + Since this is the time that has been used throughout execution, + there is no way to avoid this action. + Also, unless \-u was specified or the working file is mentioned as + a dependent of `.PRECIOUS', it will be removed on exit. + If the `.CO' target is missing or has no commands associated with it, + then the effect is the same as if \-c had been specified. + .PP + When + .I make + terminates, if any files that were automatically checked out are marked + for deletion, + it will run the special target `.CLEANUP'. + The default rule is: + .nf + .RS + .HP + .PD 0 + \&.CLEANUP: + $(RM) $(RMFLAGS) $? + .PD + .RE + .fi + .PP + where: + .PP + .RS + .nf + RM = rm + RMFLAGS = -f + .RE + .fi + .PP + and the macro `$?' is set to the names of the files that + were checked out previously and are not dependents of the + target `.PRECIOUS'. + If `.CLEANUP' is missing, has no commands associated with it, or `$?' + is blank, the effect is the same as if \-u had been specified. + .PP + The exact form of the `.CO' target is probably open to debate. + Since + .IR co (1) + strips subdirectories from working file names, but not RCS file names, + the `correct' form of the `.CO' should probably be: + .PP + .RS + $(CO) $(COFLAGS) -p $< > $@ + .RE + .PP + However, in executing a command, + .I make + looks at it for the special shell characters: + .PP + .RS + =|^();&<>*?[]:$`'"\\\\n + .RE + .PP + If none are detected, the command is executed directly, without + a shell. + Thus, the latter form of the `.CO' target is less efficient, since + a shell must be used to do the redirection (`>'). + Furthermore, the former description fails only when RCS files in + subdirectories other than `.' or `./RCS' must be checked out. + For this reason, the `less correct' rule has been chosen. + .PP Other options: .TP + .B \-c + If a file does not exist, do not try to find a corresponding + RCS file and check it out. + .TP + .B \-C + Try to get the file from RCS (this is the default). + .TP + .B \-d + Print debugging information (relatively useless except for + trying to find out what went wrong). + .TP .B \-i Equivalent to the special entry `.IGNORE:'. .TP *************** *** 263,284 **** Trace and print, but do not execute the commands needed to update the targets. .TP ! .B \-t ! Touch, i.e. update the modified date of targets, without ! executing any commands. .TP .B \-r ! Equivalent to an initial special entry `.SUFFIXES:' ! with no list. .TP .B \-s Equivalent to the special entry `.SILENT:'. .SH FILES makefile, Makefile .br .SH "SEE ALSO" ! sh(1), touch(1), f77(1), pc(1) .br S. I. Feldman .I --- 391,429 ---- Trace and print, but do not execute the commands needed to update the targets. .TP ! .B \-p ! Print a version of the input graph. .TP + .B \-q + Don't do anything, but check if object is up to date. + Return exit status 0 if it is, -1 if it is not. + .TP .B \-r ! Do not use the default set of rules. ! .TP ! .B \-S ! The inverse of ! .BR \-k . .TP .B \-s Equivalent to the special entry `.SILENT:'. + .TP + .B \-t + Touch, i.e. update the modified date of targets, without + executing any commands. + .TP + .B \-u + Don't cleanup files that were automatically checked-out from RCS. + .TP + .B \-U + Cleanup files that were automatically checked-out from RCS, + unless they are listed in the `.PRECIOUS' target (default). .SH FILES makefile, Makefile .br .SH "SEE ALSO" ! co(1E), rcs(1E), sh(1), touch(1), utime(1) .br S. I. Feldman .I
mohamed@hscfvax.harvard.edu (Mohamed_el_Lozy) (03/16/88)
The two postings about make seem to have something missing. Applying the first patch will produce a program that fails to link, with do_include() missing. If -DINCLUDE is removed from the DFLAGS it will make properly. I very much suspect that do_include() should live in files.c, and there are no patches for that file. The second posting (which adds RCS compatibility) confirms that impression. There is a patch which takes files.c from 1.3 to 1.4. It takes, apart from the headers. Like after the first patch, compilation fails with do_include() missing, but works if you remove -DINCLUDE from DFLAGS. Since I do not care about the include capability, I am perfectly satisfied. Others may want it.
dls@s.cc.purdue.edu (David L Stevens) (03/16/88)
You should also be aware that these changes (in an earlier version, at least) disallow explicit rules for RCS files, as we use. This means that Makefiles that work with the standard make(1) will generate an error and exit. The problem is (or was, at least) with using an explicit rule of the form: ${SRC}: co $@ We do this (locally) for all of our Makefiles, rather than hack make(1). We evaluated Charlie's make(1) and discovered that it generated the error message: <blotto> has RCS file and rules. Thus, Makefiles from other places that have explicit RCS rules would require source changes and (worse) you cannot customize an RCS rule. I admit that I haven't tried the above on the posted diffs, but I discussed the problem with Charlie at the time (over a year ago) and there were some technical difficulties in making it do the "right" thing, which is to use explicit rules when they are there and only use the implicit rules when they aren't. I assume this incompatibility persists, but welcome someone else to give the definitive word. -- +-DLS (dls@s.cc.purdue.edu)
gww@beatnix.UUCP (Gary Winiger) (04/03/88)
In article <539@hscfvax.harvard.edu> mohamed@hscfvax.harvard.edu (Mohamed_el_Lozy) writes: >The two postings about make seem to have something missing. Applying >the first patch will produce a program that fails to link, with >do_include() missing. If -DINCLUDE is removed from the DFLAGS it will >make properly. I very much suspect that do_include() should live in >files.c, and there are no patches for that file. Sorry for the length of time it has taken me to reply, I'm only at Elxsi occassionally at present. I don't believe that the routine ``do_include'' was missing from the posting. ``do_include'' is in gram.y. Perhaps Mr. Mohamed_el_Lozy didn't either clean the make directory before building with -DINCLUDE defined, or didn't remove gram.c. Note that make's Makefile does not have very good dependences. Gary..