.error "message"
.warning "message"
	based on FreeBSD implementation.
	add .info while were at it.

.ERROR:	a target to run on error.
	We pass the failing GNode to PrintOnError so it can set
	.ERROR_TARGET.

.MAKE.MAKEFILE_PREFERENCE
	As a means to control make's list of prefered makefile names.
	(Default: "makefile Makefile")

.MAKE.DEPENDFILE
	Names the file to read dependencies from
	(Default ".depend")

.MAKE.MODE
	Processed after all makefiles are read.
	Can put make into "compat" mode (more to come).

Fix:

compat.c: Error code should not be sent to debug_file.
Make_DoAllVar: use DONE_ALLSRC to avoid processing a node multiple times.
ReadMakefile: we can simply use doing_depend to control setting MAKEFILE.
This commit is contained in:
sjg 2010-04-07 00:11:27 +00:00
parent 66aa934e53
commit b6e2a6c85f
8 changed files with 212 additions and 43 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $ */
/* $NetBSD: compat.c,v 1.77 2010/04/07 00:11:27 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.76 2009/02/22 07:33:00 dholland Exp $";
static char rcsid[] = "$NetBSD: compat.c,v 1.77 2010/04/07 00:11:27 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.76 2009/02/22 07:33:00 dholland Exp $");
__RCSID("$NetBSD: compat.c,v 1.77 2010/04/07 00:11:27 sjg Exp $");
#endif
#endif /* not lint */
#endif
@ -407,7 +407,7 @@ again:
}
fprintf(debug_file, "\n");
}
fprintf(debug_file, "*** Error code %d", status);
printf("*** Error code %d", status);
}
} else {
status = WTERMSIG(reason); /* signaled */
@ -574,7 +574,7 @@ Compat_Make(void *gnp, void *pgnp)
} else if (keepgoing) {
pgn->flags &= ~REMAKE;
} else {
PrintOnError("\n\nStop.");
PrintOnError(gn, "\n\nStop.");
exit(1);
}
} else if (gn->made == ERROR) {
@ -665,7 +665,7 @@ Compat_Run(Lst targs)
if (gn != NULL) {
Compat_Make(gn, gn);
if (gn->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(gn, "\n\nStop.");
exit(1);
}
}
@ -706,7 +706,7 @@ Compat_Run(Lst targs)
if (errors == 0) {
Compat_Make(ENDNode, ENDNode);
if (gn->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(gn, "\n\nStop.");
exit(1);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.146 2009/06/26 01:26:32 sjg Exp $ */
/* $NetBSD: job.c,v 1.147 2010/04/07 00:11:27 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.146 2009/06/26 01:26:32 sjg Exp $";
static char rcsid[] = "$NetBSD: job.c,v 1.147 2010/04/07 00:11:27 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.146 2009/06/26 01:26:32 sjg Exp $");
__RCSID("$NetBSD: job.c,v 1.147 2010/04/07 00:11:27 sjg Exp $");
#endif
#endif /* not lint */
#endif
@ -1225,8 +1225,8 @@ 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 .depend for %s\n",
progname, gn->name);
fprintf(stdout, "%s: ignoring stale %s for %s\n",
progname, makeDependfile, gn->name);
return TRUE;
}
@ -1897,7 +1897,7 @@ JobRun(GNode *targ)
#else
Compat_Make(targ, targ);
if (targ->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(targ, "\n\nStop.");
exit(1);
}
#endif
@ -2227,7 +2227,7 @@ Job_Init(void)
if (begin != NULL) {
JobRun(begin);
if (begin->made == ERROR) {
PrintOnError("\n\nStop.");
PrintOnError(begin, "\n\nStop.");
exit(1);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.175 2010/01/04 17:05:25 sjg Exp $ */
/* $NetBSD: main.c,v 1.176 2010/04/07 00:11:27 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: main.c,v 1.175 2010/01/04 17:05:25 sjg Exp $";
static char rcsid[] = "$NetBSD: main.c,v 1.176 2010/04/07 00:11:27 sjg 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.175 2010/01/04 17:05:25 sjg Exp $");
__RCSID("$NetBSD: main.c,v 1.176 2010/04/07 00:11:27 sjg Exp $");
#endif
#endif /* not lint */
#endif
@ -184,6 +184,7 @@ static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
static char curdir[MAXPATHLEN + 1]; /* startup directory */
static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
char *progname; /* the program name */
char *makeDependfile;
Boolean forceJobs = FALSE;
@ -680,6 +681,22 @@ ReadAllMakefiles(const void *p, const void *q)
return (ReadMakefile(p, q) == 0);
}
static int
str2Lst_Append(Lst lp, char *str, const char *sep)
{
char *cp;
int n;
if (!sep)
sep = " \t";
for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
(void)Lst_AtEnd(lp, cp);
n++;
}
return (n);
}
#ifdef SIGINFO
/*ARGSUSED*/
static void
@ -696,6 +713,27 @@ siginfo(int signo)
}
#endif
/*
* Allow makefiles some control over the mode we run in.
*/
void
MakeMode(const char *mode)
{
char *mp = NULL;
if (!mode)
mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0);
if (mode && *mode) {
if (strstr(mode, "compat")) {
compatMake = TRUE;
forceJobs = FALSE;
}
}
if (mp)
free(mp);
}
/*-
* main --
* The main function, for obvious reasons. Initializes variables
@ -813,6 +851,15 @@ main(int argc, char **argv)
Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0);
#endif
Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */
/*
* This is the traditional preference for makefiles.
*/
#ifndef MAKEFILE_PREFERENCE_LIST
# define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
#endif
Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
VAR_GLOBAL, 0);
Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL, 0);
create = Lst_Init(FALSE);
makefiles = Lst_Init(FALSE);
@ -1051,16 +1098,27 @@ main(int argc, char **argv)
if (ln != NULL)
Fatal("%s: cannot open %s.", progname,
(char *)Lst_Datum(ln));
} else if (ReadMakefile("makefile", NULL) != 0)
(void)ReadMakefile("Makefile", NULL);
} else {
p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
VAR_CMD, 0);
if (p1) {
(void)str2Lst_Append(makefiles, p1, NULL);
(void)Lst_Find(makefiles, NULL, ReadMakefile);
free(p1);
}
}
/* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
if (!noBuiltins || !printVars) {
doing_depend = TRUE;
(void)ReadMakefile(".depend", NULL);
doing_depend = FALSE;
makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
VAR_CMD, 0);
doing_depend = TRUE;
(void)ReadMakefile(makeDependfile, NULL);
doing_depend = FALSE;
}
MakeMode(NULL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
if (p1)
free(p1);
@ -1219,14 +1277,11 @@ ReadMakefile(const void *p, const void *q __unused)
int fd;
size_t len = MAXPATHLEN;
char *name, *path = bmake_malloc(len);
int setMAKEFILE;
if (!strcmp(fname, "-")) {
Parse_File("(stdin)", dup(fileno(stdin)));
Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
} else {
setMAKEFILE = strcmp(fname, ".depend");
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
size_t plen = strlen(curdir) + strlen(fname) + 2;
@ -1273,7 +1328,7 @@ ReadMakefile(const void *p, const void *q __unused)
* makefile specified, as it is set by SysV make.
*/
found:
if (setMAKEFILE)
if (!doing_depend)
Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
Parse_File(fname, fd);
}
@ -1666,7 +1721,7 @@ Fatal(const char *fmt, ...)
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
PrintOnError(NULL);
PrintOnError(NULL, NULL);
if (DEBUG(GRAPH2) || DEBUG(GRAPH3))
Targ_PrintGraph(2);
@ -1698,7 +1753,7 @@ Punt(const char *fmt, ...)
(void)fprintf(stderr, "\n");
(void)fflush(stderr);
PrintOnError(NULL);
PrintOnError(NULL, NULL);
DieHorribly();
}
@ -1819,15 +1874,32 @@ PrintAddr(void *a, void *b)
void
PrintOnError(const char *s)
PrintOnError(GNode *gn, const char *s)
{
GNode *en;
char tmp[64];
char *cp;
if (s)
printf("%s", s);
printf("%s", s);
printf("\n%s: stopped in %s\n", progname, curdir);
if (gn) {
/*
* We can print this even if there is no .ERROR target.
*/
Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL, 0);
}
/*
* See if there is a .ERROR target, and run it if so.
*/
en = Targ_FindNode(".ERROR", TARG_NOCREATE);
if (en) {
en->type |= OP_SPECIAL;
Compat_Make(en, en);
}
strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
sizeof(tmp) - 1);
cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.167 2010/02/22 19:20:33 joerg Exp $
.\" $NetBSD: make.1,v 1.168 2010/04/07 00:11:27 sjg 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 November 15, 2009
.Dd April 6, 2010
.Dt MAKE 1
.Os
.Sh NAME
@ -652,14 +652,34 @@ The preferred variable to use is the environment variable
because it is more compatible with other versions of
.Nm
and cannot be confused with the special target with the same name.
.It Va .MAKE.DEPENDFILE
Names the makefile (default
.Ql Pa .depend )
from which generated dependencies are read.
.It Va .MAKE.EXPORTED
The list of variables exported by
.Nm .
.It Va .MAKE.MAKEFILE_PREFERENCE
The ordered list of makefile names
(default
.Ql Pa makefile ,
.Ql Pa Makefile )
that
.Nm
will look for.
.It Va .MAKE.MAKEFILES
The list of makefiles read by
.Nm ,
which is useful for tracking dependencies.
Each makefile is recorded only once, regardless of the number of times read.
.It Va .MAKE.MODE
Processed after reading all makefiles.
Can affect the mode that
.Nm
runs in.
Currently just
.Ql Pa compat
mode.
.It Va .MAKE.LEVEL
The recursion depth of
.Nm .
@ -1274,6 +1294,11 @@ Conditional expressions are also preceded by a single dot as the first
character of a line.
The possible conditionals are as follows:
.Bl -tag -width Ds
.It Ic .error Ar message
The message is printed along with the name of the makefile and line number,
then
.Nm
will exit.
.It Ic .export Ar variable ...
Export the specified global variable.
If no variable list is provided, all globals are exported
@ -1286,6 +1311,8 @@ flag, so should be used with caution.
Appending a variable name to
.Va .MAKE.EXPORTED
is equivalent to exporting a variable.
.It Ic .info Ar message
The message is printed along with the name of the makefile and line number.
.It Ic .unexport Ar variable ...
The opposite of
.Ql .export .
@ -1325,6 +1352,10 @@ will also be pushed into the new environment.
.It Ic .undef Ar variable
Un-define the specified global variable.
Only global variables may be un-defined.
.It Ic .warning Ar message
The message prefixed by
.Ql Pa warning:
is printed along with the name of the makefile and line number.
.It Ic \&.if Oo \&! Oc Ns Ar expression Op Ar operator expression ...
Test the value of an expression.
.It Ic .ifdef Oo \&! Oc Ns Ar variable Op Ar operator variable ...
@ -1627,6 +1658,13 @@ to the target's own name.
.It Ic .END
Any command lines attached to this target are executed after everything
else is done.
.It Ic .ERROR
Any command lines attached to this target are executed when another target fails.
The
.Ic .ERROR_TARGET
variable is set to the target that failed.
See also
.Ic MAKE_PRINT_VAR_ON_ERROR .
.It Ic .IGNORE
Mark each of the sources with the
.Ic .IGNORE

