Fix detection and reporting of dependency loops in parallel makes.

make's unit_tests should now run again.
This commit is contained in:
dsl 2006-12-20 20:46:35 +00:00
parent f60d1114d3
commit c26f3a4858
3 changed files with 37 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: make.c,v 1.69 2006/12/18 15:06:16 christos Exp $ */
/* $NetBSD: make.c,v 1.70 2006/12/20 20:46:35 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: make.c,v 1.69 2006/12/18 15:06:16 christos Exp $";
static char rcsid[] = "$NetBSD: make.c,v 1.70 2006/12/20 20:46:35 dsl 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.69 2006/12/18 15:06:16 christos Exp $");
__RCSID("$NetBSD: make.c,v 1.70 2006/12/20 20:46:35 dsl Exp $");
#endif
#endif /* not lint */
#endif
@ -120,6 +120,7 @@ __RCSID("$NetBSD: make.c,v 1.69 2006/12/18 15:06:16 christos Exp $");
#include "dir.h"
#include "job.h"
static unsigned int checked = 1;/* Sequence # to detect recursion */
static Lst toBeMade; /* The current fringe of the graph. These
* are nodes which await examination by
* MakeOODate. It is added to by
@ -678,6 +679,9 @@ Make_Update(GNode *cgn)
Lst parents;
GNode *centurion;
/* It is save to re-examine any nodes again */
checked++;
cname = Var_Value(TARGET, cgn, &p1);
if (p1)
free(p1);
@ -1078,6 +1082,15 @@ MakeStartJobs(void)
make_abort(gn, __LINE__);
}
if (gn->checked == checked) {
/* We've already looked at this node since a job finished... */
if (DEBUG(MAKE))
fprintf(debug_file, "alreadey checked %s%s\n",
gn->name, gn->cohort_num);
continue;
}
gn->checked = checked;
if (gn->unmade != 0) {
/*
* We can't build this yet, add all unmade children to toBeMade,
@ -1218,29 +1231,27 @@ MakePrintStatus(ClientData gnp, ClientData v_errors)
gn->name, gn->cohort_num, gn->unmade);
/*
* If printing cycles and came to one that has unmade children,
* print out the cycle by recursing on its children. Note a
* cycle like:
* a : b
* b : c
* c : b
* will cause this to erroneously complain about a being in
* the cycle, but this is a good approximation.
* print out the cycle by recursing on its children.
*/
if (gn->flags & CYCLE) {
Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);
gn->flags |= ENDCYCLE | ONCYCLE;
/* This will hit all the cycle... */
Lst_ForEach(gn->children, MakePrintStatus, errors);
if ((*errors)++ > 1000)
return 1;
gn->flags &= ~(CYCLE | ENDCYCLE);
} else if (!(gn->flags & ENDCYCLE)) {
if (!(gn->flags & CYCLE)) {
/* Fist time we've seen this node, check all children */
gn->flags |= CYCLE;
Lst_ForEach(gn->children, MakePrintStatus, errors);
/* Mark that this node needn't be processed again */
gn->flags |= DONECYCLE;
return 0;
}
return (0);
/* Only output the error once per node */
gn->flags |= DONECYCLE;
Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);
if ((*errors)++ > 100)
/* Abandon the whole error report */
return 1;
/* Reporting for our children will give the rest of the loop */
Lst_ForEach(gn->children, MakePrintStatus, errors);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.65 2006/12/04 21:34:47 dsl Exp $ */
/* $NetBSD: make.h,v 1.66 2006/12/20 20:46:35 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -163,9 +163,7 @@ typedef struct GNode {
#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */
#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */
#define CYCLE 0x1000 /* Used by MakePrintStatus */
#define ENDCYCLE 0x2000 /* Used by MakePrintStatus */
#define ONCYCLE 0x4000 /* Used by MakePrintStatus */
#define DONECYCLE 0x8000 /* Used by MakePrintStatus */
#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
enum enum_made {
UNMADE, DEFERRED, REQUESTED, BEINGMADE,
MADE, UPTODATE, ERROR, ABORTED
@ -202,6 +200,7 @@ typedef struct GNode {
cohorts list */
struct GNode *centurion; /* Pointer to the first instance of a ::
node; only set when on a cohorts list */
unsigned int checked; /* Last time we tried to makle this node */
Hash_Table context; /* The local variables */
Lst commands; /* Creation commands */

View File

@ -1,4 +1,4 @@
/* $NetBSD: targ.c,v 1.47 2006/12/18 15:06:16 christos Exp $ */
/* $NetBSD: targ.c,v 1.48 2006/12/20 20:46:35 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: targ.c,v 1.47 2006/12/18 15:06:16 christos Exp $";
static char rcsid[] = "$NetBSD: targ.c,v 1.48 2006/12/20 20:46:35 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
#else
__RCSID("$NetBSD: targ.c,v 1.47 2006/12/18 15:06:16 christos Exp $");
__RCSID("$NetBSD: targ.c,v 1.48 2006/12/20 20:46:35 dsl Exp $");
#endif
#endif /* not lint */
#endif
@ -609,7 +609,6 @@ made_name(enum enum_made made)
case UPTODATE: return "up-to-date";
case ERROR: return "error when made";
case ABORTED: return "aborted";
case ENDCYCLE: return "end cycle";
default: return "unknown enum_made value";
}
}