Subject: Review: make changes
To: None <tech-toolchain@netbsd.org>
From: Simon J. Gerraty <sjg@quick.com.au>
List: tech-toolchain
Date: 06/01/2001 01:12:54
Ok, below are diffs against NetBSD-current's make for the features
I've mentioned recently.  The changes are:

1. -dx does sh -x

Using -dx one can now get the shell run with -x in compat mode or a
"set -x" sent in job mode (result is not quite as neat due to extra
+'s resulting from the set - and set -v's)

2. PrintOnError

When make encounters an error. Instead of simply printing "\n\nStop.\n"
it prints that as well as info about .CURDIR.
It also prints the values of any variables listed in
${MAKE_PRINT_VAR_ON_ERROR}

Eg. 

$ cat /tmp/tmf
VAR=default
MAKE_PRINT_VAR_ON_ERROR=.OBJDIR .MAKE

all:
	@echo VAR=${VAR}

rec:
	${MAKE} -f ${MAKEFILE} all

oops:
	@echo oops!; false


$ make -dx -f /tmp/tmf oops
+ echo oops!
oops!
+ false
*** Error code 1

Stop.
make: stopped in /u3/NetBSD/current/src/usr.bin/make
.OBJDIR='/u3/NetBSD/current/src/usr.bin/make'
.MAKE='/var/obj/u3/NetBSD/current/src/usr.bin/make/make'
$

3. VAR_CMD added to MAKEFLAGS

Command line var assignments are now added to MAKEFLAGS so given
the makefile above, instead of:

$ make -f /tmp/tmf VAR=foo rec
make -f /tmp/tmf all
VAR=default
$

we get:

$ make -f /tmp/tmf VAR=foo rec
make -f /tmp/tmf all
VAR=foo
$

4. do not set MAKEFILE=.depend

Resetting MAKEFILE when we read .depend just loses any useful info
that ${MAKEFILE} might have provided.

5. .newline

I added a var called .newline so that one can include a newline in the
output of :@ loop expansions.  I used this for the original handling
of MAKE_PRINT_VAR_ON_ERROR.  Its not needed now, but I've had the same
need in the past and there seems no way to get a newline into a var
otherwise. 

6. set MAKE_VERSION if provided by the Makefile.

In bmake I set MAKE_VERSION to something like "bmake-3.1.6 %Y%m%d".
where the date is the build date.

I haven't heard anyone object to any of these changes.  I'd like to
commit these soon, so I can go ahead and merge netbsd's make back into
bmake - so I can kick 3.1.7 out the door :-)

Thanks
--sjg

Index: compat.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/compat.c,v
retrieving revision 1.33
diff -u -r1.33 compat.c
--- compat.c	2001/05/29 17:37:51	1.33
+++ compat.c	2001/06/01 07:46:20
@@ -257,7 +257,10 @@
 	 */
 	static char	*shargv[4] = { "/bin/sh" };
 
-	shargv[1] = (errCheck ? "-ec" : "-c");
+	if (DEBUG(SHELL))
+		shargv[1] = (errCheck ? "-exc" : "-xc");
+	else
+		shargv[1] = (errCheck ? "-ec" : "-c");
 	shargv[2] = cmd;
 	shargv[3] = (char *)NULL;
 	av = shargv;
@@ -479,7 +482,7 @@
 	} else if (keepgoing) {
 	    pgn->flags &= ~REMAKE;
 	} else {
-	    printf ("\n\nStop.\n");
+	    PrintOnError("\n\nStop.");
 	    exit (1);
 	}
     } else if (gn->made == ERROR) {
@@ -574,7 +577,7 @@
 	if (gn != NILGNODE) {
 	    Lst_ForEach(gn->commands, CompatRunCommand, (ClientData)gn);
             if (gn->made == ERROR) {
-                printf("\n\nStop.\n");
+                PrintOnError("\n\nStop.");
                 exit(1);
             }
 	}
Index: job.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/job.c,v
retrieving revision 1.48
diff -u -r1.48 job.c
--- job.c	2001/05/29 17:37:52	1.48
+++ job.c	2001/06/01 07:46:26
@@ -708,6 +708,12 @@
 	}
     }
 
