Date: Sun, 24 May 2009 22:07:23 +0000 (UTC) From: John Birrell <jb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r192701 - projects/jbuild/usr.bin/make Message-ID: <200905242207.n4OM7N82002557@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jb Date: Sun May 24 22:07:23 2009 New Revision: 192701 URL: http://svn.freebsd.org/changeset/base/192701 Log: Merge build/jbuild changes from p4 Modified: projects/jbuild/usr.bin/make/cond.c projects/jbuild/usr.bin/make/dir.c projects/jbuild/usr.bin/make/dir.h projects/jbuild/usr.bin/make/globals.h projects/jbuild/usr.bin/make/job.c projects/jbuild/usr.bin/make/job.h projects/jbuild/usr.bin/make/main.c projects/jbuild/usr.bin/make/make.c projects/jbuild/usr.bin/make/parse.c projects/jbuild/usr.bin/make/pathnames.h projects/jbuild/usr.bin/make/proc.c projects/jbuild/usr.bin/make/proc.h projects/jbuild/usr.bin/make/util.c projects/jbuild/usr.bin/make/var.c Modified: projects/jbuild/usr.bin/make/cond.c ============================================================================== --- projects/jbuild/usr.bin/make/cond.c Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/cond.c Sun May 24 22:07:23 2009 (r192701) @@ -148,7 +148,7 @@ static CondProc *condDefProc; /* default static char *condExpr; /* The expression to parse */ static Token condPushBack = None; /* Single push-back token in parsing */ -#define MAXIF 30 /* greatest depth of #if'ing */ +#define MAXIF 1024 /* greatest depth of #if'ing */ static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ static int condLineno[MAXIF]; /* Line numbers of the opening .if */ Modified: projects/jbuild/usr.bin/make/dir.c ============================================================================== --- projects/jbuild/usr.bin/make/dir.c Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/dir.c Sun May 24 22:07:23 2009 (r192701) @@ -1152,3 +1152,15 @@ Path_Print(const struct Path *path) TAILQ_FOREACH(p, path, link) printf("%s ", p->dir->name); } + +#ifdef MAKE_IS_BUILD +void +Path_List(const struct Path *path, path_listcb_t *cbfunc, char *srctop, + size_t ssrctop) +{ + const struct PathElement *p; + + TAILQ_FOREACH(p, path, link) + cbfunc(srctop, ssrctop, p->dir->name); +} +#endif Modified: projects/jbuild/usr.bin/make/dir.h ============================================================================== --- projects/jbuild/usr.bin/make/dir.h Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/dir.h Sun May 24 22:07:23 2009 (r192701) @@ -68,4 +68,9 @@ char *Path_FindFile(char *, struct Path char *Path_MakeFlags(const char *, const struct Path *); void Path_Print(const struct Path *); +#ifdef MAKE_IS_BUILD +typedef void path_listcb_t(char *, size_t, const char *); +void Path_List(const struct Path *, path_listcb_t *, char *, size_t); +#endif + #endif /* dir_h_6002e3b8 */ Modified: projects/jbuild/usr.bin/make/globals.h ============================================================================== --- projects/jbuild/usr.bin/make/globals.h Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/globals.h Sun May 24 22:07:23 2009 (r192701) @@ -69,6 +69,9 @@ extern struct Path parseIncPath; /* The system include path. */ extern struct Path sysIncPath; +/* The build include path. */ +extern struct Path bldIncPath; + extern int jobLimit; /* -j argument: maximum number of jobs */ extern int makeErrors; /* Number of targets not remade due to errors */ extern Boolean jobsRunning; /* True if jobs are running */ @@ -95,6 +98,9 @@ extern Boolean touchFlag; * when the shell exits */ extern Boolean usePipes; +/* Gather meta data. */ +extern Boolean use_meta; + /* TRUE if we aren't supposed to really make anything, just see if the * targets are out-of-date */ extern Boolean queryFlag; Modified: projects/jbuild/usr.bin/make/job.c ============================================================================== --- projects/jbuild/usr.bin/make/job.c Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/job.c Sun May 24 22:07:23 2009 (r192701) @@ -101,8 +101,10 @@ __FBSDID("$FreeBSD$"); * thems as need creatin' */ +#include <sys/param.h> #include <sys/queue.h> #include <sys/types.h> +#include <sys/ioccom.h> #include <sys/select.h> #include <sys/stat.h> #ifdef USE_KQUEUE @@ -114,6 +116,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <fcntl.h> #include <inttypes.h> +#include <libgen.h> #include <string.h> #include <signal.h> #include <stdlib.h> @@ -136,9 +139,17 @@ __FBSDID("$FreeBSD$"); #include "targ.h" #include "util.h" #include "var.h" +#ifdef MAKE_IS_BUILD +#include "jdirdep.h" +#ifndef BUILDMON +#include "filemon.h" +#endif +#endif #define TMPPAT "/tmp/makeXXXXXXXXXX" +extern char **environ; + #ifndef USE_KQUEUE /* * The SEL_ constants determine the maximum amount of time spent in select @@ -165,6 +176,16 @@ typedef struct Job { pid_t pid; /* The child's process ID */ struct GNode *node; /* The target the child is making */ + char cwd[MAXPATHLEN]; + +#ifdef MAKE_IS_BUILD + char mon_fname[MAXPATHLEN]; +#ifndef BUILDMON + int filemon_fd; + int mon_fd; +#endif + FILE *mfp; +#endif /* * A LstNode for the first command to be saved after the job completes. @@ -264,6 +285,13 @@ TAILQ_HEAD(JobList, Job); * error handling variables */ static int aborting = 0; /* why is the make aborting? */ +#ifdef MAKE_IS_BUILD +static char mon_fname[MAXPATHLEN]; +#ifndef BUILDMON +static int filemon_fd = -1; +static int mon_fd = -1; +#endif +#endif #define ABORT_ERROR 1 /* Because of an error */ #define ABORT_INTERRUPT 2 /* Because it was interrupted */ #define ABORT_WAIT 3 /* Waiting for jobs to finish */ @@ -379,11 +407,283 @@ static int JobStart(GNode *, int, Job *) static void JobDoOutput(Job *, Boolean); static void JobInterrupt(int, int); static void JobRestartJobs(void); -static int Compat_RunCommand(char *, struct GNode *); +static int Compat_RunCommand(char *, struct GNode *, FILE *); static GNode *curTarg = NULL; static GNode *ENDNode; +#ifdef MAKE_IS_BUILD +static int n_meta_created = 0; /* Number of meta data files created. */ + +void +meta_exit(void) +{ + Boolean f = 0; + char *result; + char sharedobj[MAXPATHLEN]; + const char *curdir; + const char *filedep_name; + const char *objdir; + const char *objroot; + const char *p_incmk; + const char *p_machine; + const char *p_machine_arch; + const char *srcrel; + const char *srctop; + size_t len = 0; + + /* + * If no meta data files were created, then there can be no change + * to the dependencies. + */ + if (n_meta_created == 0) + return; + + /* + * If there is no include makefile list variable defined, then + * we can't update dependencies. + */ + if ((p_incmk = Var_Value("INCMK", VAR_GLOBAL)) != NULL) { + /* Initialise the include makefile name list. */ + jdirdep_incmk(Var_Value("INCMK", VAR_GLOBAL)); + + p_machine = Var_Value("MACHINE", VAR_GLOBAL); + p_machine_arch = Var_Value("MACHINE_ARCH", VAR_GLOBAL); + + if ((result = Var_Parse(p_machine_arch, VAR_GLOBAL, TRUE, &len, &f)) != var_Error) + p_machine_arch = result; + else + p_machine_arch = NULL; + + /* + * Initialise the current machine and architecture. + * Using this method, we only do one machine type at + * a time. + */ + jdirdep_supmac_add(p_machine, p_machine_arch); + + srctop = Var_Value(".SRCTOP", VAR_GLOBAL); + curdir = Var_Value(".CURDIR", VAR_GLOBAL); + srcrel = Var_Value(".SRCREL", VAR_GLOBAL); + objroot = Var_Value(".OBJROOT", VAR_GLOBAL); + objdir = Var_Value(".OBJDIR", VAR_GLOBAL); + filedep_name = Var_Value(".FILEDEP_NAME", VAR_GLOBAL); + + snprintf(sharedobj, sizeof(sharedobj), "%s/../shared", objroot); + + /* Add any new directory and/or source dependencies. */ + jdirdep(srctop, curdir, srcrel, objroot, objdir, sharedobj, filedep_name, + JDIRDEP_OPT_ADD | JDIRDEP_OPT_SOURCE | JDIRDEP_OPT_UPDATE); + } +} + +/* + * Read the build monitor output file and write records to the target's + * metadata file. + */ +static void +buildmon_read(FILE *mfp, const char *fname) +{ + FILE *fp; + char bufr[1024]; + int done = 0; + + /* Check if we're not writing to a meta data file.*/ + if (mfp == NULL) { + /* + * Delete the build monitor file since we have no need + * for it. + */ + unlink(fname); + return; + } + + if ((fp = fopen(fname, "r")) == NULL) + err(1, "Could not read build monitor file '%s'", fname); + + fprintf(mfp, "-- buildmon acquired metadata --\n"); + + do { + if (fgets(bufr, sizeof(bufr), fp) != NULL) { + if (strncmp(bufr, "# Session completed", 19) == 0) + done = 1; + + fprintf(mfp, "%s", bufr); + } else +#ifdef BUILDMON + usleep(1000); +#else + done = 1; +#endif + + clearerr(fp); + } while (!done); + + fclose(fp); + + /* Delete the build monitor file now we're done with it. */ + unlink(fname); +} + +#ifndef BUILDMON +/* + * Open the filemon device. + */ +static void +filemon_open(Job *job) +{ + int retry = 5; + + strcpy(mon_fname, "filemon.XXXXXX"); + + while (retry > 0) { + if ((filemon_fd = open("/dev/filemon", O_RDWR)) >= 0) + break; + + retry--; + } + + if (filemon_fd < 0) + err(1, "Could not open filemon device!"); + if ((mon_fd = mkstemp(mon_fname)) < 0) + err(1, "Could not create temporary file!"); + else if (ioctl(filemon_fd, FILEMON_SET_FD, &mon_fd) < 0) + err(1, "Could not set filemon file descriptor!"); + + if (job != NULL) { + job->filemon_fd = filemon_fd; + job->mon_fd = mon_fd; + strlcpy(job->mon_fname, mon_fname, sizeof(job->mon_fname)); + } +} +#endif + +char * +meta_name(struct GNode *gn, char *mname, size_t mnamelen) +{ + char bufr[PATH_MAX]; + char *p; + const char *dname = Var_Value(".OBJDIR", gn); + const char *tname = Var_Value(TARGET, gn); + + /* Weed out relative paths from the target file name. */ + tname = realpath(tname, bufr); + + if (strcmp(dname, dirname(tname)) == 0) + snprintf(mname, mnamelen, "%s.meta", tname); + else { + snprintf(mname, mnamelen, "%s/%s.meta", dname, tname); + + /* + * Replace path separators in the file name after the + * current object directory path. + */ + p = mname + strlen(dname) + 1; + + while (*p != '\0') { + if (*p == '/') + *p = '_'; + p++; + } + } + + return (mname); +} + +static FILE * +meta_create(GNode *gn) +{ + FILE *fp; + LstNode *ln; + char bufr[PATH_MAX]; + char fname[MAXPATHLEN]; + char **ptr; + const char *cname = Var_Value(".CURDIR", gn); + const char *dname = Var_Value(".OBJDIR", gn); + const char *p; + const char *tname = Var_Value(TARGET, gn); + int f_make = 0; + struct stat fs; + + /* This may be a phony node which we don't want meta data for... */ + if ((gn->type & OP_PHONY) != 0) + return (NULL); + + /* The object directory may not exist. Check it.. */ + if (stat(dname, &fs) != 0) + return (NULL); + + /* Check if there are no commands to execute. */ + if (gn->commands.firstPtr == NULL) + return (NULL); + + /* If we aren't in the object directory, don't create a meta file. */ + if (strcmp(cname, dname) == 0) + return (NULL); + + LST_FOREACH(ln, &gn->commands) { + char *cp; + for (cp = Lst_Datum(ln); !f_make && *cp != '\0'; cp++) { + if (*cp == '$') { + Boolean f = 0; + size_t len = 0; + char *result; + + if ((result = Var_Parse(cp, gn, TRUE, + &len, &f)) != var_Error) { + if (len == 7 && strncmp(cp, "${MAKE}", 7) == 0) + f_make = 1; + if (f) + free(result); + cp += len - 1; + } + } + } + } + + /* Check if a recusive 'make' reference was found. */ + if (f_make) + /* Don't create meta data for recursive make commands. */ + return (NULL); + + /* Check if the target is in the current object directory. */ + if ((p = strrchr(tname, '/')) == NULL) { + p = tname; + fprintf(stderr, "Building %s/%s\n", dname, p); + } else { + p++; + fprintf(stderr, "Building %s\n", realpath(tname, bufr)); + } + + fflush(stdout); + + if (!use_meta) + /* Don't create meta data. */ + return (NULL); + + meta_name(gn, fname, sizeof(fname)); + + if ((fp = fopen(fname, "w")) == NULL) + err(1, "Could not open meta file '%s'", fname); + + fprintf(fp, "# Meta data file %s\n", fname); + + LST_FOREACH(ln, &gn->commands) + fprintf(fp, "CMD %s\n", Buf_Peel(Var_Subst(Lst_Datum(ln), gn, FALSE))); + + fprintf(fp, "CWD %s\n", getcwd(bufr, sizeof(bufr))); + + for (ptr = environ; *ptr != NULL; ptr++) + fprintf(fp, "ENV %s\n", *ptr); + + fprintf(fp, "-- command output --\n"); + + n_meta_created++; + + return (fp); +} +#endif + /** * Create a fifo file with a uniq filename, and returns a file * descriptor to that fifo. @@ -713,7 +1013,7 @@ JobPrintCommand(char *cmd, Job *job) * but this one needs to be - use compat mode * just for it. */ - Compat_RunCommand(cmd, job->node); + Compat_RunCommand(cmd, job->node, NULL); return (0); } break; @@ -959,6 +1259,15 @@ JobFinish(Job *job, int *status) MESSAGE(out, job->node); lastNode = job->node; } +#ifdef MAKE_IS_BUILD + if (job->mfp != NULL) + fprintf(job->mfp, "*** Error code %d%s\n", + WEXITSTATUS(*status), + (job->flags & JOB_IGNERR) ? + "(ignored)" : ""); +#endif + fprintf(out, "Error building '%s'\nin directory %s\n", + job->node->path, job->cwd); fprintf(out, "*** Error code %d%s\n", WEXITSTATUS(*status), (job->flags & JOB_IGNERR) ? @@ -1118,6 +1427,23 @@ JobFinish(Job *job, int *status) Buf_Peel( Var_Subst(Lst_Datum(ln), job->node, FALSE))); } +#ifdef MAKE_IS_BUILD + if (job->mfp != NULL) { +#ifndef BUILDMON + close(job->filemon_fd); + close(job->mon_fd); +#endif + + /* Process the build monitor file. */ + buildmon_read(job->mfp, job->mon_fname); + + /* + * Close the meta file now that the target has been + * made. + */ + fclose(job->mfp); + } +#endif job->node->made = MADE; Make_Update(job->node); @@ -1299,6 +1625,11 @@ static void JobExec(Job *job, char **argv) { ProcStuff ps; +#ifdef MAKE_IS_BUILD +#ifdef BUILDMON + ssize_t num; +#endif +#endif if (DEBUG(JOB)) { int i; @@ -1347,6 +1678,19 @@ JobExec(Job *job, char **argv) ps.argv = argv; ps.argv_free = 0; +#ifdef MAKE_IS_BUILD + ps.mfp = job->mfp; + +#ifdef BUILDMON + if (job->mfp != NULL && pipe(ps.pipe_fds) < 0) + errx(1, "Could not create pipe for child/parent comms"); +#else + if (job->mfp != NULL) + /* Open the filemon device. */ + filemon_open(job); +#endif +#endif + /* * Fork. Warning since we are doing vfork() instead of fork(), * do not allocate memory in the child process! @@ -1362,6 +1706,14 @@ JobExec(Job *job, char **argv) if (fifoFd >= 0) close(fifoFd); +#ifdef MAKE_IS_BUILD +#ifdef BUILDMON + if (job->mfp != NULL) + /* Close the read end of the pipe. */ + close(ps.pipe_fds[0]); +#endif +#endif + Proc_Exec(&ps); /* NOTREACHED */ } @@ -1371,6 +1723,29 @@ JobExec(Job *job, char **argv) */ job->pid = ps.child_pid; +#ifdef MAKE_IS_BUILD + if (job->mfp != NULL) { +#ifdef BUILDMON + /* Close the write end of the pipe. */ + close(ps.pipe_fds[1]); + + if ((num = read(ps.pipe_fds[0], job->mon_fname, + sizeof(job->mon_fname))) <= 0) + err(1, "Error reading buildmon file name from pipe"); + + /* Close the read end of the pipe. */ + close(ps.pipe_fds[0]); +#else + /* + * Now that the child's pid is known update the filemon to + * monitor just it. + */ + if (ioctl(job->filemon_fd, FILEMON_SET_PID, &ps.child_pid) < 0) + err(1, "Could not set filemon pid!"); +#endif + } +#endif + if (usePipes && (job->flags & JOB_FIRST)) { /* * The first time a job is run for a node, we set the @@ -1593,6 +1968,7 @@ JobStart(GNode *gn, int flags, Job *prev job->node = gn; job->tailCmds = NULL; + getcwd(job->cwd, sizeof(job->cwd)); /* * Set the initial value of the flags for this job based on the global @@ -1693,6 +2069,9 @@ JobStart(GNode *gn, int flags, Job *prev * We can do all the commands at once. hooray for sanity */ numCommands = 0; +#ifdef MAKE_IS_BUILD + job->mfp = meta_create(gn); +#endif LST_FOREACH(ln, &gn->commands) { if (JobPrintCommand(Lst_Datum(ln), job)) break; @@ -2022,6 +2401,12 @@ JobDoOutput(Job *job, Boolean finish) MESSAGE(stdout, job->node); lastNode = job->node; } +#ifdef MAKE_IS_BUILD + if (job->mfp != NULL && + strncmp(cp, "Building", 8) != 0) + fprintf(job->mfp, "%s%s", cp, + gotNL ? "\n" : ""); +#endif fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); fflush(stdout); @@ -2706,6 +3091,10 @@ Cmd_Exec(const char *cmd, const char **e ps.argv[3] = NULL; ps.argv_free = 1; +#ifdef MAKE_IS_BUILD + ps.mfp = NULL; +#endif + /* * Fork. Warning since we are doing vfork() instead of fork(), * do not allocate memory in the child process! @@ -2718,6 +3107,16 @@ Cmd_Exec(const char *cmd, const char **e /* * Child */ +#ifdef MAKE_IS_BUILD +#ifdef BUILDMON + /* Close the read end of the pipe. */ + close(ps.pipe_fds[0]); +#else + /* Close the write end of the pipe. */ + close(ps.pipe_fds[1]); +#endif +#endif + Proc_Exec(&ps); /* NOTREACHED */ } @@ -2813,7 +3212,7 @@ CompatInterrupt(int signo) gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); if (gn != NULL) { LST_FOREACH(ln, &gn->commands) { - if (Compat_RunCommand(Lst_Datum(ln), gn)) + if (Compat_RunCommand(Lst_Datum(ln), gn, NULL)) break; } } @@ -2888,7 +3287,7 @@ shellneed(ArgArray *aa, char *cmd) * The node's 'made' field may be set to ERROR. */ static int -Compat_RunCommand(char *cmd, GNode *gn) +Compat_RunCommand(char *cmd, GNode *gn, FILE *mfp) { ArgArray aa; char *cmdStart; /* Start of expanded command */ @@ -2995,21 +3394,67 @@ Compat_RunCommand(char *cmd, GNode *gn) } ps.errCheck = errCheck; +#ifdef MAKE_IS_BUILD + ps.mfp = mfp; + +#ifdef BUILDMON + if (mfp != NULL && pipe(ps.pipe_fds) < 0) + errx(1, "Could not create pipe for child/parent comms"); +#else + if (mfp != NULL) + /* Open the filemon device. */ + filemon_open(NULL); +#endif +#endif + /* * Warning since we are doing vfork() instead of fork(), * do not allocate memory in the child process! */ if ((ps.child_pid = vfork()) == -1) { - Fatal("Could not fork"); + Fatal("Cannot fork"); } else if (ps.child_pid == 0) { /* * Child */ +#ifdef MAKE_IS_BUILD +#ifdef BUILDMON + /* Close the read end of the pipe. */ + close(ps.pipe_fds[0]); +#endif +#endif + Proc_Exec(&ps); - /* NOTREACHED */ + _exit(1); } else { +#ifdef MAKE_IS_BUILD +#ifdef BUILDMON + char bufr[MAXPATHLEN]; + if (mfp != NULL) { + ssize_t num; + + /* Close the write end of the pipe. */ + close(ps.pipe_fds[1]); + + if ((num = read(ps.pipe_fds[0], bufr, sizeof(bufr))) <= 0) + err(1, "Error reading buildmon file name from pipe"); + + /* Close the read end of the pipe. */ + close(ps.pipe_fds[0]); + } +#else + if (mfp != NULL) + /* + * Now that the child's pid is known update the + * filemon to monitor just it. + */ + if (ioctl(filemon_fd, FILEMON_SET_PID, &ps.child_pid) < 0) + err(1, "Could not set filemon pid!"); +#endif +#endif + if (ps.argv_free) { free(ps.argv[2]); free(ps.argv[1]); @@ -3034,6 +3479,17 @@ Compat_RunCommand(char *cmd, GNode *gn) */ reason = ProcWait(&ps); +#ifdef MAKE_IS_BUILD + if (mfp != NULL) { +#ifndef BUILDMON + close(filemon_fd); + close(mon_fd); +#endif + /* Process the build monitor file. */ + buildmon_read(mfp, mon_fname); + } +#endif + if (interrupted) CompatInterrupt(interrupted); @@ -3047,12 +3503,20 @@ Compat_RunCommand(char *cmd, GNode *gn) return (0); } else { printf("*** Error code %d", status); +#ifdef MAKE_IS_BUILD + if (mfp != NULL) + fprintf(mfp, "*** Error code %d", status); +#endif } } else if (WIFSTOPPED(reason)) { status = WSTOPSIG(reason); } else { status = WTERMSIG(reason); printf("*** Signal %d", status); +#ifdef MAKE_IS_BUILD + if (mfp != NULL) + fprintf(mfp, "*** Signal %d", status); +#endif } if (ps.errCheck) { @@ -3064,6 +3528,10 @@ Compat_RunCommand(char *cmd, GNode *gn) * others continue. */ printf(" (continuing)\n"); +#ifdef MAKE_IS_BUILD + if (mfp != NULL) + fprintf(mfp, " (continuing)\n"); +#endif } return (status); } else { @@ -3074,6 +3542,10 @@ Compat_RunCommand(char *cmd, GNode *gn) * happen... */ printf(" (ignored)\n"); +#ifdef MAKE_IS_BUILD + if (mfp != NULL) + fprintf(mfp, " (ignored)\n"); +#endif return (0); } } @@ -3117,10 +3589,27 @@ Compat_Make(GNode *gn, GNode *pgn) return (0); } +#ifdef MAKE_IS_BUILD + if (strcmp(gn->name, ".depend") == 0) { + gn->made = UPTODATE; + return (0); + } +#endif + if (Lst_Member(&gn->iParents, pgn) != NULL) { Var_Set(IMPSRC, Var_Value(TARGET, gn), pgn); } +#ifdef MAKE_IS_BUILD + /* + * We need to check if the target is out-of-date. This includes + * checking if the expanded command has changed. This in turn + * requires that all variables are set in the same way that they + * would be if the target needs to be re-built. + */ + Make_DoAllVar(gn); +#endif + /* * All the children were made ok. Now cmtime contains the * modification time of the newest child, we need to find out @@ -3144,12 +3633,14 @@ Compat_Make(GNode *gn, GNode *pgn) exit(1); } +#ifndef MAKE_IS_BUILD /* * We need to be re-made. We also have to make sure we've got * a $? variable. To be nice, we also define the $> variable * using Make_DoAllVar(). */ Make_DoAllVar(gn); +#endif /* * Alter our type to tell if errors should be ignored or things @@ -3171,7 +3662,7 @@ Compat_Make(GNode *gn, GNode *pgn) curTarg = gn; LST_FOREACH(ln, &gn->commands) { if (Compat_RunCommand(Lst_Datum(ln), - gn)) + gn, NULL)) break; } curTarg = NULL; @@ -3348,8 +3839,13 @@ Compat_Run(Lst *targs) if (!queryFlag) { gn = Targ_FindNode(".BEGIN", TARG_NOCREATE); if (gn != NULL) { +#ifdef MAKE_IS_BUILD + fprintf(stderr, "Building %s/%s\n", Var_Value(".OBJDIR", gn), + Var_Value(TARGET, gn)); + fflush(stdout); +#endif LST_FOREACH(ln, &gn->commands) { - if (Compat_RunCommand(Lst_Datum(ln), gn)) + if (Compat_RunCommand(Lst_Datum(ln), gn, NULL)) break; } if (gn->made == ERROR) { @@ -3387,9 +3883,14 @@ Compat_Run(Lst *targs) * If the user has defined a .END target, run its commands. */ if (makeErrors == 0) { +#ifdef MAKE_IS_BUILD + fprintf(stderr, "Building %s/%s\n", Var_Value(".OBJDIR", gn), + Var_Value(TARGET, gn)); +#endif LST_FOREACH(ln, &ENDNode->commands) { - if (Compat_RunCommand(Lst_Datum(ln), ENDNode)) + if (Compat_RunCommand(Lst_Datum(ln), ENDNode, NULL)) break; } } } + Modified: projects/jbuild/usr.bin/make/job.h ============================================================================== --- projects/jbuild/usr.bin/make/job.h Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/job.h Sun May 24 22:07:23 2009 (r192701) @@ -77,4 +77,9 @@ int Compat_Make(struct GNode *gn, struct void Compat_InstallSignalHandlers(void); void Compat_Run(struct Lst *); +#ifdef MAKE_IS_BUILD +char *meta_name(struct GNode *, char *, size_t); +void meta_exit(void); +#endif + #endif /* job_h_4678dfd1 */ Modified: projects/jbuild/usr.bin/make/main.c ============================================================================== --- projects/jbuild/usr.bin/make/main.c Sun May 24 22:00:20 2009 (r192700) +++ projects/jbuild/usr.bin/make/main.c Sun May 24 22:07:23 2009 (r192701) @@ -114,6 +114,13 @@ static char *curdir; /* startup director static char *objdir; /* where we chdir'ed to */ static char **save_argv; /* saved argv */ static char *save_makeflags;/* saved MAKEFLAGS */ +#ifdef MAKE_IS_BUILD +static char *save_mklvl; /* saved __MKLVL__ */ +static char *save_path; /* saved PATH */ +static char *clean_environ[2]; +static char *default_machine = NULL; +#endif +static struct utsname utsname; /* (-E) vars to override from env */ Lst envFirstVars = Lst_Initializer(envFirstVars); @@ -140,6 +147,9 @@ Boolean printGraphOnly; /* -p flag */ Boolean queryFlag; /* -q flag */ Boolean touchFlag; /* -t flag */ Boolean usePipes; /* !-P flag */ +#ifdef MAKE_IS_BUILD +Boolean use_meta; /* !-Q flag */ +#endif uint32_t warn_cmd; /* command line warning flags */ uint32_t warn_flags; /* actual warning flags */ uint32_t warn_nocmd; /* command line no-warning flags */ @@ -154,7 +164,8 @@ static void usage(void) { fprintf(stderr, - "usage: make [-BPSXeiknpqrstv] [-C directory] [-D variable]\n" + "usage: make [-BPQSXeiknpqrstv] [-C directory] [-D variable]\n" + "\t[-b directory]\n" "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n" "\t[-j max_jobs] [-m directory] [-V variable]\n" "\t[variable=value] [target ...]\n"); @@ -459,6 +470,10 @@ rearg: Lst_AtEnd(&envFirstVars, estrdup(optarg)); MFLAGS_append("-E", optarg); break; + case 'b': + Path_AddDir(&bldIncPath, optarg); + MFLAGS_append("-b", optarg); + break; case 'e': checkEnvFirst = TRUE; MFLAGS_append("-e", NULL); @@ -510,6 +525,9 @@ rearg: case 'Q': beQuiet = TRUE; beVerbose = FALSE; +#ifdef MAKE_IS_BUILD + use_meta = FALSE; +#endif MFLAGS_append("-Q", NULL); break; case 'q': @@ -526,7 +544,11 @@ rearg: MFLAGS_append("-S", NULL); break; case 's': +#ifdef MAKE_IS_BUILD + beSilent = FALSE; +#else beSilent = TRUE; +#endif MFLAGS_append("-s", NULL); break; case 't': @@ -572,6 +594,11 @@ rearg: char *ptr = MAKEFLAGS_quote(*argv); char *v = estrdup(*argv); +#ifdef MAKE_IS_BUILD + if (strncmp(v, "MACHINE=", 8) == 0) + default_machine = utsname.machine; +#endif + Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL); Parse_DoVar(v, VAR_CMD); free(ptr); @@ -671,7 +698,11 @@ static void check_make_level(void) { #ifdef WANT_ENV_MKLVL +#ifdef MAKE_IS_BUILD + char *value = save_mklvl; +#else char *value = getenv(MKLVL_ENVVAR); +#endif int level = (value == NULL) ? 0 : atoi(value); if (level < 0) { @@ -685,6 +716,15 @@ check_make_level(void) sprintf(new_value, "%d", level + 1); setenv(MKLVL_ENVVAR, new_value, 1); } + +#ifdef MAKE_IS_BUILD + /* + * Register a function to call on exit for child build processes so + * that dependency hooks can be activated. + */ + if (level > 0) + atexit(meta_exit); +#endif #endif /* WANT_ENV_MKLVL */ } @@ -833,6 +873,57 @@ Remake_Makefiles(void) } } +#ifdef MAKE_IS_BUILD +static void +make_objdir(char *path) +{ + struct stat fs; + + while (stat(path, &fs) != 0) { + char bufr[MAXPATHLEN]; + char *p; + + strcpy(bufr, path); + + if ((p = strrchr(bufr, '/')) == NULL) + err(1, "Missing '/' in directory path"); + else { + *p = '\0'; + + make_objdir(bufr); + } + + if (mkdir(path, 0775) != 0 && errno != EEXIST) + err(1, "Could not make directory '%s'", path); + } +} + +static void +mk_path_init(char *srctop, size_t ssrctop, const char *p) +{ + char path[MAXPATHLEN]; + const char *mk_path_rel = "/bld"; + size_t len; + size_t len1 = strlen(mk_path_rel); + + if (*srctop != '\0' || ssrctop == 0) + return; + + if (realpath(p, path) == NULL) + return; + + if ((len = strlen(path)) < len1) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905242207.n4OM7N82002557>