View File

@ -1,4 +1,4 @@
/* $NetBSD: make.c,v 1.78 2009/01/23 21:26:30 dsl Exp $ */
/* $NetBSD: make.c,v 1.79 2010/04/07 00:11:27 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: make.c,v 1.78 2009/01/23 21:26:30 dsl Exp $";
static char rcsid[] = "$NetBSD: make.c,v 1.79 2010/04/07 00:11:27 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.78 2009/01/23 21:26:30 dsl Exp $");
__RCSID("$NetBSD: make.c,v 1.79 2010/04/07 00:11:27 sjg Exp $");
#endif
#endif /* not lint */
#endif
@ -958,6 +958,9 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
void
Make_DoAllVar(GNode *gn)
{
if (gn->flags & DONE_ALLSRC)
return;
Lst_ForEach(gn->children, MakeUnmark, gn);
Lst_ForEach(gn->children, MakeAddAllSrc, gn);
@ -974,6 +977,7 @@ Make_DoAllVar(GNode *gn)
if (p1)
free(p1);
}
gn->flags |= DONE_ALLSRC;
}
/*-

View File

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.79 2009/09/08 17:29:20 sjg Exp $ */
/* $NetBSD: make.h,v 1.80 2010/04/07 00:11:27 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -164,6 +164,7 @@ typedef struct GNode {
#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */
#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */
#define FROM_DEPEND 0x20 /* Node created from .depend */
#define DONE_ALLSRC 0x40 /* We do it once only */
#define CYCLE 0x1000 /* Used by MakePrintStatus */
#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
enum enum_made {
@ -392,6 +393,7 @@ extern Lst sysIncPath; /* The system include path. */
extern Lst defIncPath; /* The default include path. */
extern char *progname; /* The program name */
extern char *makeDependfile; /* .depend */
#define MAKEFLAGS ".MAKEFLAGS"
#define MAKEOVERRIDES ".MAKEOVERRIDES"
@ -399,6 +401,9 @@ extern char *progname; /* The program name */
#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
#define MAKE_MODE ".MAKE.MODE"
/*
* debug control:
@ -442,7 +447,7 @@ void Make_DoAllVar(GNode *);
Boolean Make_Run(Lst);
char * Check_Cwd_Cmd(const char *);
void Check_Cwd(const char **);
void PrintOnError(const char *);
void PrintOnError(GNode *, const char *);
void Main_ExportMAKEFLAGS(Boolean);
Boolean Main_SetObjdir(const char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nonints.h,v 1.57 2009/11/19 00:30:24 sjg Exp $ */
/* $NetBSD: nonints.h,v 1.58 2010/04/07 00:11:27 sjg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@ -108,6 +108,7 @@ void For_Run(int);
/* main.c */
void Main_ParseArgLine(const char *);
void MakeMode(const char *);
int main(int, char **);
char *Cmd_Exec(const char *, const char **);
void Error(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.160 2009/11/19 00:30:25 sjg Exp $ */
/* $NetBSD: parse.c,v 1.161 2010/04/07 00:11:27 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: parse.c,v 1.160 2009/11/19 00:30:25 sjg Exp $";
static char rcsid[] = "$NetBSD: parse.c,v 1.161 2010/04/07 00:11:27 sjg 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.160 2009/11/19 00:30:25 sjg Exp $");
__RCSID("$NetBSD: parse.c,v 1.161 2010/04/07 00:11:27 sjg Exp $");
#endif
#endif /* not lint */
#endif
@ -497,6 +497,50 @@ Parse_Error(int type, const char *fmt, ...)
}
}
/*
* ParseMessage
* Parse a .info .warning or .error directive
*
* The input is the line minus the ".". We substitute
* variables, print the message and exit(1) (for .error) or just print
* a warning if the directive is malformed.
*/
static void
ParseMessage(char *line)
{
int mtype;
switch(*line) {
case 'i':
mtype = 0;
break;
case 'w':
mtype = PARSE_WARNING;
break;
case 'e':
mtype = PARSE_FATAL;
break;
default:
Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line);
return;
}
while (!isspace((u_char)*line))
line++;
while (isspace((u_char)*line))
line++;
line = Var_Subst(NULL, line, VAR_CMD, 0);
Parse_Error(mtype, "%s", line);
free(line);
if (mtype == PARSE_FATAL) {
/* Terminate immediately. */
exit(1);
}
}
/*-
*---------------------------------------------------------------------
* ParseLinkSrc --
@ -2513,7 +2557,12 @@ Parse_File(const char *name, int fd)
} else if (strncmp(cp, "unexport", 8) == 0) {
Var_UnExport(cp);
continue;
}
} else if (strncmp(cp, "info", 4) == 0 ||
strncmp(cp, "error", 5) == 0 ||
strncmp(cp, "warning", 7) == 0) {
ParseMessage(cp);
continue;
}
}
if (*line == '\t') {
@ -2661,7 +2710,7 @@ Parse_File(const char *name, int fd)
(void)fprintf(stderr,
"%s: Fatal errors encountered -- cannot continue\n",
progname);
PrintOnError(NULL);
PrintOnError(NULL, NULL);
exit(1);
}
}