Synchronize on NetBSD-CVS (2013/12/1 12:00:00 UTC)
- Fix for possible unset uid/gid in toproto
- Fix for default mtree style
- Update libelf
- Importing libexecinfo
- Resynchronize GCC, mpc, gmp, mpfr
- build.sh: Replace params with show-params.
This has been done as the make target has been renamed in the same
way, while a new target named params has been added. This new
target generates a file containing all the parameters, instead of
printing it on the console.
- Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
get getservbyport() out of the inner loop
Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
This commit is contained in:
@@ -1,71 +0,0 @@
|
||||
# $NetBSD: Makefile,v 1.55 2011/08/14 13:06:09 christos Exp $
|
||||
# @(#)Makefile 5.2 (Berkeley) 12/28/90
|
||||
|
||||
PROG= make
|
||||
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
|
||||
make.c parse.c str.c suff.c targ.c trace.c var.c util.c
|
||||
SRCS+= strlist.c
|
||||
SRCS+= make_malloc.c
|
||||
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
|
||||
lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
|
||||
lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \
|
||||
lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \
|
||||
lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c
|
||||
SRCS += lstPrev.c
|
||||
|
||||
# let people experiment for a bit
|
||||
USE_META ?= no
|
||||
.if ${USE_META:tl} != "no"
|
||||
SRCS+= meta.c
|
||||
CPPFLAGS+= -DUSE_META
|
||||
FILEMON_H ?= ${.CURDIR:H:H}/sys/dev/filemon/filemon.h
|
||||
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
|
||||
COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
|
||||
.endif
|
||||
.endif
|
||||
|
||||
# For MINIX
|
||||
CPPFLAGS+= -DHAVE_SETENV -DHAVE_STRERROR -DHAVE_STRDUP \
|
||||
-DHAVE_STRFTIME -DHAVE_VSNPRINTF -DUSE_SELECT
|
||||
|
||||
# Gross hack, but we assume i386 everywhere
|
||||
.if ${MACHINE_ARCH} == "i686"
|
||||
MACHINE_ARCH=i386
|
||||
.endif
|
||||
.if $(MACHINE) == "i686"
|
||||
MACHINE=i386
|
||||
.endif
|
||||
CPPFLAGS+= -DTARGET_MACHINE=\"${MACHINE}\" \
|
||||
-DTARGET_MACHINE_ARCH=\"${MACHINE_ARCH}\" \
|
||||
-DMAKE_MACHINE=\"${MACHINE}\" \
|
||||
-DMAKE_MACHINE_ARCH=\"${MACHINE_ARCH}\"
|
||||
|
||||
|
||||
.PATH: ${.CURDIR}/lst.lib
|
||||
.if make(install)
|
||||
SUBDIR= PSD.doc
|
||||
.endif
|
||||
.if make(obj) || make(clean)
|
||||
SUBDIR+= unit-tests
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
.ifdef TOOLDIR
|
||||
CPPFLAGS+= -DMAKE_NATIVE
|
||||
COPTS.var.c += -Wno-cast-qual
|
||||
COPTS.job.c += -Wno-format-nonliteral
|
||||
COPTS.parse.c += -Wno-format-nonliteral
|
||||
COPTS.var.c += -Wno-format-nonliteral
|
||||
|
||||
# this is a native netbsd build,
|
||||
# use libutil rather than the local emalloc etc.
|
||||
CPPFLAGS+= -DUSE_EMALLOC
|
||||
LDADD+=-lutil
|
||||
DPADD+=${LIBUTIL}
|
||||
.endif
|
||||
|
||||
# A simple unit-test driver to help catch regressions
|
||||
accept test:
|
||||
cd ${.CURDIR}/unit-tests && ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: compat.c,v 1.90 2012/10/07 19:17:31 sjg Exp $ */
|
||||
/* $NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: compat.c,v 1.90 2012/10/07 19:17:31 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: compat.c,v 1.90 2012/10/07 19:17:31 sjg Exp $");
|
||||
__RCSID("$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -329,18 +329,23 @@ again:
|
||||
* We need to pass the command off to the shell, typically
|
||||
* because the command contains a "meta" character.
|
||||
*/
|
||||
static const char *shargv[4];
|
||||
static const char *shargv[5];
|
||||
int shargc;
|
||||
|
||||
shargv[0] = shellPath;
|
||||
shargc = 0;
|
||||
shargv[shargc++] = shellPath;
|
||||
/*
|
||||
* The following work for any of the builtin shell specs.
|
||||
*/
|
||||
if (errCheck && shellErrFlag) {
|
||||
shargv[shargc++] = shellErrFlag;
|
||||
}
|
||||
if (DEBUG(SHELL))
|
||||
shargv[1] = "-xc";
|
||||
shargv[shargc++] = "-xc";
|
||||
else
|
||||
shargv[1] = "-c";
|
||||
shargv[2] = cmd;
|
||||
shargv[3] = NULL;
|
||||
shargv[shargc++] = "-c";
|
||||
shargv[shargc++] = cmd;
|
||||
shargv[shargc++] = NULL;
|
||||
av = shargv;
|
||||
argc = 0;
|
||||
bp = NULL;
|
||||
@@ -374,7 +379,6 @@ again:
|
||||
Fatal("Could not fork");
|
||||
}
|
||||
if (cpid == 0) {
|
||||
Check_Cwd(av);
|
||||
Var_ExportVars();
|
||||
#ifdef USE_META
|
||||
if (useMeta) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $ */
|
||||
/* $NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $";
|
||||
static char rcsid[] = "$NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 christos Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $");
|
||||
__RCSID("$NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -1227,7 +1227,8 @@ do_Cond_EvalExpression(Boolean *value)
|
||||
int
|
||||
Cond_Eval(char *line)
|
||||
{
|
||||
#define MAXIF 128 /* maximum depth of .if'ing */
|
||||
#define MAXIF 128 /* maximum depth of .if'ing */
|
||||
#define MAXIF_BUMP 32 /* how much to grow by */
|
||||
enum if_states {
|
||||
IF_ACTIVE, /* .if or .elif part active */
|
||||
ELSE_ACTIVE, /* .else part active */
|
||||
@@ -1235,7 +1236,8 @@ Cond_Eval(char *line)
|
||||
SKIP_TO_ELSE, /* has been true, but not seen '.else' */
|
||||
SKIP_TO_ENDIF /* nothing else to execute */
|
||||
};
|
||||
static enum if_states cond_state[MAXIF + 1] = { IF_ACTIVE };
|
||||
static enum if_states *cond_state = NULL;
|
||||
static unsigned int max_if_depth = MAXIF;
|
||||
|
||||
const struct If *ifp;
|
||||
Boolean isElif;
|
||||
@@ -1244,7 +1246,10 @@ Cond_Eval(char *line)
|
||||
enum if_states state;
|
||||
|
||||
level = PARSE_FATAL;
|
||||
|
||||
if (!cond_state) {
|
||||
cond_state = bmake_malloc(max_if_depth * sizeof(*cond_state));
|
||||
cond_state[0] = IF_ACTIVE;
|
||||
}
|
||||
/* skip leading character (the '.') and any whitespace */
|
||||
for (line++; *line == ' ' || *line == '\t'; line++)
|
||||
continue;
|
||||
@@ -1261,8 +1266,6 @@ Cond_Eval(char *line)
|
||||
}
|
||||
/* Return state for previous conditional */
|
||||
cond_depth--;
|
||||
if (cond_depth > MAXIF)
|
||||
return COND_SKIP;
|
||||
return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
|
||||
}
|
||||
|
||||
@@ -1275,8 +1278,6 @@ Cond_Eval(char *line)
|
||||
return COND_PARSE;
|
||||
}
|
||||
|
||||
if (cond_depth > MAXIF)
|
||||
return COND_SKIP;
|
||||
state = cond_state[cond_depth];
|
||||
switch (state) {
|
||||
case SEARCH_FOR_ELIF:
|
||||
@@ -1325,9 +1326,6 @@ Cond_Eval(char *line)
|
||||
Parse_Error(level, "if-less elif");
|
||||
return COND_PARSE;
|
||||
}
|
||||
if (cond_depth > MAXIF)
|
||||
/* Error reported when we saw the .if ... */
|
||||
return COND_SKIP;
|
||||
state = cond_state[cond_depth];
|
||||
if (state == SKIP_TO_ENDIF || state == ELSE_ACTIVE) {
|
||||
Parse_Error(PARSE_WARNING, "extra elif");
|
||||
@@ -1341,10 +1339,15 @@ Cond_Eval(char *line)
|
||||
}
|
||||
} else {
|
||||
/* Normal .if */
|
||||
if (cond_depth >= MAXIF) {
|
||||
cond_depth++;
|
||||
Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);
|
||||
return COND_SKIP;
|
||||
if (cond_depth + 1 >= max_if_depth) {
|
||||
/*
|
||||
* This is rare, but not impossible.
|
||||
* In meta mode, dirdeps.mk (only runs at level 0)
|
||||
* can need more than the default.
|
||||
*/
|
||||
max_if_depth += MAXIF_BUMP;
|
||||
cond_state = bmake_realloc(cond_state, max_if_depth *
|
||||
sizeof(*cond_state));
|
||||
}
|
||||
state = cond_state[cond_depth];
|
||||
cond_depth++;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $ */
|
||||
/* $NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $";
|
||||
static char rcsid[] = "$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
|
||||
__RCSID("$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -145,6 +145,7 @@ __RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "dir.h"
|
||||
#include "job.h"
|
||||
|
||||
/*
|
||||
* A search path consists of a Lst of Path structures. A Path structure
|
||||
@@ -1463,9 +1464,11 @@ Dir_MTime(GNode *gn, Boolean recheck)
|
||||
* so that we give that to the compiler.
|
||||
*/
|
||||
gn->path = bmake_strdup(fullName);
|
||||
fprintf(stdout,
|
||||
"%s: ignoring stale %s for %s, found %s\n",
|
||||
progname, makeDependfile, gn->name, fullName);
|
||||
if (!Job_RunTarget(".STALE", gn->fname))
|
||||
fprintf(stdout,
|
||||
"%s: %s, %d: ignoring stale %s for %s, "
|
||||
"found %s\n", progname, gn->fname, gn->lineno,
|
||||
makeDependfile, gn->name, fullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $ */
|
||||
/* $NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $";
|
||||
static char rcsid[] = "$NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $");
|
||||
__RCSID("$NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -221,6 +221,9 @@ Hash_FindEntry(Hash_Table *t, const char *key)
|
||||
unsigned h;
|
||||
const char *p;
|
||||
|
||||
if (t == NULL || t->bucketPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (h = 0, p = key; *p;)
|
||||
h = (h << 5) - h + *p++;
|
||||
p = key;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $ */
|
||||
/* $NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@@ -70,14 +70,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $");
|
||||
__RCSID("$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -139,6 +139,7 @@ __RCSID("$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $");
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifndef USE_SELECT
|
||||
@@ -299,6 +300,7 @@ static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to
|
||||
const char *shellPath = NULL, /* full pathname of
|
||||
* executable image */
|
||||
*shellName = NULL; /* last component of shell */
|
||||
char *shellErrFlag = NULL;
|
||||
static const char *shellArgv = NULL; /* Custom shell args */
|
||||
|
||||
|
||||
@@ -330,7 +332,7 @@ static Job childExitJob; /* child exit pseudo-job */
|
||||
|
||||
#define TARG_FMT "%s %s ---\n" /* Default format */
|
||||
#define MESSAGE(fp, gn) \
|
||||
if (maxJobs != 1) \
|
||||
if (maxJobs != 1 && targPrefix && *targPrefix) \
|
||||
(void)fprintf(fp, TARG_FMT, targPrefix, gn->name)
|
||||
|
||||
static sigset_t caught_signals; /* Set of signals we handle */
|
||||
@@ -400,6 +402,15 @@ JobCreatePipe(Job *job, int minfd)
|
||||
if (pipe(job->jobPipe) == -1)
|
||||
Punt("Cannot create pipe: %s", strerror(errno));
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Avoid using low numbered fds */
|
||||
fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
|
||||
if (fd != -1) {
|
||||
close(job->jobPipe[i]);
|
||||
job->jobPipe[i] = fd;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set close-on-exec flag for both */
|
||||
(void)fcntl(job->jobPipe[0], F_SETFD, 1);
|
||||
(void)fcntl(job->jobPipe[1], F_SETFD, 1);
|
||||
@@ -412,15 +423,6 @@ JobCreatePipe(Job *job, int minfd)
|
||||
*/
|
||||
fcntl(job->jobPipe[0], F_SETFL,
|
||||
fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Avoid using low numbered fds */
|
||||
fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
|
||||
if (fd != -1) {
|
||||
close(job->jobPipe[i]);
|
||||
job->jobPipe[i] = fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
@@ -477,7 +479,8 @@ JobCondPassSig(int signo)
|
||||
static void
|
||||
JobChildSig(int signo MAKE_ATTR_UNUSED)
|
||||
{
|
||||
write(childExitJob.outPipe, CHILD_EXIT, 1);
|
||||
while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 && errno == EAGAIN)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -504,7 +507,9 @@ JobContinueSig(int signo MAKE_ATTR_UNUSED)
|
||||
* Defer sending to SIGCONT to our stopped children until we return
|
||||
* from the signal handler.
|
||||
*/
|
||||
write(childExitJob.outPipe, DO_JOB_RESUME, 1);
|
||||
while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 &&
|
||||
errno == EAGAIN)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-
|
||||
@@ -675,7 +680,6 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
char *escCmd = NULL; /* Command with quotes/backticks escaped */
|
||||
char *cmd = (char *)cmdp;
|
||||
Job *job = (Job *)jobp;
|
||||
char *cp, *tmp;
|
||||
int i, j;
|
||||
|
||||
noSpecials = NoExecute(job->node);
|
||||
@@ -847,11 +851,6 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
job->flags |= JOB_TRACED;
|
||||
}
|
||||
|
||||
if ((cp = Check_Cwd_Cmd(cmd)) != NULL) {
|
||||
DBPRINTF("test -d %s && ", cp);
|
||||
DBPRINTF("cd %s\n", cp);
|
||||
}
|
||||
|
||||
DBPRINTF(cmdTemplate, cmd);
|
||||
free(cmdStart);
|
||||
if (escCmd)
|
||||
@@ -871,10 +870,6 @@ JobPrintCommand(void *cmdp, void *jobp)
|
||||
if (shutUp && commandShell->hasEchoCtl) {
|
||||
DBPRINTF("%s\n", commandShell->echoOn);
|
||||
}
|
||||
if (cp != NULL) {
|
||||
DBPRINTF("test -d %s && ", cp);
|
||||
DBPRINTF("cd %s\n", Var_Value(".OBJDIR", VAR_GLOBAL, &tmp));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1171,7 +1166,8 @@ Job_Touch(GNode *gn, Boolean silent)
|
||||
*/
|
||||
if (read(streamID, &c, 1) == 1) {
|
||||
(void)lseek(streamID, (off_t)0, SEEK_SET);
|
||||
(void)write(streamID, &c, 1);
|
||||
while (write(streamID, &c, 1) == -1 && errno == EAGAIN)
|
||||
continue;
|
||||
}
|
||||
|
||||
(void)close(streamID);
|
||||
@@ -1237,8 +1233,10 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
|
||||
static const char msg[] = ": don't know how to make";
|
||||
|
||||
if (gn->flags & FROM_DEPEND) {
|
||||
fprintf(stdout, "%s: ignoring stale %s for %s\n",
|
||||
progname, makeDependfile, gn->name);
|
||||
if (!Job_RunTarget(".STALE", gn->fname))
|
||||
fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n",
|
||||
progname, gn->fname, gn->lineno, makeDependfile,
|
||||
gn->name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1381,11 +1379,13 @@ JobExec(Job *job, char **argv)
|
||||
* we can kill it and all its descendants in one fell swoop,
|
||||
* by killing its process family, but not commit suicide.
|
||||
*/
|
||||
#if defined(MAKE_NATIVE) || defined(HAVE_SETPGID)
|
||||
#if defined(SYSV) || defined(__minix)
|
||||
/* XXX: dsl - I'm sure this should be setpgrp()... */
|
||||
(void)setsid();
|
||||
#else
|
||||
(void)setpgid(0, getpid());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Var_ExportVars();
|
||||
@@ -2051,31 +2051,45 @@ Job_CatchOutput(void)
|
||||
(void)fflush(stdout);
|
||||
|
||||
/* The first fd in the list is the job token pipe */
|
||||
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
|
||||
do {
|
||||
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
|
||||
} while (nready < 0 && errno == EINTR);
|
||||
|
||||
if (nready < 0 || readyfd(&childExitJob)) {
|
||||
if (nready < 0)
|
||||
Punt("poll: %s", strerror(errno));
|
||||
|
||||
if (nready > 0 && readyfd(&childExitJob)) {
|
||||
char token = 0;
|
||||
nready -= 1;
|
||||
(void)read(childExitJob.inPipe, &token, 1);
|
||||
if (token == DO_JOB_RESUME[0])
|
||||
/* Complete relay requested from our SIGCONT handler */
|
||||
JobRestartJobs();
|
||||
Job_CatchChildren();
|
||||
ssize_t count;
|
||||
count = read(childExitJob.inPipe, &token, 1);
|
||||
switch (count) {
|
||||
case 0:
|
||||
Punt("unexpected eof on token pipe");
|
||||
case -1:
|
||||
Punt("token pipe read: %s", strerror(errno));
|
||||
case 1:
|
||||
if (token == DO_JOB_RESUME[0])
|
||||
/* Complete relay requested from our SIGCONT handler */
|
||||
JobRestartJobs();
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
--nready;
|
||||
}
|
||||
|
||||
if (nready <= 0)
|
||||
return;
|
||||
|
||||
if (wantToken && readyfd(&tokenWaitJob))
|
||||
nready--;
|
||||
Job_CatchChildren();
|
||||
if (nready == 0)
|
||||
return;
|
||||
|
||||
for (i = 2; i < nfds; i++) {
|
||||
if (!fds[i].revents)
|
||||
continue;
|
||||
job = jobfds[i];
|
||||
if (job->job_state != JOB_ST_RUNNING)
|
||||
continue;
|
||||
JobDoOutput(job, FALSE);
|
||||
if (job->job_state == JOB_ST_RUNNING)
|
||||
JobDoOutput(job, FALSE);
|
||||
if (--nready == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2123,6 +2137,24 @@ Shell_Init(void)
|
||||
if (commandShell->echo == NULL) {
|
||||
commandShell->echo = "";
|
||||
}
|
||||
if (commandShell->hasErrCtl && *commandShell->exit) {
|
||||
if (shellErrFlag &&
|
||||
strcmp(commandShell->exit, &shellErrFlag[1]) != 0) {
|
||||
free(shellErrFlag);
|
||||
shellErrFlag = NULL;
|
||||
}
|
||||
if (!shellErrFlag) {
|
||||
int n = strlen(commandShell->exit) + 2;
|
||||
|
||||
shellErrFlag = bmake_malloc(n);
|
||||
if (shellErrFlag) {
|
||||
snprintf(shellErrFlag, n, "-%s", commandShell->exit);
|
||||
}
|
||||
}
|
||||
} else if (shellErrFlag) {
|
||||
free(shellErrFlag);
|
||||
shellErrFlag = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
@@ -2166,8 +2198,7 @@ Job_SetPrefix(void)
|
||||
void
|
||||
Job_Init(void)
|
||||
{
|
||||
GNode *begin; /* node for commands to do at the very start */
|
||||
|
||||
Job_SetPrefix();
|
||||
/* Allocate space for all the job info */
|
||||
job_table = bmake_malloc(maxJobs * sizeof *job_table);
|
||||
memset(job_table, 0, maxJobs * sizeof *job_table);
|
||||
@@ -2243,15 +2274,7 @@ Job_Init(void)
|
||||
ADDSIG(SIGCONT, JobContinueSig)
|
||||
#undef ADDSIG
|
||||
|
||||
begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
|
||||
|
||||
if (begin != NULL) {
|
||||
JobRun(begin);
|
||||
if (begin->made == ERROR) {
|
||||
PrintOnError(begin, "\n\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
(void)Job_RunTarget(".BEGIN", NULL);
|
||||
postCommands = Targ_FindNode(".END", TARG_CREATE);
|
||||
}
|
||||
|
||||
@@ -2477,6 +2500,8 @@ Job_ParseShell(char *line)
|
||||
commandShell = bmake_malloc(sizeof(Shell));
|
||||
*commandShell = newShell;
|
||||
}
|
||||
/* this will take care of shellErrFlag */
|
||||
Shell_Init();
|
||||
}
|
||||
|
||||
if (commandShell->echoOn && commandShell->echoOff) {
|
||||
@@ -2787,7 +2812,8 @@ JobTokenAdd(void)
|
||||
if (DEBUG(JOB))
|
||||
fprintf(debug_file, "(%d) aborting %d, deposit token %c\n",
|
||||
getpid(), aborting, JOB_TOKENS[aborting]);
|
||||
write(tokenWaitJob.outPipe, &tok, 1);
|
||||
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-
|
||||
@@ -2808,6 +2834,8 @@ Job_ServerStart(int max_tokens, int jp_0, int jp_1)
|
||||
/* Pipe passed in from parent */
|
||||
tokenWaitJob.inPipe = jp_0;
|
||||
tokenWaitJob.outPipe = jp_1;
|
||||
(void)fcntl(jp_0, F_SETFD, 1);
|
||||
(void)fcntl(jp_1, F_SETFD, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2900,13 +2928,15 @@ Job_TokenWithdraw(void)
|
||||
while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
|
||||
continue;
|
||||
/* And put the stopper back */
|
||||
write(tokenWaitJob.outPipe, &tok, 1);
|
||||
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
|
||||
continue;
|
||||
Fatal("A failure has been detected in another branch of the parallel make");
|
||||
}
|
||||
|
||||
if (count == 1 && jobTokensRunning == 0)
|
||||
/* We didn't want the token really */
|
||||
write(tokenWaitJob.outPipe, &tok, 1);
|
||||
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
|
||||
continue;
|
||||
|
||||
jobTokensRunning++;
|
||||
if (DEBUG(JOB))
|
||||
@@ -2914,6 +2944,38 @@ Job_TokenWithdraw(void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* Job_RunTarget --
|
||||
* Run the named target if found. If a filename is specified, then
|
||||
* set that to the sources.
|
||||
*
|
||||
* Results:
|
||||
* None
|
||||
*
|
||||
* Side Effects:
|
||||
* exits if the target fails.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
Boolean
|
||||
Job_RunTarget(const char *target, const char *fname) {
|
||||
GNode *gn = Targ_FindNode(target, TARG_NOCREATE);
|
||||
|
||||
if (gn == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (fname)
|
||||
Var_Set(ALLSRC, fname, gn, 0);
|
||||
|
||||
JobRun(gn);
|
||||
if (gn->made == ERROR) {
|
||||
PrintOnError(gn, "\n\nStop.");
|
||||
exit(1);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_SELECT
|
||||
int
|
||||
emul_poll(struct pollfd *fd, int nfd, int timeout)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: job.h,v 1.40 2010/09/13 15:36:57 sjg Exp $ */
|
||||
/* $NetBSD: job.h,v 1.42 2013/07/05 22:14:56 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@@ -243,6 +243,7 @@ typedef struct Shell {
|
||||
|
||||
extern const char *shellPath;
|
||||
extern const char *shellName;
|
||||
extern char *shellErrFlag;
|
||||
|
||||
extern int jobTokensRunning; /* tokens currently "out" */
|
||||
extern int maxJobs; /* Max jobs we can run */
|
||||
@@ -268,5 +269,6 @@ void Job_TokenReturn(void);
|
||||
Boolean Job_TokenWithdraw(void);
|
||||
void Job_ServerStart(int, int, int);
|
||||
void Job_SetPrefix(void);
|
||||
Boolean Job_RunTarget(const char *, const char *);
|
||||
|
||||
#endif /* _JOB_H_ */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
|
||||
/* $NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -33,14 +33,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
|
||||
static char rcsid[] = "$NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
|
||||
__RCSID("$NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -58,6 +58,9 @@ Lst_Member(Lst l, void *d)
|
||||
List list = l;
|
||||
ListNode lNode;
|
||||
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
lNode = list->firstPtr;
|
||||
if (lNode == NULL) {
|
||||
return NULL;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $ */
|
||||
/* $NetBSD: main.c,v 1.225 2013/09/14 15:09:34 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -69,7 +69,7 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.225 2013/09/14 15:09:34 matt Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $");
|
||||
__RCSID("$NetBSD: main.c,v 1.225 2013/09/14 15:09:34 matt Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -117,19 +117,21 @@ __RCSID("$NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $");
|
||||
#include <sys/time.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef MAKE_NATIVE
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
@@ -165,6 +167,7 @@ Boolean noRecursiveExecute; /* -N flag */
|
||||
Boolean keepgoing; /* -k flag */
|
||||
Boolean queryFlag; /* -q flag */
|
||||
Boolean touchFlag; /* -t flag */
|
||||
Boolean enterFlag; /* -w flag */
|
||||
Boolean ignoreErrors; /* -i flag */
|
||||
Boolean beSilent; /* -s flag */
|
||||
Boolean oldVars; /* variable substitution style */
|
||||
@@ -176,7 +179,6 @@ Boolean varNoExportEnv; /* -X flag */
|
||||
Boolean doing_depend; /* Set while reading .depend */
|
||||
static Boolean jobsRunning; /* TRUE if the jobs might be running */
|
||||
static const char * tracefile;
|
||||
static char * Check_Cwd_av(int, char **, int);
|
||||
static void MainParseArgs(int, char **);
|
||||
static int ReadMakefile(const void *, const void *);
|
||||
static void usage(void) MAKE_ATTR_DEAD;
|
||||
@@ -187,11 +189,44 @@ char curdir[MAXPATHLEN + 1]; /* Startup directory */
|
||||
char *progname; /* the program name */
|
||||
char *makeDependfile;
|
||||
pid_t myPid;
|
||||
int makelevel;
|
||||
|
||||
Boolean forceJobs = FALSE;
|
||||
|
||||
extern Lst parseIncPath;
|
||||
|
||||
/*
|
||||
* For compatibility with the POSIX version of MAKEFLAGS that includes
|
||||
* all the options with out -, convert flags to -f -l -a -g -s.
|
||||
*/
|
||||
static char *
|
||||
explode(const char *flags)
|
||||
{
|
||||
size_t len;
|
||||
char *nf, *st;
|
||||
const char *f;
|
||||
|
||||
if (flags == NULL)
|
||||
return NULL;
|
||||
|
||||
for (f = flags; *f; f++)
|
||||
if (!isalpha((unsigned char)*f))
|
||||
break;
|
||||
|
||||
if (*f)
|
||||
return bmake_strdup(flags);
|
||||
|
||||
len = strlen(flags);
|
||||
st = nf = bmake_malloc(len * 3 + 1);
|
||||
while (*flags) {
|
||||
*nf++ = '-';
|
||||
*nf++ = *flags++;
|
||||
*nf++ = ' ';
|
||||
}
|
||||
*nf = '\0';
|
||||
return st;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_debug_options(const char *argvalue)
|
||||
{
|
||||
@@ -344,7 +379,7 @@ MainParseArgs(int argc, char **argv)
|
||||
Boolean inOption, dashDash = FALSE;
|
||||
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
|
||||
|
||||
#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst"
|
||||
#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw"
|
||||
/* Can't actually use getopt(3) because rescanning is not portable */
|
||||
|
||||
getopt_def = OPTFLAGS;
|
||||
@@ -552,6 +587,10 @@ rearg:
|
||||
touchFlag = TRUE;
|
||||
Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
|
||||
break;
|
||||
case 'w':
|
||||
enterFlag = TRUE;
|
||||
Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
|
||||
break;
|
||||
case '-':
|
||||
dashDash = TRUE;
|
||||
break;
|
||||
@@ -742,7 +781,7 @@ MakeMode(const char *mode)
|
||||
}
|
||||
#if USE_META
|
||||
if (strstr(mode, "meta"))
|
||||
meta_init(mode);
|
||||
meta_mode_init(mode);
|
||||
#endif
|
||||
}
|
||||
if (mp)
|
||||
@@ -772,7 +811,7 @@ main(int argc, char **argv)
|
||||
Lst targs; /* target nodes to create -- passed to Make_Init */
|
||||
Boolean outOfDate = FALSE; /* FALSE if all targets up to date */
|
||||
struct stat sb, sa;
|
||||
char *p1, *path, *pwd;
|
||||
char *p1, *path;
|
||||
char mdpath[MAXPATHLEN];
|
||||
const char *machine = getenv("MACHINE");
|
||||
const char *machine_arch = getenv("MACHINE_ARCH");
|
||||
@@ -783,9 +822,7 @@ main(int argc, char **argv)
|
||||
static char defsyspath[] = _PATH_DEFSYSPATH;
|
||||
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
|
||||
struct timeval rightnow; /* to initialize random seed */
|
||||
#ifdef MAKE_NATIVE
|
||||
struct utsname utsname;
|
||||
#endif
|
||||
|
||||
/* default to writing debug to stderr */
|
||||
debug_file = stderr;
|
||||
@@ -804,7 +841,7 @@ main(int argc, char **argv)
|
||||
progname++;
|
||||
else
|
||||
progname = argv[0];
|
||||
#if defined(RLIMIT_NOFILE) && !defined(__minix)
|
||||
#if !defined(__minix) && (defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)))
|
||||
/*
|
||||
* get rid of resource limit on file descriptors
|
||||
*/
|
||||
@@ -818,6 +855,12 @@ main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uname(&utsname) == -1) {
|
||||
(void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
|
||||
strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the name of this type of MACHINE from utsname
|
||||
* so we can share an executable for similar machines.
|
||||
@@ -828,11 +871,6 @@ main(int argc, char **argv)
|
||||
*/
|
||||
if (!machine) {
|
||||
#ifdef MAKE_NATIVE
|
||||
if (uname(&utsname) == -1) {
|
||||
(void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
|
||||
strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
machine = utsname.machine;
|
||||
#else
|
||||
#ifdef MAKE_MACHINE
|
||||
@@ -844,6 +882,20 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (!machine_arch) {
|
||||
#if defined(MAKE_NATIVE) && !defined(__minix)
|
||||
static char machine_arch_buf[sizeof(utsname.machine)];
|
||||
const int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
|
||||
size_t len = sizeof(machine_arch_buf);
|
||||
|
||||
if (sysctl(mib, __arraycount(mib), machine_arch_buf,
|
||||
&len, NULL, 0) < 0) {
|
||||
(void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
|
||||
strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
machine_arch = machine_arch_buf;
|
||||
#else
|
||||
#ifndef MACHINE_ARCH
|
||||
#ifdef MAKE_MACHINE_ARCH
|
||||
machine_arch = MAKE_MACHINE_ARCH;
|
||||
@@ -852,6 +904,7 @@ main(int argc, char **argv)
|
||||
#endif
|
||||
#else
|
||||
machine_arch = MACHINE_ARCH;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -862,6 +915,7 @@ main(int argc, char **argv)
|
||||
*/
|
||||
Var_Init(); /* Initialize the lists of variables for
|
||||
* parsing arguments */
|
||||
Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0);
|
||||
Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
|
||||
Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
|
||||
#ifdef MAKE_VERSION
|
||||
@@ -935,32 +989,43 @@ main(int argc, char **argv)
|
||||
Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
|
||||
Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
|
||||
Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
|
||||
/* some makefiles need to know this */
|
||||
Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMD, 0);
|
||||
|
||||
/*
|
||||
* Set some other useful macros
|
||||
*/
|
||||
{
|
||||
char tmp[64];
|
||||
const char *ep;
|
||||
char tmp[64], *ep;
|
||||
|
||||
if (!(ep = getenv(MAKE_LEVEL))) {
|
||||
ep = "0";
|
||||
}
|
||||
Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
|
||||
makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0;
|
||||
if (makelevel < 0)
|
||||
makelevel = 0;
|
||||
snprintf(tmp, sizeof(tmp), "%d", makelevel);
|
||||
Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL, 0);
|
||||
snprintf(tmp, sizeof(tmp), "%u", myPid);
|
||||
Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
|
||||
snprintf(tmp, sizeof(tmp), "%u", getppid());
|
||||
Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
|
||||
}
|
||||
Job_SetPrefix();
|
||||
if (makelevel > 0) {
|
||||
char pn[1024];
|
||||
snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel);
|
||||
progname = bmake_strdup(pn);
|
||||
}
|
||||
|
||||
#ifdef USE_META
|
||||
meta_init();
|
||||
#endif
|
||||
/*
|
||||
* First snag any flags out of the MAKE environment variable.
|
||||
* (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
|
||||
* in a different format).
|
||||
*/
|
||||
#ifdef POSIX
|
||||
Main_ParseArgLine(getenv("MAKEFLAGS"));
|
||||
p1 = explode(getenv("MAKEFLAGS"));
|
||||
Main_ParseArgLine(p1);
|
||||
free(p1);
|
||||
#else
|
||||
Main_ParseArgLine(getenv("MAKE"));
|
||||
#endif
|
||||
@@ -977,6 +1042,9 @@ main(int argc, char **argv)
|
||||
|
||||
MainParseArgs(argc, argv);
|
||||
|
||||
if (enterFlag)
|
||||
printf("%s: Entering directory `%s'\n", progname, curdir);
|
||||
|
||||
/*
|
||||
* Verify that cwd is sane.
|
||||
*/
|
||||
@@ -997,17 +1065,23 @@ main(int argc, char **argv)
|
||||
* So, to stop it breaking this case only, we ignore PWD if
|
||||
* MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
|
||||
*/
|
||||
if (!ignorePWD &&
|
||||
(pwd = getenv("PWD")) != NULL &&
|
||||
getenv("MAKEOBJDIRPREFIX") == NULL) {
|
||||
const char *makeobjdir = getenv("MAKEOBJDIR");
|
||||
#ifndef NO_PWD_OVERRIDE
|
||||
if (!ignorePWD) {
|
||||
char *pwd;
|
||||
|
||||
if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
|
||||
if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
|
||||
sa.st_dev == sb.st_dev)
|
||||
(void)strncpy(curdir, pwd, MAXPATHLEN);
|
||||
if ((pwd = getenv("PWD")) != NULL &&
|
||||
getenv("MAKEOBJDIRPREFIX") == NULL) {
|
||||
const char *makeobjdir = getenv("MAKEOBJDIR");
|
||||
|
||||
if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
|
||||
if (stat(pwd, &sb) == 0 &&
|
||||
sa.st_ino == sb.st_ino &&
|
||||
sa.st_dev == sb.st_dev)
|
||||
(void)strncpy(curdir, pwd, MAXPATHLEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
|
||||
|
||||
/*
|
||||
@@ -1165,8 +1239,6 @@ main(int argc, char **argv)
|
||||
jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
|
||||
|
||||
Main_ExportMAKEFLAGS(TRUE); /* initial export */
|
||||
|
||||
Check_Cwd_av(0, NULL, 0); /* initialize it */
|
||||
|
||||
|
||||
/*
|
||||
@@ -1295,6 +1367,9 @@ main(int argc, char **argv)
|
||||
|
||||
Trace_Log(MAKEEND, 0);
|
||||
|
||||
if (enterFlag)
|
||||
printf("%s: Leaving directory `%s'\n", progname, curdir);
|
||||
|
||||
Suff_End();
|
||||
Targ_End();
|
||||
Arch_End();
|
||||
@@ -1327,7 +1402,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
|
||||
|
||||
if (!strcmp(fname, "-")) {
|
||||
Parse_File(NULL /*stdin*/, -1);
|
||||
Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
|
||||
Var_Set("MAKEFILE", "", VAR_INTERNAL, 0);
|
||||
} else {
|
||||
/* if we've chdir'd, rebuild the path name */
|
||||
if (strcmp(curdir, objdir) && *fname != '/') {
|
||||
@@ -1376,7 +1451,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
|
||||
*/
|
||||
found:
|
||||
if (!doing_depend)
|
||||
Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
|
||||
Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0);
|
||||
Parse_File(fname, fd);
|
||||
}
|
||||
free(path);
|
||||
@@ -1384,190 +1459,6 @@ found:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
|
||||
* in situations that would not arrise with ./obj (links or not).
|
||||
* This tends to break things like:
|
||||
*
|
||||
* build:
|
||||
* ${MAKE} includes
|
||||
*
|
||||
* This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
|
||||
* opposed to an argument) in a command line and if so returns
|
||||
* ${.CURDIR} so caller can chdir() so that the assumptions made by
|
||||
* the Makefile hold true.
|
||||
*
|
||||
* If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
|
||||
*
|
||||
* The chdir() only happens in the child process, and does nothing if
|
||||
* MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
|
||||
* should not break anything. Also if NOCHECKMAKECHDIR is set we
|
||||
* do nothing - to ensure historic semantics can be retained.
|
||||
*/
|
||||
static int Check_Cwd_Off = 0;
|
||||
|
||||
static char *
|
||||
Check_Cwd_av(int ac, char **av, int copy)
|
||||
{
|
||||
static char *make[4];
|
||||
static char *cur_dir = NULL;
|
||||
char **mp;
|
||||
char *cp;
|
||||
int is_cmd, next_cmd;
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (Check_Cwd_Off) {
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "check_cwd: check is off.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (make[0] == NULL) {
|
||||
if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
|
||||
Check_Cwd_Off = 1;
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "check_cwd: turning check off.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
|
||||
if ((make[0] = strrchr(make[1], '/')) == NULL) {
|
||||
make[0] = make[1];
|
||||
make[1] = NULL;
|
||||
} else
|
||||
++make[0];
|
||||
make[2] = NULL;
|
||||
cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
|
||||
}
|
||||
if (ac == 0 || av == NULL) {
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "check_cwd: empty command.\n");
|
||||
return NULL; /* initialization only */
|
||||
}
|
||||
|
||||
if (getenv("MAKEOBJDIR") == NULL &&
|
||||
getenv("MAKEOBJDIRPREFIX") == NULL) {
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "check_cwd: no obj dirs.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
next_cmd = 1;
|
||||
for (i = 0; i < ac; ++i) {
|
||||
is_cmd = next_cmd;
|
||||
|
||||
n = strlen(av[i]);
|
||||
cp = &(av[i])[n - 1];
|
||||
if (strspn(av[i], "|&;") == (size_t)n) {
|
||||
next_cmd = 1;
|
||||
continue;
|
||||
} else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
|
||||
next_cmd = 1;
|
||||
if (copy) {
|
||||
do {
|
||||
*cp-- = '\0';
|
||||
} while (*cp == ';' || *cp == '&' || *cp == '|' ||
|
||||
*cp == ')' || *cp == '}') ;
|
||||
} else {
|
||||
/*
|
||||
* XXX this should not happen.
|
||||
*/
|
||||
fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n",
|
||||
progname, av[i]);
|
||||
}
|
||||
} else
|
||||
next_cmd = 0;
|
||||
|
||||
cp = av[i];
|
||||
if (*cp == ';' || *cp == '&' || *cp == '|')
|
||||
is_cmd = 1;
|
||||
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "av[%d] == %s '%s'",
|
||||
i, (is_cmd) ? "cmd" : "arg", av[i]);
|
||||
if (is_cmd != 0) {
|
||||
if (*cp == '(' || *cp == '{' ||
|
||||
*cp == ';' || *cp == '&' || *cp == '|') {
|
||||
do {
|
||||
++cp;
|
||||
} while (*cp == '(' || *cp == '{' ||
|
||||
*cp == ';' || *cp == '&' || *cp == '|');
|
||||
if (*cp == '\0') {
|
||||
next_cmd = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, " == cd, done.\n");
|
||||
return NULL;
|
||||
}
|
||||
for (mp = make; *mp != NULL; ++mp) {
|
||||
n = strlen(*mp);
|
||||
if (strcmp(cp, *mp) == 0) {
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, " %s == '%s', chdir(%s)\n",
|
||||
cp, *mp, cur_dir);
|
||||
return cur_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
Check_Cwd_Cmd(const char *cmd)
|
||||
{
|
||||
char *cp, *bp;
|
||||
char **av;
|
||||
int ac;
|
||||
|
||||
if (Check_Cwd_Off)
|
||||
return NULL;
|
||||
|
||||
if (cmd) {
|
||||
av = brk_string(cmd, &ac, TRUE, &bp);
|
||||
if (DEBUG(CWD))
|
||||
fprintf(debug_file, "splitting: '%s' -> %d words\n",
|
||||
cmd, ac);
|
||||
} else {
|
||||
ac = 0;
|
||||
av = NULL;
|
||||
bp = NULL;
|
||||
}
|
||||
cp = Check_Cwd_av(ac, av, 1);
|
||||
if (bp)
|
||||
free(bp);
|
||||
if (av)
|
||||
free(av);
|
||||
return cp;
|
||||
}
|
||||
|
||||
void
|
||||
Check_Cwd(const char **argv)
|
||||
{
|
||||
char *cp;
|
||||
int ac;
|
||||
|
||||
if (Check_Cwd_Off)
|
||||
return;
|
||||
|
||||
for (ac = 0; argv[ac] != NULL; ++ac)
|
||||
/* NOTHING */;
|
||||
if (ac == 3 && *argv[1] == '-') {
|
||||
cp = Check_Cwd_Cmd(argv[2]);
|
||||
} else {
|
||||
cp = Check_Cwd_av(ac, UNCONST(argv), 0);
|
||||
}
|
||||
if (cp) {
|
||||
chdir(cp);
|
||||
}
|
||||
}
|
||||
|
||||
/*-
|
||||
* Cmd_Exec --
|
||||
@@ -1849,7 +1740,7 @@ Finish(int errors)
|
||||
}
|
||||
|
||||
/*
|
||||
* enunlink --
|
||||
* eunlink --
|
||||
* Remove a file carefully, avoiding directories.
|
||||
*/
|
||||
int
|
||||
@@ -1895,7 +1786,8 @@ execError(const char *af, const char *av)
|
||||
IOADD(")\n");
|
||||
|
||||
#ifdef USE_IOVEC
|
||||
(void)writev(2, iov, 8);
|
||||
while (writev(2, iov, 8) == -1 && errno == EAGAIN)
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1906,8 +1798,12 @@ execError(const char *af, const char *av)
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
char *p;
|
||||
if ((p = strchr(progname, '[')) != NULL)
|
||||
*p = '\0';
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-BeikNnqrstWX] \n\
|
||||
"usage: %s [-BeikNnqrstWwX] \n\
|
||||
[-C directory] [-D variable] [-d flags] [-f makefile]\n\
|
||||
[-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
|
||||
[-V variable] [variable=value] [target ...]\n", progname);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: make.1,v 1.209 2012/10/08 15:09:48 christos Exp $
|
||||
.\" $NetBSD: make.1,v 1.226 2013/11/07 18:50:46 dholland Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
@@ -29,7 +29,7 @@
|
||||
.\"
|
||||
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
|
||||
.\"
|
||||
.Dd October 8, 2012
|
||||
.Dd October 25, 2013
|
||||
.Dt MAKE 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -37,7 +37,7 @@
|
||||
.Nd maintain program dependencies
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl BeikNnqrstWX
|
||||
.Op Fl BeikNnqrstWwX
|
||||
.Op Fl C Ar directory
|
||||
.Op Fl D Ar variable
|
||||
.Op Fl d Ar flags
|
||||
@@ -209,6 +209,8 @@ Force the
|
||||
option to print raw values of variables.
|
||||
.It Ar v
|
||||
Print debugging information about variable assignment.
|
||||
.It Ar w
|
||||
Print entering and leaving directory messages, pre and post processing.
|
||||
.It Ar x
|
||||
Run shell commands with
|
||||
.Fl x
|
||||
@@ -468,6 +470,50 @@ except that the effect can be limited to a single line of a script.
|
||||
A
|
||||
.Ql Ic \-
|
||||
causes any non-zero exit status of the command line to be ignored.
|
||||
.Pp
|
||||
When
|
||||
.Nm
|
||||
is run in jobs mode with
|
||||
.Fl j Ar max_jobs ,
|
||||
the entire script for the target is fed to a
|
||||
single instance of the shell.
|
||||
.Pp
|
||||
In compatibility (non-jobs) mode, each command is run in a separate process.
|
||||
If the command contains any shell meta characters
|
||||
.Pq Ql #=|^(){};&<>*?[]:$`\e\en
|
||||
it will be passed to the shell, otherwise
|
||||
.Nm
|
||||
will attempt direct execution.
|
||||
.Pp
|
||||
Since
|
||||
.Nm
|
||||
will
|
||||
.Xr chdir 2
|
||||
to
|
||||
.Ql Va .OBJDIR
|
||||
before executing any targets, each child process
|
||||
starts with that as its current working directory.
|
||||
.Pp
|
||||
Makefiles should be written so that the mode of
|
||||
.Nm
|
||||
operation does not change their behavior.
|
||||
For example, any command which needs to use
|
||||
.Dq cd
|
||||
or
|
||||
.Dq chdir ,
|
||||
without side-effect should be put in parenthesis:
|
||||
.Bd -literal -offset indent
|
||||
|
||||
avoid-chdir-side-effects:
|
||||
@echo Building $@ in `pwd`
|
||||
@(cd ${.CURDIR} && ${.MAKE} $@)
|
||||
@echo Back in `pwd`
|
||||
|
||||
ensure-one-shell-regardless-of-mode:
|
||||
@echo Building $@ in `pwd`; \\
|
||||
(cd ${.CURDIR} && ${.MAKE} $@); \\
|
||||
echo Back in `pwd`
|
||||
.Ed
|
||||
.Sh VARIABLE ASSIGNMENTS
|
||||
Variables in make are much like variables in the shell, and, by tradition,
|
||||
consist of all upper-case letters.
|
||||
@@ -699,6 +745,9 @@ then output for each target is prefixed with a token
|
||||
.Ql --- target ---
|
||||
the first part of which can be controlled via
|
||||
.Va .MAKE.JOB.PREFIX .
|
||||
If
|
||||
.Va .MAKE.JOB.PREFIX
|
||||
is empty, no token is printed.
|
||||
.br
|
||||
For example:
|
||||
.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
|
||||
@@ -812,6 +861,11 @@ In "meta" mode, this variable contains a list of all the meta files
|
||||
used (updated or not).
|
||||
This list can be used to process the meta files to extract dependency
|
||||
information.
|
||||
.It Va .MAKE.META.IGNORE_PATHS
|
||||
Provides a list of path prefixes that should be ignored;
|
||||
because the contents are expected to change over time.
|
||||
The default list includes:
|
||||
.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp
|
||||
.It Va .MAKE.META.PREFIX
|
||||
Defines the message printed for each meta file updated in "meta verbose" mode.
|
||||
The default value is:
|
||||
@@ -830,6 +884,13 @@ by appending their names to
|
||||
is re-exported whenever
|
||||
.Ql Va .MAKEOVERRIDES
|
||||
is modified.
|
||||
.It Va .MAKE.PATH_FILEMON
|
||||
If
|
||||
.Nm
|
||||
was built with
|
||||
.Xr filemon 4
|
||||
support, this is set to the path of the device node.
|
||||
This allows makefiles to test for this support.
|
||||
.It Va .MAKE.PID
|
||||
The process-id of
|
||||
.Nm .
|
||||
@@ -1005,6 +1066,13 @@ may
|
||||
be used.
|
||||
The wildcard characters may be escaped with a backslash
|
||||
.Pq Ql \e .
|
||||
As a consequence of the way values are split into words, matched,
|
||||
and then joined, a construct like
|
||||
.Dl ${VAR:M*}
|
||||
will normalise the inter-word spacing, removing all leading and
|
||||
trailing space, and converting multiple consecutive spaces
|
||||
to single spaces.
|
||||
.
|
||||
.It Cm \&:N Ns Ar pattern
|
||||
This is identical to
|
||||
.Ql Cm \&:M ,
|
||||
@@ -1148,7 +1216,7 @@ The
|
||||
modifier is just like the
|
||||
.Cm \&:S
|
||||
modifier except that the old and new strings, instead of being
|
||||
simple strings, are a regular expression (see
|
||||
simple strings, are an extended regular expression (see
|
||||
.Xr regex 3 )
|
||||
string
|
||||
.Ar pattern
|
||||
@@ -1247,7 +1315,7 @@ should start and end with a period.
|
||||
For example.
|
||||
.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
|
||||
.Pp
|
||||
However a single character varaiable is often more readable:
|
||||
However a single character variable is often more readable:
|
||||
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
|
||||
.It Cm \&:U Ns Ar newval
|
||||
If the variable is undefined
|
||||
@@ -1270,7 +1338,7 @@ The path of the node which has the same name as the variable
|
||||
is the value.
|
||||
If no such node exists or its path is null, then the
|
||||
name of the variable is used.
|
||||
In order for this modifier to work, the name (node) must at least have
|
||||
In order for this modifier to work, the name (node) must at least have
|
||||
appeared on the rhs of a dependency.
|
||||
.Sm off
|
||||
.It Cm \&:\&! Ar cmd Cm \&!
|
||||
@@ -1690,7 +1758,7 @@ or
|
||||
.Fl t
|
||||
options were specified.
|
||||
Normally used to mark recursive
|
||||
.Nm Ns 's .
|
||||
.Nm Ns s .
|
||||
.It Ic .META
|
||||
Create a meta file for the target, even if it is flagged as
|
||||
.Ic .PHONY ,
|
||||
@@ -1713,6 +1781,20 @@ targets.
|
||||
Ignore differences in commands when deciding if target is out of date.
|
||||
This is useful if the command contains a value which always changes.
|
||||
If the number of commands change, though, the target will still be out of date.
|
||||
The same effect applies to any command line that uses the variable
|
||||
.Va .OODATE ,
|
||||
which can be used for that purpose even when not otherwise needed or desired:
|
||||
.Bd -literal -offset indent
|
||||
|
||||
skip-compare-for-some:
|
||||
@echo this will be compared
|
||||
@echo this will not ${.OODATE:M.NOMETA_CMP}
|
||||
@echo this will also be compared
|
||||
|
||||
.Ed
|
||||
The
|
||||
.Cm \&:M
|
||||
pattern suppresses any expansion of the unwanted variable.
|
||||
.It Ic .NOPATH
|
||||
Do not search for the target in the directories specified by
|
||||
.Ic .PATH .
|
||||
@@ -1896,6 +1978,12 @@ If the source is the special
|
||||
.Ic .DOTLAST
|
||||
target, then the current working
|
||||
directory is searched last.
|
||||
.It Ic .PATH. Ns Va suffix
|
||||
Like
|
||||
.Ic .PATH
|
||||
but applies only to files with a particular suffix.
|
||||
The suffix must have been previously declared with
|
||||
.Ic .SUFFIXES .
|
||||
.It Ic .PHONY
|
||||
Apply the
|
||||
.Ic .PHONY
|
||||
@@ -1964,6 +2052,10 @@ If no sources are specified, the
|
||||
.Ic .SILENT
|
||||
attribute is applied to every
|
||||
command in the file.
|
||||
.It Ic .STALE
|
||||
This target gets run when a dependency file contains stale entries, having
|
||||
.Va .ALLSRC
|
||||
set to the name of that dependency file.
|
||||
.It Ic .SUFFIXES
|
||||
Each source specifies a suffix to
|
||||
.Nm .
|
||||
@@ -2027,28 +2119,6 @@ The way that .for loop variables are substituted changed after
|
||||
so that they still appear to be variable expansions.
|
||||
In particular this stops them being treated as syntax, and removes some
|
||||
obscure problems using them in .if statements.
|
||||
.Pp
|
||||
Unlike other
|
||||
.Nm
|
||||
programs, this implementation by default executes all commands for a given
|
||||
target using a single shell invocation.
|
||||
This is done for both efficiency and to simplify error handling in remote
|
||||
command invocations.
|
||||
Typically this is transparent to the user, unless the target commands change
|
||||
the current working directory using
|
||||
.Dq cd
|
||||
or
|
||||
.Dq chdir .
|
||||
To be compatible with Makefiles that do this, one can use
|
||||
.Fl B
|
||||
to disable this behavior.
|
||||
.Pp
|
||||
In compatibility mode, each command is run in a separate process.
|
||||
If the command contains any shell meta characters
|
||||
.Pq Ql #=|^(){};&<>*?[]:$`\e\en
|
||||
it will be passed to the shell, otherwise
|
||||
.Nm
|
||||
will attempt direct execution.
|
||||
.Sh SEE ALSO
|
||||
.Xr mkdep 1
|
||||
.Sh HISTORY
|
||||
@@ -2063,6 +2133,13 @@ for Sprite at Berkeley.
|
||||
It was designed to be a parallel distributed make running jobs on different
|
||||
machines using a daemon called
|
||||
.Dq customs .
|
||||
.Pp
|
||||
Historically the target/dependency
|
||||
.Dq FRC
|
||||
has been used to FoRCe rebuilding (since the target/dependency
|
||||
does not exist... unless someone creates an
|
||||
.Dq FRC
|
||||
file).
|
||||
.Sh BUGS
|
||||
The
|
||||
.Nm
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $ */
|
||||
/* $NetBSD: make.c,v 1.88 2012/11/09 18:53:05 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $";
|
||||
static char rcsid[] = "$NetBSD: make.c,v 1.88 2012/11/09 18:53:05 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $");
|
||||
__RCSID("$NetBSD: make.c,v 1.88 2012/11/09 18:53:05 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -1032,7 +1032,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
|
||||
if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
|
||||
/* Can't build this (or anything else in this child list) yet */
|
||||
cn->made = DEFERRED;
|
||||
return 1;
|
||||
return 0; /* but keep looking */
|
||||
}
|
||||
|
||||
if (DEBUG(MAKE))
|
||||
@@ -1055,7 +1055,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
|
||||
return cn->type & OP_WAIT && cn->unmade > 0;
|
||||
}
|
||||
|
||||
/* When a .ORDER RHS node completes we do this on each LHS */
|
||||
/* When a .ORDER LHS node completes we do this on each RHS */
|
||||
static int
|
||||
MakeBuildParent(void *v_pn, void *toBeMade_next)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: make.h,v 1.89 2012/06/12 19:21:51 joerg Exp $ */
|
||||
/* $NetBSD: make.h,v 1.92 2013/09/04 15:38:26 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -388,6 +388,10 @@ extern Boolean varNoExportEnv; /* TRUE if we should not export variables
|
||||
|
||||
extern GNode *DEFAULT; /* .DEFAULT rule */
|
||||
|
||||
extern GNode *VAR_INTERNAL; /* Variables defined internally by make
|
||||
* which should not override those set by
|
||||
* makefiles.
|
||||
*/
|
||||
extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
|
||||
* in the Makefile itself */
|
||||
extern GNode *VAR_CMD; /* Variables defined on the command line */
|
||||
@@ -426,6 +430,9 @@ extern pid_t myPid;
|
||||
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
|
||||
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
|
||||
#define MAKE_MODE ".MAKE.MODE"
|
||||
#ifndef MAKE_LEVEL_ENV
|
||||
# define MAKE_LEVEL_ENV "MAKELEVEL"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* debug control:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.c,v 1.25 2012/06/27 17:22:58 sjg Exp $ */
|
||||
/* $NetBSD: meta.c,v 1.33 2013/10/01 05:37:17 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Implement 'meta' mode.
|
||||
@@ -55,7 +55,12 @@
|
||||
#endif
|
||||
|
||||
static BuildMon Mybm; /* for compat */
|
||||
static Lst metaBailiwick; /* our scope of control */
|
||||
static Lst metaBailiwick; /* our scope of control */
|
||||
static Lst metaIgnorePaths; /* paths we deliberately ignore */
|
||||
|
||||
#ifndef MAKE_META_IGNORE_PATHS
|
||||
#define MAKE_META_IGNORE_PATHS ".MAKE.META.IGNORE_PATHS"
|
||||
#endif
|
||||
|
||||
Boolean useMeta = FALSE;
|
||||
static Boolean useFilemon = FALSE;
|
||||
@@ -539,8 +544,24 @@ boolValue(char *s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization we need before reading makefiles.
|
||||
*/
|
||||
void
|
||||
meta_init(const char *make_mode)
|
||||
meta_init(void)
|
||||
{
|
||||
#ifdef USE_FILEMON
|
||||
/* this allows makefiles to test if we have filemon support */
|
||||
Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialization we need after reading makefiles.
|
||||
*/
|
||||
void
|
||||
meta_mode_init(const char *make_mode)
|
||||
{
|
||||
static int once = 0;
|
||||
char *cp;
|
||||
@@ -591,6 +612,17 @@ meta_init(const char *make_mode)
|
||||
if (cp) {
|
||||
str2Lst_Append(metaBailiwick, cp, NULL);
|
||||
}
|
||||
/*
|
||||
* We ignore any paths that start with ${.MAKE.META.IGNORE_PATHS}
|
||||
*/
|
||||
metaIgnorePaths = Lst_Init(FALSE);
|
||||
Var_Append(MAKE_META_IGNORE_PATHS,
|
||||
"/dev /etc /proc /tmp /var/run /var/tmp ${TMPDIR}", VAR_GLOBAL);
|
||||
cp = Var_Subst(NULL,
|
||||
"${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL, 0);
|
||||
if (cp) {
|
||||
str2Lst_Append(metaIgnorePaths, cp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -828,6 +860,13 @@ string_match(const void *p, const void *q)
|
||||
continue; \
|
||||
}
|
||||
|
||||
#define DEQUOTE(p) if (*p == '\'') { \
|
||||
char *ep; \
|
||||
p++; \
|
||||
if ((ep = strchr(p, '\''))) \
|
||||
*ep = '\0'; \
|
||||
}
|
||||
|
||||
Boolean
|
||||
meta_oodate(GNode *gn, Boolean oodate)
|
||||
{
|
||||
@@ -840,10 +879,12 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
char fname2[MAXPATHLEN];
|
||||
char *p;
|
||||
char *cp;
|
||||
char *link_src;
|
||||
char *move_target;
|
||||
static size_t cwdlen = 0;
|
||||
static size_t tmplen = 0;
|
||||
FILE *fp;
|
||||
Boolean ignoreOODATE = FALSE;
|
||||
Boolean needOODATE = FALSE;
|
||||
Lst missingFiles;
|
||||
|
||||
if (oodate)
|
||||
@@ -906,6 +947,8 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
oodate = TRUE;
|
||||
break;
|
||||
}
|
||||
link_src = NULL;
|
||||
move_target = NULL;
|
||||
/* Find the start of the build monitor section. */
|
||||
if (!f) {
|
||||
if (strncmp(buf, "-- filemon", 10) == 0) {
|
||||
@@ -1019,16 +1062,21 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
break;
|
||||
|
||||
case 'M': /* renaMe */
|
||||
if (Lst_IsEmpty(missingFiles))
|
||||
break;
|
||||
/*
|
||||
* For 'M'oves we want to check
|
||||
* the src as for 'R'ead
|
||||
* and the target as for 'W'rite.
|
||||
*/
|
||||
cp = p; /* save this for a second */
|
||||
/* now get target */
|
||||
if (strsep(&p, " ") == NULL)
|
||||
continue;
|
||||
CHECK_VALID_META(p);
|
||||
move_target = p;
|
||||
p = cp;
|
||||
/* 'L' and 'M' put single quotes around the args */
|
||||
if (*p == '\'') {
|
||||
char *ep;
|
||||
|
||||
p++;
|
||||
if ((ep = strchr(p, '\'')))
|
||||
*ep = '\0';
|
||||
}
|
||||
DEQUOTE(p);
|
||||
DEQUOTE(move_target);
|
||||
/* FALLTHROUGH */
|
||||
case 'D': /* unlink */
|
||||
if (*p == '/' && !Lst_IsEmpty(missingFiles)) {
|
||||
@@ -1037,24 +1085,42 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
char *tp = Lst_Datum(ln);
|
||||
Lst_Remove(missingFiles, ln);
|
||||
free(tp);
|
||||
ln = NULL; /* we're done with it */
|
||||
}
|
||||
}
|
||||
if (buf[0] == 'M') {
|
||||
/* the target of the mv is a file 'W'ritten */
|
||||
#ifdef DEBUG_META_MODE
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "meta_oodate: M %s -> %s\n",
|
||||
p, move_target);
|
||||
#endif
|
||||
p = move_target;
|
||||
goto check_write;
|
||||
}
|
||||
break;
|
||||
case 'L': /* Link */
|
||||
/* we want the target */
|
||||
/*
|
||||
* For 'L'inks check
|
||||
* the src as for 'R'ead
|
||||
* and the target as for 'W'rite.
|
||||
*/
|
||||
link_src = p;
|
||||
/* now get target */
|
||||
if (strsep(&p, " ") == NULL)
|
||||
continue;
|
||||
CHECK_VALID_META(p);
|
||||
/* 'L' and 'M' put single quotes around the args */
|
||||
if (*p == '\'') {
|
||||
char *ep;
|
||||
|
||||
p++;
|
||||
if ((ep = strchr(p, '\'')))
|
||||
*ep = '\0';
|
||||
}
|
||||
DEQUOTE(p);
|
||||
DEQUOTE(link_src);
|
||||
#ifdef DEBUG_META_MODE
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "meta_oodate: L %s -> %s\n",
|
||||
link_src, p);
|
||||
#endif
|
||||
/* FALLTHROUGH */
|
||||
case 'W': /* Write */
|
||||
check_write:
|
||||
/*
|
||||
* If a file we generated within our bailiwick
|
||||
* but outside of .OBJDIR is missing,
|
||||
@@ -1086,6 +1152,14 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
Lst_AtEnd(missingFiles, bmake_strdup(p));
|
||||
}
|
||||
break;
|
||||
check_link_src:
|
||||
p = link_src;
|
||||
link_src = NULL;
|
||||
#ifdef DEBUG_META_MODE
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "meta_oodate: L src %s\n", p);
|
||||
#endif
|
||||
/* FALLTHROUGH */
|
||||
case 'R': /* Read */
|
||||
case 'E': /* Exec */
|
||||
/*
|
||||
@@ -1093,20 +1167,15 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
* be part of the dependencies because
|
||||
* they are _expected_ to change.
|
||||
*/
|
||||
if (strncmp(p, "/tmp/", 5) == 0 ||
|
||||
(tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0))
|
||||
break;
|
||||
|
||||
if (strncmp(p, "/var/", 5) == 0)
|
||||
break;
|
||||
|
||||
/* Ignore device files. */
|
||||
if (strncmp(p, "/dev/", 5) == 0)
|
||||
break;
|
||||
|
||||
/* Ignore /etc/ files. */
|
||||
if (strncmp(p, "/etc/", 5) == 0)
|
||||
if (*p == '/' &&
|
||||
Lst_ForEach(metaIgnorePaths, prefix_match, p)) {
|
||||
#ifdef DEBUG_META_MODE
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "meta_oodate: ignoring: %s\n",
|
||||
p);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if ((cp = strrchr(p, '/'))) {
|
||||
cp++;
|
||||
@@ -1185,6 +1254,8 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!oodate && buf[0] == 'L' && link_src != NULL)
|
||||
goto check_link_src;
|
||||
} else if (strcmp(buf, "CMD") == 0) {
|
||||
/*
|
||||
* Compare the current command with the one in the
|
||||
@@ -1196,17 +1267,19 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
oodate = TRUE;
|
||||
} else {
|
||||
char *cmd = (char *)Lst_Datum(ln);
|
||||
Boolean hasOODATE = FALSE;
|
||||
|
||||
if (!ignoreOODATE) {
|
||||
if (strstr(cmd, "$?"))
|
||||
ignoreOODATE = TRUE;
|
||||
else if ((cp = strstr(cmd, ".OODATE"))) {
|
||||
/* check for $[{(].OODATE[)}] */
|
||||
if (cp > cmd + 2 && cp[-2] == '$')
|
||||
ignoreOODATE = TRUE;
|
||||
}
|
||||
if (ignoreOODATE && DEBUG(META))
|
||||
fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno);
|
||||
if (strstr(cmd, "$?"))
|
||||
hasOODATE = TRUE;
|
||||
else if ((cp = strstr(cmd, ".OODATE"))) {
|
||||
/* check for $[{(].OODATE[:)}] */
|
||||
if (cp > cmd + 2 && cp[-2] == '$')
|
||||
hasOODATE = TRUE;
|
||||
}
|
||||
if (hasOODATE) {
|
||||
needOODATE = TRUE;
|
||||
if (DEBUG(META))
|
||||
fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
|
||||
}
|
||||
cmd = Var_Subst(NULL, cmd, gn, TRUE);
|
||||
|
||||
@@ -1235,7 +1308,7 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
if (buf[x - 1] == '\n')
|
||||
buf[x - 1] = '\0';
|
||||
}
|
||||
if (!ignoreOODATE &&
|
||||
if (!hasOODATE &&
|
||||
!(gn->type & OP_NOMETA_CMP) &&
|
||||
strcmp(p, cmd) != 0) {
|
||||
if (DEBUG(META))
|
||||
@@ -1279,14 +1352,16 @@ meta_oodate(GNode *gn, Boolean oodate)
|
||||
oodate = TRUE;
|
||||
}
|
||||
}
|
||||
if (oodate && ignoreOODATE) {
|
||||
if (oodate && needOODATE) {
|
||||
/*
|
||||
* Target uses .OODATE, so we need to re-compute it.
|
||||
* We need to clean up what Make_DoAllVar() did.
|
||||
* Target uses .OODATE which is empty; or we wouldn't be here.
|
||||
* We have decided it is oodate, so .OODATE needs to be set.
|
||||
* All we can sanely do is set it to .ALLSRC.
|
||||
*/
|
||||
Var_Delete(ALLSRC, gn);
|
||||
Var_Delete(OODATE, gn);
|
||||
gn->flags &= ~DONE_ALLSRC;
|
||||
Var_Set(OODATE, Var_Value(ALLSRC, gn, &cp), gn, 0);
|
||||
if (cp)
|
||||
free(cp);
|
||||
}
|
||||
return oodate;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: meta.h,v 1.2 2011/03/30 22:03:49 sjg Exp $ */
|
||||
/* $NetBSD: meta.h,v 1.3 2013/03/23 05:31:29 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Things needed for 'meta' mode.
|
||||
@@ -41,7 +41,8 @@ typedef struct BuildMon {
|
||||
extern Boolean useMeta;
|
||||
|
||||
struct Job; /* not defined yet */
|
||||
void meta_init(const char *);
|
||||
void meta_init(void);
|
||||
void meta_mode_init(const char *);
|
||||
void meta_job_start(struct Job *, GNode *);
|
||||
void meta_job_child(struct Job *);
|
||||
void meta_job_error(struct Job *, GNode *, int, int);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $ */
|
||||
/* $NetBSD: parse.c,v 1.192 2013/10/18 20:47:06 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -68,22 +68,15 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __minix
|
||||
#ifndef MAP_COPY
|
||||
#define MAP_COPY MAP_PRIVATE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $";
|
||||
static char rcsid[] = "$NetBSD: parse.c,v 1.192 2013/10/18 20:47:06 christos Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
|
||||
__RCSID("$NetBSD: parse.c,v 1.192 2013/10/18 20:47:06 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -140,6 +133,9 @@ __RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif
|
||||
#ifndef MAP_COPY
|
||||
#define MAP_COPY MAP_PRIVATE
|
||||
#endif
|
||||
@@ -158,7 +154,7 @@ __RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
|
||||
* Structure for a file being read ("included file")
|
||||
*/
|
||||
typedef struct IFile {
|
||||
const char *fname; /* name of file */
|
||||
char *fname; /* name of file */
|
||||
int lineno; /* current line number in file */
|
||||
int first_lineno; /* line number of start of text */
|
||||
int cond_depth; /* 'if' nesting when file opened */
|
||||
@@ -214,6 +210,7 @@ typedef enum {
|
||||
ExShell, /* .SHELL */
|
||||
Silent, /* .SILENT */
|
||||
SingleShell, /* .SINGLESHELL */
|
||||
Stale, /* .STALE */
|
||||
Suffixes, /* .SUFFIXES */
|
||||
Wait, /* .WAIT */
|
||||
Attribute /* Generic attribute */
|
||||
@@ -337,6 +334,7 @@ static const struct {
|
||||
{ ".SHELL", ExShell, 0 },
|
||||
{ ".SILENT", Silent, OP_SILENT },
|
||||
{ ".SINGLESHELL", SingleShell, 0 },
|
||||
{ ".STALE", Stale, 0 },
|
||||
{ ".SUFFIXES", Suffixes, 0 },
|
||||
{ ".USE", Attribute, OP_USE },
|
||||
{ ".USEBEFORE", Attribute, OP_USEBEFORE },
|
||||
@@ -521,7 +519,6 @@ loadfile(const char *path, int fd)
|
||||
* FUTURE: remove PROT_WRITE when the parser no longer
|
||||
* needs to scribble on the input.
|
||||
*/
|
||||
|
||||
lf->buf = mmap(NULL, lf->maplen, PROT_READ|PROT_WRITE,
|
||||
MAP_FILE|MAP_COPY, fd, 0);
|
||||
if (lf->buf != MAP_FAILED) {
|
||||
@@ -910,6 +907,8 @@ ParseDoOp(void *gnp, void *opp)
|
||||
gn->type |= op & ~OP_OPMASK;
|
||||
|
||||
cohort = Targ_FindNode(gn->name, TARG_NOHASH);
|
||||
if (doing_depend)
|
||||
ParseMark(cohort);
|
||||
/*
|
||||
* Make the cohort invisible as well to avoid duplicating it into
|
||||
* other variables. True, parents of this target won't tend to do
|
||||
@@ -982,6 +981,8 @@ ParseDoSrc(int tOp, const char *src)
|
||||
*/
|
||||
snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
|
||||
gn = Targ_FindNode(wait_src, TARG_NOHASH);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
|
||||
Lst_ForEach(targets, ParseLinkSrc, gn);
|
||||
return;
|
||||
@@ -1013,6 +1014,8 @@ ParseDoSrc(int tOp, const char *src)
|
||||
* source and the current one.
|
||||
*/
|
||||
gn = Targ_FindNode(src, TARG_CREATE);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
if (predecessor != NULL) {
|
||||
(void)Lst_AtEnd(predecessor->order_succ, gn);
|
||||
(void)Lst_AtEnd(gn->order_pred, predecessor);
|
||||
@@ -1044,6 +1047,8 @@ ParseDoSrc(int tOp, const char *src)
|
||||
|
||||
/* Find/create the 'src' node and attach to all targets */
|
||||
gn = Targ_FindNode(src, TARG_CREATE);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
if (tOp) {
|
||||
gn->type |= tOp;
|
||||
} else {
|
||||
@@ -1201,9 +1206,8 @@ ParseDoDependency(char *line)
|
||||
*/
|
||||
int length;
|
||||
void *freeIt;
|
||||
char *result;
|
||||
|
||||
result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
|
||||
(void)Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
|
||||
if (freeIt)
|
||||
free(freeIt);
|
||||
cp += length-1;
|
||||
@@ -1289,6 +1293,7 @@ ParseDoDependency(char *line)
|
||||
* apply the .DEFAULT commands.
|
||||
* .PHONY The list of targets
|
||||
* .NOPATH Don't search for file in the path
|
||||
* .STALE
|
||||
* .BEGIN
|
||||
* .END
|
||||
* .ERROR
|
||||
@@ -1299,42 +1304,45 @@ ParseDoDependency(char *line)
|
||||
* .ORDER Must set initial predecessor to NULL
|
||||
*/
|
||||
switch (specType) {
|
||||
case ExPath:
|
||||
if (paths == NULL) {
|
||||
paths = Lst_Init(FALSE);
|
||||
}
|
||||
(void)Lst_AtEnd(paths, dirSearchPath);
|
||||
break;
|
||||
case Main:
|
||||
if (!Lst_IsEmpty(create)) {
|
||||
specType = Not;
|
||||
}
|
||||
break;
|
||||
case Begin:
|
||||
case End:
|
||||
case dotError:
|
||||
case Interrupt:
|
||||
gn = Targ_FindNode(line, TARG_CREATE);
|
||||
gn->type |= OP_NOTMAIN|OP_SPECIAL;
|
||||
(void)Lst_AtEnd(targets, gn);
|
||||
break;
|
||||
case Default:
|
||||
gn = Targ_NewGN(".DEFAULT");
|
||||
gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
|
||||
(void)Lst_AtEnd(targets, gn);
|
||||
DEFAULT = gn;
|
||||
break;
|
||||
case NotParallel:
|
||||
maxJobs = 1;
|
||||
break;
|
||||
case SingleShell:
|
||||
compatMake = TRUE;
|
||||
break;
|
||||
case Order:
|
||||
predecessor = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case ExPath:
|
||||
if (paths == NULL) {
|
||||
paths = Lst_Init(FALSE);
|
||||
}
|
||||
(void)Lst_AtEnd(paths, dirSearchPath);
|
||||
break;
|
||||
case Main:
|
||||
if (!Lst_IsEmpty(create)) {
|
||||
specType = Not;
|
||||
}
|
||||
break;
|
||||
case Begin:
|
||||
case End:
|
||||
case Stale:
|
||||
case dotError:
|
||||
case Interrupt:
|
||||
gn = Targ_FindNode(line, TARG_CREATE);
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
gn->type |= OP_NOTMAIN|OP_SPECIAL;
|
||||
(void)Lst_AtEnd(targets, gn);
|
||||
break;
|
||||
case Default:
|
||||
gn = Targ_NewGN(".DEFAULT");
|
||||
gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
|
||||
(void)Lst_AtEnd(targets, gn);
|
||||
DEFAULT = gn;
|
||||
break;
|
||||
case NotParallel:
|
||||
maxJobs = 1;
|
||||
break;
|
||||
case SingleShell:
|
||||
compatMake = TRUE;
|
||||
break;
|
||||
case Order:
|
||||
predecessor = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (strncmp(line, ".PATH", 5) == 0) {
|
||||
/*
|
||||
@@ -1393,6 +1401,8 @@ ParseDoDependency(char *line)
|
||||
} else {
|
||||
gn = Suff_AddTransform(targName);
|
||||
}
|
||||
if (doing_depend)
|
||||
ParseMark(gn);
|
||||
|
||||
(void)Lst_AtEnd(targets, gn);
|
||||
}
|
||||
@@ -1440,6 +1450,7 @@ ParseDoDependency(char *line)
|
||||
Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
|
||||
break;
|
||||
case Default:
|
||||
case Stale:
|
||||
case Begin:
|
||||
case End:
|
||||
case dotError:
|
||||
@@ -1729,6 +1740,12 @@ Parse_IsVar(char *line)
|
||||
ch = *line++;
|
||||
wasSpace = TRUE;
|
||||
}
|
||||
#ifdef SUNSHCMD
|
||||
if (ch == ':' && strncmp(line, "sh", 2) == 0) {
|
||||
line += 2;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (ch == '=')
|
||||
return TRUE;
|
||||
if (*line == '=' && ISEQOPERATOR(ch))
|
||||
@@ -2322,7 +2339,7 @@ Parse_SetInput(const char *name, int line, int fd,
|
||||
* name of the include file so error messages refer to the right
|
||||
* place.
|
||||
*/
|
||||
curFile->fname = name;
|
||||
curFile->fname = bmake_strdup(name);
|
||||
curFile->lineno = line;
|
||||
curFile->first_lineno = line;
|
||||
curFile->nextbuf = nextbuf;
|
||||
@@ -2335,6 +2352,8 @@ Parse_SetInput(const char *name, int line, int fd,
|
||||
buf = curFile->nextbuf(curFile->nextbuf_arg, &len);
|
||||
if (buf == NULL) {
|
||||
/* Was all a waste of time ... */
|
||||
if (curFile->fname)
|
||||
free(curFile->fname);
|
||||
free(curFile);
|
||||
return;
|
||||
}
|
||||
@@ -2449,6 +2468,7 @@ ParseGmakeExport(char *line)
|
||||
"Variable/Value missing from \"export\"");
|
||||
return;
|
||||
}
|
||||
*value++ = '\0'; /* terminate variable */
|
||||
|
||||
/*
|
||||
* Expand the value before putting it in the environment.
|
||||
@@ -2557,6 +2577,16 @@ ParseGetLine(int flags, int *length)
|
||||
if (cf->P_end == NULL)
|
||||
/* End of string (aka for loop) data */
|
||||
break;
|
||||
/* see if there is more we can parse */
|
||||
while (ptr++ < cf->P_end) {
|
||||
if ((ch = *ptr) == '\n') {
|
||||
if (ptr > line && ptr[-1] == '\\')
|
||||
continue;
|
||||
Parse_Error(PARSE_WARNING,
|
||||
"Zero byte read from file, skipping rest of line.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cf->nextbuf != NULL) {
|
||||
/*
|
||||
* End of this buffer; return EOF and outer logic
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $ */
|
||||
/* $NetBSD: suff.c,v 1.70 2013/05/18 13:13:34 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: suff.c,v 1.70 2013/05/18 13:13:34 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $");
|
||||
__RCSID("$NetBSD: suff.c,v 1.70 2013/05/18 13:13:34 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -684,8 +684,8 @@ GNode *
|
||||
Suff_AddTransform(char *line)
|
||||
{
|
||||
GNode *gn; /* GNode of transformation rule */
|
||||
Suff *s = NULL, /* source suffix */
|
||||
*t = NULL; /* target suffix */
|
||||
Suff *s, /* source suffix */
|
||||
*t; /* target suffix */
|
||||
LstNode ln; /* Node for existing transformation */
|
||||
|
||||
ln = Lst_Find(transforms, line, SuffGNHasNameP);
|
||||
@@ -2058,118 +2058,124 @@ SuffFindNormalDeps(GNode *gn, Lst slst)
|
||||
* children, then look for any overriding transformations they imply.
|
||||
* Should we find one, we discard the one we found before.
|
||||
*/
|
||||
bottom = NULL;
|
||||
targ = NULL;
|
||||
|
||||
while (ln != NULL) {
|
||||
/*
|
||||
* Look for next possible suffix...
|
||||
*/
|
||||
ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
|
||||
|
||||
if (ln != NULL) {
|
||||
int prefLen; /* Length of the prefix */
|
||||
if (!(gn->type & OP_PHONY)) {
|
||||
|
||||
while (ln != NULL) {
|
||||
/*
|
||||
* Allocate a Src structure to which things can be transformed
|
||||
* Look for next possible suffix...
|
||||
*/
|
||||
ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
|
||||
|
||||
if (ln != NULL) {
|
||||
int prefLen; /* Length of the prefix */
|
||||
|
||||
/*
|
||||
* Allocate a Src structure to which things can be transformed
|
||||
*/
|
||||
targ = bmake_malloc(sizeof(Src));
|
||||
targ->file = bmake_strdup(gn->name);
|
||||
targ->suff = (Suff *)Lst_Datum(ln);
|
||||
targ->suff->refCount++;
|
||||
targ->node = gn;
|
||||
targ->parent = NULL;
|
||||
targ->children = 0;
|
||||
#ifdef DEBUG_SRC
|
||||
targ->cp = Lst_Init(FALSE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate room for the prefix, whose end is found by
|
||||
* subtracting the length of the suffix from
|
||||
* the end of the name.
|
||||
*/
|
||||
prefLen = (eoname - targ->suff->nameLen) - sopref;
|
||||
targ->pref = bmake_malloc(prefLen + 1);
|
||||
memcpy(targ->pref, sopref, prefLen);
|
||||
targ->pref[prefLen] = '\0';
|
||||
|
||||
/*
|
||||
* Add nodes from which the target can be made
|
||||
*/
|
||||
SuffAddLevel(srcs, targ);
|
||||
|
||||
/*
|
||||
* Record the target so we can nuke it
|
||||
*/
|
||||
(void)Lst_AtEnd(targs, targ);
|
||||
|
||||
/*
|
||||
* Search from this suffix's successor...
|
||||
*/
|
||||
ln = Lst_Succ(ln);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle target of unknown suffix...
|
||||
*/
|
||||
if (Lst_IsEmpty(targs) && suffNull != NULL) {
|
||||
if (DEBUG(SUFF)) {
|
||||
fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
|
||||
}
|
||||
|
||||
targ = bmake_malloc(sizeof(Src));
|
||||
targ->file = bmake_strdup(gn->name);
|
||||
targ->suff = (Suff *)Lst_Datum(ln);
|
||||
targ->suff = suffNull;
|
||||
targ->suff->refCount++;
|
||||
targ->node = gn;
|
||||
targ->parent = NULL;
|
||||
targ->children = 0;
|
||||
targ->pref = bmake_strdup(sopref);
|
||||
#ifdef DEBUG_SRC
|
||||
targ->cp = Lst_Init(FALSE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate room for the prefix, whose end is found by subtracting
|
||||
* the length of the suffix from the end of the name.
|
||||
* Only use the default suffix rules if we don't have commands
|
||||
* defined for this gnode; traditional make programs used to
|
||||
* not define suffix rules if the gnode had children but we
|
||||
* don't do this anymore.
|
||||
*/
|
||||
prefLen = (eoname - targ->suff->nameLen) - sopref;
|
||||
targ->pref = bmake_malloc(prefLen + 1);
|
||||
memcpy(targ->pref, sopref, prefLen);
|
||||
targ->pref[prefLen] = '\0';
|
||||
if (Lst_IsEmpty(gn->commands))
|
||||
SuffAddLevel(srcs, targ);
|
||||
else {
|
||||
if (DEBUG(SUFF))
|
||||
fprintf(debug_file, "not ");
|
||||
}
|
||||
|
||||
/*
|
||||
* Add nodes from which the target can be made
|
||||
*/
|
||||
SuffAddLevel(srcs, targ);
|
||||
|
||||
/*
|
||||
* Record the target so we can nuke it
|
||||
*/
|
||||
(void)Lst_AtEnd(targs, targ);
|
||||
|
||||
/*
|
||||
* Search from this suffix's successor...
|
||||
*/
|
||||
ln = Lst_Succ(ln);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle target of unknown suffix...
|
||||
*/
|
||||
if (Lst_IsEmpty(targs) && suffNull != NULL) {
|
||||
if (DEBUG(SUFF)) {
|
||||
fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
|
||||
}
|
||||
|
||||
targ = bmake_malloc(sizeof(Src));
|
||||
targ->file = bmake_strdup(gn->name);
|
||||
targ->suff = suffNull;
|
||||
targ->suff->refCount++;
|
||||
targ->node = gn;
|
||||
targ->parent = NULL;
|
||||
targ->children = 0;
|
||||
targ->pref = bmake_strdup(sopref);
|
||||
#ifdef DEBUG_SRC
|
||||
targ->cp = Lst_Init(FALSE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Only use the default suffix rules if we don't have commands
|
||||
* defined for this gnode; traditional make programs used to
|
||||
* not define suffix rules if the gnode had children but we
|
||||
* don't do this anymore.
|
||||
*/
|
||||
if (Lst_IsEmpty(gn->commands))
|
||||
SuffAddLevel(srcs, targ);
|
||||
else {
|
||||
if (DEBUG(SUFF))
|
||||
fprintf(debug_file, "not ");
|
||||
fprintf(debug_file, "adding suffix rules\n");
|
||||
|
||||
(void)Lst_AtEnd(targs, targ);
|
||||
}
|
||||
|
||||
if (DEBUG(SUFF))
|
||||
fprintf(debug_file, "adding suffix rules\n");
|
||||
|
||||
(void)Lst_AtEnd(targs, targ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Using the list of possible sources built up from the target suffix(es),
|
||||
* try and find an existing file/target that matches.
|
||||
*/
|
||||
bottom = SuffFindThem(srcs, slst);
|
||||
|
||||
if (bottom == NULL) {
|
||||
/*
|
||||
* No known transformations -- use the first suffix found for setting
|
||||
* the local variables.
|
||||
* Using the list of possible sources built up from the target
|
||||
* suffix(es), try and find an existing file/target that matches.
|
||||
*/
|
||||
if (!Lst_IsEmpty(targs)) {
|
||||
targ = (Src *)Lst_Datum(Lst_First(targs));
|
||||
bottom = SuffFindThem(srcs, slst);
|
||||
|
||||
if (bottom == NULL) {
|
||||
/*
|
||||
* No known transformations -- use the first suffix found
|
||||
* for setting the local variables.
|
||||
*/
|
||||
if (!Lst_IsEmpty(targs)) {
|
||||
targ = (Src *)Lst_Datum(Lst_First(targs));
|
||||
} else {
|
||||
targ = NULL;
|
||||
}
|
||||
} else {
|
||||
targ = NULL;
|
||||
/*
|
||||
* Work up the transformation path to find the suffix of the
|
||||
* target to which the transformation was made.
|
||||
*/
|
||||
for (targ = bottom; targ->parent != NULL; targ = targ->parent)
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Work up the transformation path to find the suffix of the
|
||||
* target to which the transformation was made.
|
||||
*/
|
||||
for (targ = bottom; targ->parent != NULL; targ = targ->parent)
|
||||
continue;
|
||||
}
|
||||
|
||||
Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
|
||||
@@ -2419,12 +2425,7 @@ SuffFindDeps(GNode *gn, Lst slst)
|
||||
*/
|
||||
Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
|
||||
Var_Set(PREFIX, gn->name, gn, 0);
|
||||
if (gn->type & OP_PHONY) {
|
||||
/*
|
||||
* If this is a .PHONY target, we do not apply suffix rules.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG(SUFF)) {
|
||||
fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.34 2012/06/19 23:25:53 sjg Exp $
|
||||
# $NetBSD: Makefile,v 1.38 2013/08/28 21:56:50 sjg Exp $
|
||||
#
|
||||
# Unit tests for make(1)
|
||||
# The main targets are:
|
||||
@@ -24,6 +24,7 @@ SUBFILES= \
|
||||
error \
|
||||
export \
|
||||
export-all \
|
||||
export-env \
|
||||
doterror \
|
||||
dotwait \
|
||||
forloop \
|
||||
@@ -36,9 +37,11 @@ SUBFILES= \
|
||||
modorder \
|
||||
modts \
|
||||
modword \
|
||||
order \
|
||||
phony-end \
|
||||
posix \
|
||||
qequals \
|
||||
sunshcmd \
|
||||
sysv \
|
||||
ternary \
|
||||
unexport \
|
||||
@@ -48,6 +51,7 @@ SUBFILES= \
|
||||
all: ${SUBFILES}
|
||||
|
||||
flags.doterror=
|
||||
flags.order=-j1
|
||||
|
||||
# the tests are actually done with sub-makes.
|
||||
.PHONY: ${SUBFILES}
|
||||
@@ -76,7 +80,7 @@ LANG= C
|
||||
test:
|
||||
@echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
|
||||
@cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
|
||||
${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \
|
||||
${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[^:]*:,make:,' \
|
||||
-e '/stopped/s, /.*, unit-tests,' \
|
||||
-e 's,${.CURDIR:C/\./\\\./g}/,,g' \
|
||||
-e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \
|
||||
|
||||
24
usr.bin/make/unit-tests/export-env
Normal file
24
usr.bin/make/unit-tests/export-env
Normal file
@@ -0,0 +1,24 @@
|
||||
# $Id: export-env,v 1.1 2013/03/22 16:36:46 sjg Exp $
|
||||
|
||||
# our normal .export, subsequent changes affect the environment
|
||||
UT_TEST=this
|
||||
.export UT_TEST
|
||||
UT_TEST:= ${.PARSEFILE}
|
||||
|
||||
# not so with .export-env
|
||||
UT_ENV=exported
|
||||
.export-env UT_ENV
|
||||
UT_ENV=not-exported
|
||||
|
||||
# gmake style export goes further; affects nothing but the environment
|
||||
UT_EXP=before-export
|
||||
export UT_EXP=exported
|
||||
UT_EXP=not-exported
|
||||
|
||||
all:
|
||||
@echo make:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=${$v};@}
|
||||
@echo env:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=$${$v};@}
|
||||
|
||||
|
||||
|
||||
|
||||
20
usr.bin/make/unit-tests/order
Normal file
20
usr.bin/make/unit-tests/order
Normal file
@@ -0,0 +1,20 @@
|
||||
# $NetBSD: order,v 1.1 2012/11/09 19:08:28 sjg Exp $
|
||||
|
||||
# Test that .ORDER is handled correctly.
|
||||
# The explicit dependency the.o: the.h will make us examine the.h
|
||||
# the .ORDER will prevent us building it immediately,
|
||||
# we should then examine the.c rather than stop.
|
||||
|
||||
all: the.o
|
||||
|
||||
.ORDER: the.c the.h
|
||||
|
||||
the.c the.h:
|
||||
@echo Making $@
|
||||
|
||||
.SUFFIXES: .o .c
|
||||
|
||||
.c.o:
|
||||
@echo Making $@ from $?
|
||||
|
||||
the.o: the.h
|
||||
10
usr.bin/make/unit-tests/sunshcmd
Normal file
10
usr.bin/make/unit-tests/sunshcmd
Normal file
@@ -0,0 +1,10 @@
|
||||
BYECMD = echo bye
|
||||
LATERCMD = echo later
|
||||
TEST1 :sh = echo hello
|
||||
TEST2 :sh = ${BYECMD}
|
||||
TEST3 = ${LATERCMD:sh}
|
||||
|
||||
all:
|
||||
@echo "TEST1=${TEST1}"
|
||||
@echo "TEST2=${TEST2}"
|
||||
@echo "TEST3=${TEST3}"
|
||||
@@ -43,6 +43,14 @@ UT_OK=good
|
||||
UT_OKDIR=unit-tests
|
||||
UT_TEST=export-all
|
||||
UT_ZOO=hoopie
|
||||
make:
|
||||
UT_TEST=export-env
|
||||
UT_ENV=not-exported
|
||||
UT_EXP=not-exported
|
||||
env:
|
||||
UT_TEST=export-env
|
||||
UT_ENV=exported
|
||||
UT_EXP=exported
|
||||
At first, I am
|
||||
happy
|
||||
and now: sad
|
||||
@@ -310,6 +318,9 @@ LIST:tw:C/ /,/g="one two three four five six"
|
||||
LIST:tw:C/ /,/1g="one two three four five six"
|
||||
LIST:tw:tW:C/ /,/="one,two three four five six"
|
||||
LIST:tW:tw:C/ /,/="one two three four five six"
|
||||
Making the.c
|
||||
Making the.h
|
||||
Making the.o from the.h the.c
|
||||
.TARGET="phony" .PREFIX="phony" .IMPSRC=""
|
||||
.TARGET="all" .PREFIX="all" .IMPSRC=""
|
||||
.TARGET="ok" .PREFIX="ok" .IMPSRC=""
|
||||
@@ -338,6 +349,9 @@ Now we expect an error...
|
||||
*** Error code 1 (continuing)
|
||||
`all' not remade because of errors.
|
||||
V.i386 ?= OK
|
||||
TEST1=hello
|
||||
TEST2=bye
|
||||
TEST3=later
|
||||
FOOBAR =
|
||||
FOOBAR = foobar fubar
|
||||
fun
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
/* $NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $ */
|
||||
/* $NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $ */
|
||||
|
||||
/*
|
||||
* Missing stuff from OS's
|
||||
*/
|
||||
#if defined(__MINT__) || defined(__linux__)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $";
|
||||
static char rcsid[] = "$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $");
|
||||
__RCSID("$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $ */
|
||||
/* $NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1993
|
||||
@@ -69,14 +69,14 @@
|
||||
*/
|
||||
|
||||
#ifndef MAKE_NATIVE
|
||||
static char rcsid[] = "$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $";
|
||||
static char rcsid[] = "$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $";
|
||||
#else
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $");
|
||||
__RCSID("$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
#endif
|
||||
@@ -139,6 +139,7 @@ __RCSID("$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $");
|
||||
#include "dir.h"
|
||||
#include "job.h"
|
||||
|
||||
extern int makelevel;
|
||||
/*
|
||||
* This lets us tell if we have replaced the original environ
|
||||
* (which we cannot free).
|
||||
@@ -175,6 +176,7 @@ static char varNoError[] = "";
|
||||
* The four contexts are searched in the reverse order from which they are
|
||||
* listed.
|
||||
*/
|
||||
GNode *VAR_INTERNAL; /* variables from make itself */
|
||||
GNode *VAR_GLOBAL; /* variables from the makefile */
|
||||
GNode *VAR_CMD; /* variables defined on the command-line */
|
||||
|
||||
@@ -309,7 +311,6 @@ static char *VarGetPattern(GNode *, Var_Parse_State *,
|
||||
int, const char **, int, int *, int *,
|
||||
VarPattern *);
|
||||
static char *VarQuote(char *);
|
||||
static char *VarChangeCase(char *, int);
|
||||
static char *VarHash(char *);
|
||||
static char *VarModify(GNode *, Var_Parse_State *,
|
||||
const char *,
|
||||
@@ -408,6 +409,10 @@ VarFind(const char *name, GNode *ctxt, int flags)
|
||||
(ctxt != VAR_GLOBAL))
|
||||
{
|
||||
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
|
||||
if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
|
||||
/* VAR_INTERNAL is subordinate to VAR_GLOBAL */
|
||||
var = Hash_FindEntry(&VAR_INTERNAL->context, name);
|
||||
}
|
||||
}
|
||||
if ((var == NULL) && (flags & FIND_ENV)) {
|
||||
char *env;
|
||||
@@ -429,6 +434,9 @@ VarFind(const char *name, GNode *ctxt, int flags)
|
||||
(ctxt != VAR_GLOBAL))
|
||||
{
|
||||
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
|
||||
if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
|
||||
var = Hash_FindEntry(&VAR_INTERNAL->context, name);
|
||||
}
|
||||
if (var == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
@@ -530,11 +538,20 @@ void
|
||||
Var_Delete(const char *name, GNode *ctxt)
|
||||
{
|
||||
Hash_Entry *ln;
|
||||
|
||||
ln = Hash_FindEntry(&ctxt->context, name);
|
||||
char *cp;
|
||||
|
||||
if (strchr(name, '$')) {
|
||||
cp = Var_Subst(NULL, name, VAR_GLOBAL, 0);
|
||||
} else {
|
||||
cp = (char *)name;
|
||||
}
|
||||
ln = Hash_FindEntry(&ctxt->context, cp);
|
||||
if (DEBUG(VAR)) {
|
||||
fprintf(debug_file, "%s:delete %s%s\n",
|
||||
ctxt->name, name, ln ? "" : " (not found)");
|
||||
ctxt->name, cp, ln ? "" : " (not found)");
|
||||
}
|
||||
if (cp != name) {
|
||||
free(cp);
|
||||
}
|
||||
if (ln != NULL) {
|
||||
Var *v;
|
||||
@@ -649,6 +666,15 @@ Var_ExportVars(void)
|
||||
char *val;
|
||||
int n;
|
||||
|
||||
/*
|
||||
* Several make's support this sort of mechanism for tracking
|
||||
* recursion - but each uses a different name.
|
||||
* We allow the makefiles to update MAKELEVEL and ensure
|
||||
* children see a correctly incremented value.
|
||||
*/
|
||||
snprintf(tmp, sizeof(tmp), "%d", makelevel + 1);
|
||||
setenv(MAKE_LEVEL_ENV, tmp, 1);
|
||||
|
||||
if (VAR_EXPORTED_NONE == var_exportedVars)
|
||||
return;
|
||||
|
||||
@@ -770,7 +796,7 @@ Var_UnExport(char *str)
|
||||
if (unexport_env) {
|
||||
char **newenv;
|
||||
|
||||
cp = getenv(MAKE_LEVEL); /* we should preserve this */
|
||||
cp = getenv(MAKE_LEVEL_ENV); /* we should preserve this */
|
||||
if (environ == savedEnv) {
|
||||
/* we have been here before! */
|
||||
newenv = bmake_realloc(environ, 2 * sizeof(char *));
|
||||
@@ -787,7 +813,7 @@ Var_UnExport(char *str)
|
||||
environ = savedEnv = newenv;
|
||||
newenv[0] = NULL;
|
||||
newenv[1] = NULL;
|
||||
setenv(MAKE_LEVEL, cp, 1);
|
||||
setenv(MAKE_LEVEL_ENV, cp, 1);
|
||||
} else {
|
||||
for (; *str != '\n' && isspace((unsigned char) *str); str++)
|
||||
continue;
|
||||
@@ -911,6 +937,14 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
|
||||
}
|
||||
v = VarFind(name, ctxt, 0);
|
||||
if (v == NULL) {
|
||||
if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
|
||||
/*
|
||||
* This var would normally prevent the same name being added
|
||||
* to VAR_GLOBAL, so delete it from there if needed.
|
||||
* Otherwise -V name may show the wrong value.
|
||||
*/
|
||||
Var_Delete(name, VAR_GLOBAL);
|
||||
}
|
||||
VarAdd(name, val, ctxt);
|
||||
} else {
|
||||
Buf_Empty(&v->val);
|
||||
@@ -945,22 +979,6 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
|
||||
|
||||
Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
|
||||
}
|
||||
/*
|
||||
* Another special case.
|
||||
* Several make's support this sort of mechanism for tracking
|
||||
* recursion - but each uses a different name.
|
||||
* We allow the makefiles to update .MAKE.LEVEL and ensure
|
||||
* children see a correctly incremented value.
|
||||
*/
|
||||
if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) {
|
||||
char tmp[64];
|
||||
int level;
|
||||
|
||||
level = atoi(val);
|
||||
snprintf(tmp, sizeof(tmp), "%u", level + 1);
|
||||
setenv(MAKE_LEVEL, tmp, 1);
|
||||
}
|
||||
|
||||
|
||||
out:
|
||||
if (expanded_name != NULL)
|
||||
@@ -2296,9 +2314,7 @@ VarHash(char *str)
|
||||
size_t len, len2;
|
||||
unsigned char *ustr = (unsigned char *)str;
|
||||
uint32_t h, k, c1, c2;
|
||||
int done;
|
||||
|
||||
done = 1;
|
||||
h = 0x971e137bU;
|
||||
c1 = 0x95543787U;
|
||||
c2 = 0x2ad7eb25U;
|
||||
@@ -2328,7 +2344,7 @@ VarHash(char *str)
|
||||
h = (h << 13) ^ (h >> 19);
|
||||
h = h * 5 + 0x52dce729U;
|
||||
h ^= k;
|
||||
} while (!done);
|
||||
}
|
||||
h ^= len2;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
@@ -2344,37 +2360,6 @@ VarHash(char *str)
|
||||
return Buf_Destroy(&buf, FALSE);
|
||||
}
|
||||
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* VarChangeCase --
|
||||
* Change the string to all uppercase or all lowercase
|
||||
*
|
||||
* Input:
|
||||
* str String to modify
|
||||
* upper TRUE -> uppercase, else lowercase
|
||||
*
|
||||
* Results:
|
||||
* The string with case changed
|
||||
*
|
||||
* Side Effects:
|
||||
* None.
|
||||
*
|
||||
*-----------------------------------------------------------------------
|
||||
*/
|
||||
static char *
|
||||
VarChangeCase(char *str, int upper)
|
||||
{
|
||||
Buffer buf;
|
||||
int (*modProc)(int);
|
||||
|
||||
modProc = (upper ? toupper : tolower);
|
||||
Buf_Init(&buf, 0);
|
||||
for (; *str ; str++) {
|
||||
Buf_AddByte(&buf, modProc(*str));
|
||||
}
|
||||
return Buf_Destroy(&buf, FALSE);
|
||||
}
|
||||
|
||||
static char *
|
||||
VarStrftime(const char *fmt, int zulu)
|
||||
{
|
||||
@@ -2561,7 +2546,8 @@ ApplyModifiers(char *nstr, const char *tstr,
|
||||
}
|
||||
apply_mods:
|
||||
if (DEBUG(VAR)) {
|
||||
fprintf(debug_file, "Applying :%c to \"%s\"\n", *tstr, nstr);
|
||||
fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", v->name,
|
||||
*tstr, nstr);
|
||||
}
|
||||
newStr = var_Error;
|
||||
switch ((modifier = *tstr)) {
|
||||
@@ -3050,8 +3036,16 @@ ApplyModifiers(char *nstr, const char *tstr,
|
||||
VarRealpath, NULL);
|
||||
cp = tstr + 2;
|
||||
termc = *cp;
|
||||
} else if (tstr[1] == 'u' || tstr[1] == 'l') {
|
||||
newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
|
||||
} else if (tstr[1] == 'u') {
|
||||
char *dp = bmake_strdup(nstr);
|
||||
for (newStr = dp; *dp; dp++)
|
||||
*dp = toupper((unsigned char)*dp);
|
||||
cp = tstr + 2;
|
||||
termc = *cp;
|
||||
} else if (tstr[1] == 'l') {
|
||||
char *dp = bmake_strdup(nstr);
|
||||
for (newStr = dp; *dp; dp++)
|
||||
*dp = tolower((unsigned char)*dp);
|
||||
cp = tstr + 2;
|
||||
termc = *cp;
|
||||
} else if (tstr[1] == 'W' || tstr[1] == 'w') {
|
||||
@@ -3161,8 +3155,8 @@ ApplyModifiers(char *nstr, const char *tstr,
|
||||
free(cp2);
|
||||
}
|
||||
if (DEBUG(VAR))
|
||||
fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr,
|
||||
pattern);
|
||||
fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
|
||||
v->name, nstr, pattern);
|
||||
if (*tstr == 'M') {
|
||||
newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
|
||||
pattern);
|
||||
@@ -3517,7 +3511,8 @@ ApplyModifiers(char *nstr, const char *tstr,
|
||||
}
|
||||
}
|
||||
if (DEBUG(VAR)) {
|
||||
fprintf(debug_file, "Result of :%c is \"%s\"\n", modifier, newStr);
|
||||
fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
|
||||
v->name, modifier, newStr);
|
||||
}
|
||||
|
||||
if (newStr != nstr) {
|
||||
@@ -4150,6 +4145,7 @@ Var_GetHead(char *file)
|
||||
void
|
||||
Var_Init(void)
|
||||
{
|
||||
VAR_INTERNAL = Targ_NewGN("Internal");
|
||||
VAR_GLOBAL = Targ_NewGN("Global");
|
||||
VAR_CMD = Targ_NewGN("Command");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user