+    if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 &&
+	(job->flags & JOB_TRACED) == 0) {
+	    DBPRINTF("set -%s\n", "x");
+	    job->flags |= JOB_TRACED;
+    }
+    
     if ((cp = Check_Cwd_Cmd(cmd)) != NULL) {
 	    DBPRINTF("cd %s; ", cp);
     }		    
@@ -1280,6 +1286,8 @@
 {
     int	    	  cpid;	    	/* ID of new child */
 
+    job->flags &= ~JOB_TRACED;
+
     if (DEBUG(JOB)) {
 	int 	  i;
 
@@ -2352,6 +2360,7 @@
 	    }
 	} else {
 	    job = (Job *) Lst_Datum(jnode);
+	    Job_CatchOutput();
 	    (void) Lst_Remove(jobs, jnode);
 	    nJobs -= 1;
 #ifdef REMOTE
Index: job.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/job.h,v
retrieving revision 1.14
diff -u -r1.14 job.h
--- job.h	2000/12/30 16:38:22	1.14
+++ job.h	2001/06/01 07:46:26
@@ -130,6 +130,8 @@
 #define JOB_CONTINUING	0x200	/* We are in the process of resuming this job.
 				 * Used to avoid infinite recursion between
 				 * JobFinish and JobRestart */
+#define JOB_TRACED	0x400	/* we've sent 'set -x' */
+
     union {
 	struct {
 	    int	  	op_inPipe;	/* Input side of pipe associated
Index: main.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/main.c,v
retrieving revision 1.66
diff -u -r1.66 main.c
--- main.c	2001/05/29 17:37:52	1.66
+++ main.c	2001/06/01 07:46:27
@@ -310,6 +310,9 @@
 				case 'v':
 					debug |= DEBUG_VAR;
 					break;
+				case 'x':
+					debug |= DEBUG_SHELL;
+					break;
 				default:
 					(void)fprintf(stderr,
 				"%s: illegal argument to d option -- %c\n",
@@ -389,9 +392,10 @@
 	 * on the end of the "create" list.
 	 */
 	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
-		if (Parse_IsVar(*argv))
+		if (Parse_IsVar(*argv)) {
+			Var_Append(MAKEFLAGS, *argv, VAR_GLOBAL);
 			Parse_DoVar(*argv, VAR_CMD);
-		else {
+		} else {
 			if (!**argv)
 				Punt("illegal (null) argument.");
 			if (**argv == '-') {
@@ -612,6 +616,10 @@
 	Var_Set(".CURDIR", curdir, VAR_GLOBAL);
 	Var_Set("MACHINE", machine, VAR_GLOBAL);
 	Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL);
+#ifdef MAKE_VERSION
+	Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
+#endif
+	Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */
 
 	/*
 	 * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
@@ -979,11 +987,14 @@
 	FILE *stream;
 	size_t len = MAXPATHLEN;
 	char *name, *path = emalloc(len);
+	int setMAKEFILE;
 
 	if (!strcmp(fname, "-")) {
 		Parse_File("(stdin)", stdin);
 		Var_Set("MAKEFILE", "", VAR_GLOBAL);
 	} else {
+		setMAKEFILE = strcmp(fname, ".depend");
+
 		/* if we've chdir'd, rebuild the path name */
 		if (curdir != objdir && *fname != '/') {
 			size_t plen = strlen(curdir) + strlen(fname) + 2;
@@ -1011,7 +1022,9 @@
 		 * placement of the setting here means it gets set to the last
 		 * makefile specified, as it is set by SysV make.
 		 */
-found:		Var_Set("MAKEFILE", fname, VAR_GLOBAL);
+found:
+		if (setMAKEFILE)
+			Var_Set("MAKEFILE", fname, VAR_GLOBAL);
 		Parse_File(fname, stream);
 		(void)fclose(stream);
 	}
@@ -1411,6 +1424,8 @@
 	(void)fprintf(stderr, "\n");
 	(void)fflush(stderr);
 
+	PrintOnError(NULL);
+
 	if (DEBUG(GRAPH2))
 		Targ_PrintGraph(2);
 	Trace_Log(MAKEERROR, 0);
@@ -1453,6 +1468,8 @@
 	(void)fprintf(stderr, "\n");
 	(void)fflush(stderr);
 
+	PrintOnError(NULL);
+
 	DieHorribly();
 }
 
@@ -1623,4 +1640,23 @@
 {
     printf("%lx ", (unsigned long) a);
     return b ? 0 : 0;
+}
+
+
+
+void
+PrintOnError(s)
+    char *s;
+{
+    char tmp[64];
+	
+    if (s)
+	    printf("%s", s);
+	
+    printf("\n%s: stopped in %s\n", progname, curdir);
+    strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
+	    sizeof(tmp) - 1);
+    s = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+    if (s && *s)
+	printf("%s", s);
 }
Index: make.1
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/make.1,v
retrieving revision 1.48
diff -u -r1.48 make.1
--- make.1	2001/04/04 09:39:07	1.48
+++ make.1	2001/06/01 07:46:28
@@ -136,6 +136,10 @@
 Print debugging information about target list maintenance.
 .It Ar v
 Print debugging information about variable assignment.
+.It Ar x
+Run shell commands with 
+.Fl x 
+so the actual commands are printed as they are executed. 
 .El
 .It Fl e
 Specify that environmental variables override macro assignments within
@@ -508,6 +512,19 @@
 for all programs which
 .Nm
 executes.
+.It Va MAKE_PRINT_VAR_ON_ERROR
+When 
+.Nm
+stops due to an error, it prints its name and the value of
+.Ql Va .CURDIR
+as well as the value of any variables named in 
+.Ql Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .newline
+This variable is simply assigned a newline character as its value.
+This allows expansions using the :@ modifier to put a newline between
+iterations of the loop rather than a space.  For example, the printing of
+.Ql Va MAKE_PRINT_VAR_ON_ERROR
+could be done as ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}.
 .El
 .Pp
 Variable expansion may be modified to select or modify each word of the
Index: make.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/make.h,v
retrieving revision 1.33
diff -u -r1.33 make.h
--- make.h	2001/01/14 05:34:06	1.33
+++ make.h	2001/06/01 07:46:29
@@ -385,6 +385,7 @@
 #define	DEBUG_TARG	0x0100
 #define	DEBUG_VAR	0x0200
 #define DEBUG_FOR	0x0400
+#define DEBUG_SHELL	0x0800
 
 #ifdef __STDC__
 #define CONCAT(a,b)	a##b
@@ -411,5 +412,6 @@
 Boolean Make_Run __P((Lst));
 char * Check_Cwd_Cmd __P((char *));
 void Check_Cwd __P((char **));
+void PrintOnError __P((char *));
 
 #endif /* _MAKE_H_ */
Index: parse.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/parse.c,v
retrieving revision 1.63
diff -u -r1.63 parse.c
--- parse.c	2001/02/23 21:11:38	1.63
+++ parse.c	2001/06/01 07:46:31
@@ -2716,6 +2716,7 @@
 	(void)fprintf(stderr,
 	    "%s: Fatal errors encountered -- cannot continue\n",
 	    progname);
+	PrintOnError(NULL);
 	exit (1);
     }
 }
Index: var.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/make/var.c,v
retrieving revision 1.59
diff -u -r1.59 var.c
--- var.c	2001/05/12 06:48:49	1.59
+++ var.c	2001/06/01 07:46:33
@@ -1243,15 +1243,16 @@
 {
     VarLoop_t	*loop = (VarLoop_t *) loopp;
     char *s;
+    int slen;
     
     Var_Set(loop->tvar, word, loop->ctxt);
     s = Var_Subst(NULL, loop->str, loop->ctxt, loop->err);
     if (s != NULL && *s != '\0') {
-	if (addSpace)
+	if (addSpace && *s != '\n')
 	    Buf_AddByte(buf, ' ');
-	Buf_AddBytes(buf, strlen(s), (Byte *)s);
+	Buf_AddBytes(buf, (slen = strlen(s)), (Byte *)s);
+	addSpace = (slen > 0 && s[slen - 1] != '\n');
 	free(s);
-	addSpace = TRUE;
     }
     return addSpace;
 }