2003-09-30 17:47:42 +00:00
|
|
|
#include "mk.h"
|
|
|
|
|
|
|
|
int runerrs;
|
|
|
|
|
|
|
|
void
|
|
|
|
mk(char *target)
|
|
|
|
{
|
|
|
|
Node *node;
|
|
|
|
int did = 0;
|
|
|
|
|
|
|
|
nproc(); /* it can be updated dynamically */
|
|
|
|
nrep(); /* it can be updated dynamically */
|
|
|
|
runerrs = 0;
|
|
|
|
node = graph(target);
|
|
|
|
if(DEBUG(D_GRAPH)){
|
|
|
|
dumpn("new target\n", node);
|
|
|
|
Bflush(&bout);
|
|
|
|
}
|
|
|
|
clrmade(node);
|
|
|
|
while(node->flags&NOTMADE){
|
|
|
|
if(work(node, (Node *)0, (Arc *)0))
|
|
|
|
did = 1; /* found something to do */
|
|
|
|
else {
|
|
|
|
if(waitup(1, (int *)0) > 0){
|
|
|
|
if(node->flags&(NOTMADE|BEINGMADE)){
|
|
|
|
assert("must be run errors", runerrs);
|
|
|
|
break; /* nothing more waiting */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(node->flags&BEINGMADE)
|
|
|
|
waitup(-1, (int *)0);
|
|
|
|
while(jobs)
|
|
|
|
waitup(-2, (int *)0);
|
|
|
|
assert("target didn't get done", runerrs || (node->flags&MADE));
|
|
|
|
if(did == 0)
|
|
|
|
Bprint(&bout, "mk: '%s' is up to date\n", node->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
clrmade(Node *n)
|
|
|
|
{
|
|
|
|
Arc *a;
|
|
|
|
|
|
|
|
n->flags &= ~(CANPRETEND|PRETENDING);
|
|
|
|
if(strchr(n->name, '(') ==0 || n->time)
|
|
|
|
n->flags |= CANPRETEND;
|
|
|
|
MADESET(n, NOTMADE);
|
|
|
|
for(a = n->prereqs; a; a = a->next)
|
|
|
|
if(a->n)
|
|
|
|
clrmade(a->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
unpretend(Node *n)
|
|
|
|
{
|
|
|
|
MADESET(n, NOTMADE);
|
|
|
|
n->flags &= ~(CANPRETEND|PRETENDING);
|
|
|
|
n->time = 0;
|
|
|
|
}
|
|
|
|
|
2003-11-23 17:48:53 +00:00
|
|
|
static char*
|
|
|
|
dir(void)
|
|
|
|
{
|
|
|
|
static char buf[1024];
|
|
|
|
|
|
|
|
return getcwd(buf, sizeof buf);
|
|
|
|
}
|
|
|
|
|
2003-09-30 17:47:42 +00:00
|
|
|
int
|
|
|
|
work(Node *node, Node *p, Arc *parc)
|
|
|
|
{
|
|
|
|
Arc *a, *ra;
|
|
|
|
int weoutofdate;
|
|
|
|
int ready;
|
|
|
|
int did = 0;
|
|
|
|
|
|
|
|
/*print("work(%s) flags=0x%x time=%ld\n", node->name, node->flags, node->time);*//**/
|
|
|
|
if(node->flags&BEINGMADE)
|
|
|
|
return(did);
|
|
|
|
if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){
|
|
|
|
if(explain)
|
|
|
|
fprint(1, "unpretending %s(%ld) because %s is out of date(%ld)\n",
|
|
|
|
node->name, node->time, p->name, p->time);
|
|
|
|
unpretend(node);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
have a look if we are pretending in case
|
|
|
|
someone has been unpretended out from underneath us
|
|
|
|
*/
|
|
|
|
if(node->flags&MADE){
|
|
|
|
if(node->flags&PRETENDING){
|
|
|
|
node->time = 0;
|
|
|
|
}else
|
|
|
|
return(did);
|
|
|
|
}
|
|
|
|
/* consider no prerequsite case */
|
|
|
|
if(node->prereqs == 0){
|
|
|
|
if(node->time == 0){
|
2003-11-23 17:48:53 +00:00
|
|
|
fprint(2, "mk: don't know how to make '%s' in %s\n", node->name, dir());
|
2003-09-30 17:47:42 +00:00
|
|
|
if(kflag){
|
|
|
|
node->flags |= BEINGMADE;
|
|
|
|
runerrs++;
|
|
|
|
} else
|
|
|
|
Exit();
|
|
|
|
} else
|
|
|
|
MADESET(node, MADE);
|
|
|
|
return(did);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
now see if we are out of date or what
|
|
|
|
*/
|
|
|
|
ready = 1;
|
|
|
|
weoutofdate = aflag;
|
|
|
|
ra = 0;
|
|
|
|
for(a = node->prereqs; a; a = a->next)
|
|
|
|
if(a->n){
|
|
|
|
did = work(a->n, node, a) || did;
|
|
|
|
if(a->n->flags&(NOTMADE|BEINGMADE))
|
|
|
|
ready = 0;
|
|
|
|
if(outofdate(node, a, 0)){
|
|
|
|
weoutofdate = 1;
|
|
|
|
if((ra == 0) || (ra->n == 0)
|
|
|
|
|| (ra->n->time < a->n->time))
|
|
|
|
ra = a;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(node->time == 0){
|
|
|
|
if(ra == 0)
|
|
|
|
ra = a;
|
|
|
|
weoutofdate = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(ready == 0) /* can't do anything now */
|
|
|
|
return(did);
|
|
|
|
if(weoutofdate == 0){
|
|
|
|
MADESET(node, MADE);
|
|
|
|
return(did);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
can we pretend to be made?
|
|
|
|
*/
|
|
|
|
if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND))
|
|
|
|
&& p && ra->n && !outofdate(p, ra, 0)){
|
|
|
|
node->flags &= ~CANPRETEND;
|
|
|
|
MADESET(node, MADE);
|
|
|
|
if(explain && ((node->flags&PRETENDING) == 0))
|
|
|
|
fprint(1, "pretending %s has time %ld\n", node->name, node->time);
|
|
|
|
node->flags |= PRETENDING;
|
|
|
|
return(did);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
node is out of date and we REALLY do have to do something.
|
|
|
|
quickly rescan for pretenders
|
|
|
|
*/
|
|
|
|
for(a = node->prereqs; a; a = a->next)
|
|
|
|
if(a->n && (a->n->flags&PRETENDING)){
|
|
|
|
if(explain)
|
|
|
|
Bprint(&bout, "unpretending %s because of %s because of %s\n",
|
|
|
|
a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites");
|
|
|
|
|
|
|
|
unpretend(a->n);
|
|
|
|
did = work(a->n, node, a) || did;
|
|
|
|
ready = 0;
|
|
|
|
}
|
|
|
|
if(ready == 0) /* try later unless nothing has happened for -k's sake */
|
|
|
|
return(did || work(node, p, parc));
|
|
|
|
did = dorecipe(node) || did;
|
|
|
|
return(did);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
update(int fake, Node *node)
|
|
|
|
{
|
|
|
|
Arc *a;
|
|
|
|
|
|
|
|
MADESET(node, fake? BEINGMADE : MADE);
|
|
|
|
if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){
|
|
|
|
node->time = timeof(node->name, 1);
|
|
|
|
node->flags &= ~(CANPRETEND|PRETENDING);
|
|
|
|
for(a = node->prereqs; a; a = a->next)
|
|
|
|
if(a->prog)
|
|
|
|
outofdate(node, a, 1);
|
|
|
|
} else {
|
|
|
|
node->time = 1;
|
|
|
|
for(a = node->prereqs; a; a = a->next)
|
|
|
|
if(a->n && outofdate(node, a, 1))
|
|
|
|
node->time = a->n->time;
|
|
|
|
}
|
|
|
|
/* print("----node %s time=%ld flags=0x%x\n", node->name, node->time, node->flags);*//**/
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
pcmp(char *prog, char *p, char *q)
|
|
|
|
{
|
|
|
|
char buf[3*NAMEBLOCK];
|
|
|
|
int pid;
|
|
|
|
|
|
|
|
Bflush(&bout);
|
|
|
|
sprint(buf, "%s '%s' '%s'\n", prog, p, q);
|
|
|
|
pid = pipecmd(buf, 0, 0);
|
|
|
|
while(waitup(-3, &pid) >= 0)
|
|
|
|
;
|
|
|
|
return(pid? 2:1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
outofdate(Node *node, Arc *arc, int eval)
|
|
|
|
{
|
|
|
|
char buf[3*NAMEBLOCK], *str;
|
|
|
|
Symtab *sym;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
str = 0;
|
|
|
|
if(arc->prog){
|
|
|
|
sprint(buf, "%s%c%s", node->name, 0377, arc->n->name);
|
|
|
|
sym = symlook(buf, S_OUTOFDATE, 0);
|
|
|
|
if(sym == 0 || eval){
|
|
|
|
if(sym == 0)
|
|
|
|
str = strdup(buf);
|
|
|
|
ret = pcmp(arc->prog, node->name, arc->n->name);
|
|
|
|
if(sym)
|
|
|
|
sym->value = (void *)ret;
|
|
|
|
else
|
|
|
|
symlook(str, S_OUTOFDATE, (void *)ret);
|
|
|
|
} else
|
|
|
|
ret = (int)sym->value;
|
|
|
|
return(ret-1);
|
|
|
|
} else if(strchr(arc->n->name, '(') && arc->n->time == 0) /* missing archive member */
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return node->time < arc->n->time;
|
|
|
|
}
|