Subject: make: tracking input
To: None <tech-toolchain@netbsd.org>
From: Simon Gerraty <sjg@juniper.net>
List: tech-toolchain
Date: 10/05/2007 10:46:08
This patch adds ${.MAKE.MAKEFILES} which records all the makefiles
read by make - very handy for capturing dependencies.

--sjg

Index: make.1
===================================================================
RCS file: /cvsroot/src/usr.bin/make/make.1,v
retrieving revision 1.133
diff -u -p -r1.133 make.1
--- make.1	5 Oct 2007 15:27:45 -0000	1.133
+++ make.1	5 Oct 2007 17:44:16 -0000
@@ -580,6 +580,14 @@ The preferred variable to use is the env
 because it is more compatible with other versions of
 .Nm
 and cannot be confused with the special target with the same name.
+.It Va .MAKE.EXPORTED
+The list of variables exported by
+.Nm .
+.It Va .MAKE.MAKEFILES
+The list of makefiles read by
+.Nm ,
+which is useful for tracking dependencies.
+Each makefile is recorded only once, regardless of the number of times read.
 .It Va .MAKE.PID
 The process-id of 
 .Nm .
Index: make.h
===================================================================
RCS file: /cvsroot/src/usr.bin/make/make.h,v
retrieving revision 1.69
diff -u -p -r1.69 make.h
--- make.h	5 Oct 2007 15:27:45 -0000	1.69
+++ make.h	5 Oct 2007 17:44:16 -0000
@@ -397,8 +397,9 @@ extern char	*progname;	/* The program na
 
 #define	MAKEFLAGS	".MAKEFLAGS"
 #define	MAKEOVERRIDES	".MAKEOVERRIDES"
-#define	MAKE_JOB_PREFIX	".MAKE.JOB.PREFIX"
-#define	MAKE_EXPORTED	".MAKE.EXPORTED"
+#define	MAKE_JOB_PREFIX	".MAKE.JOB.PREFIX" /* prefix to job target output */
+#define	MAKE_EXPORTED	".MAKE.EXPORTED" /* variables we export */
+#define	MAKE_MAKEFILES	".MAKE.MAKEFILES" /* all the makefiles we read */
 
 /*
  * debug control:
Index: parse.c
===================================================================
RCS file: /cvsroot/src/usr.bin/make/parse.c,v
retrieving revision 1.136
diff -u -p -r1.136 parse.c
--- parse.c	5 Oct 2007 15:27:45 -0000	1.136
+++ parse.c	5 Oct 2007 17:44:16 -0000
@@ -1915,6 +1915,48 @@ ParseSetParseFile(const char *filename)
     }
 }
 
+/*
+ * Track the makefiles we read - so makefiles can
+ * set dependencies on them.
+ * Avoid adding anything more than once.
+ */
+#define TRACK_INPUT_FMT "${.PARSEDIR}/${.PARSEFILE}"
+
+static void
+ParseTrackInput(const char *name)
+{
+    char tmp[sizeof(TRACK_INPUT_FMT) + 1];
+    char *val;
+    char *old;
+    char *cp;
+    char *fp = NULL;
+    
+    strncpy(tmp, TRACK_INPUT_FMT, sizeof(tmp));
+    val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
+    old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &fp);
+    if (old) {
+	/* does it contain val? */
+	if ((cp = strstr(old, val))) {
+	    int n = strlen(val);
+
+	    /*
+	     * It only counts if at the start/end
+	     * or bounded by ' '
+	     */
+	    if ((cp[n] == '\0' || cp[n] == ' ') &&
+		(cp == old || cp[-1] == ' ')) {
+		goto cleanup;		/* we already have it */
+	    }
+	}
+    }
+    Var_Append (MAKE_MAKEFILES, val, VAR_GLOBAL);
+ cleanup:
+    free(val);
+    if (fp) {
+	free(fp);
+    }
+}
+
 
 /*-
  *---------------------------------------------------------------------
@@ -1962,6 +2004,7 @@ Parse_SetInput(const char *name, int lin
     curFile->cond_depth = Cond_save_depth();
 
     ParseSetParseFile(name);
+    ParseTrackInput(name);
 
     if (buf == NULL) {
 	/*