mk.c (5249B)
1 #include "mk.h" 2 3 int runerrs; 4 5 void 6 mk(char *target) 7 { 8 Node *node; 9 int did = 0; 10 11 nproc(); /* it can be updated dynamically */ 12 nrep(); /* it can be updated dynamically */ 13 runerrs = 0; 14 node = graph(target); 15 if(DEBUG(D_GRAPH)){ 16 dumpn("new target\n", node); 17 Bflush(&bout); 18 } 19 clrmade(node); 20 while(node->flags&NOTMADE){ 21 if(work(node, (Node *)0, (Arc *)0)) 22 did = 1; /* found something to do */ 23 else { 24 if(waitup(1, (int *)0) > 0){ 25 if(node->flags&(NOTMADE|BEINGMADE)){ 26 assert("must be run errors", runerrs); 27 break; /* nothing more waiting */ 28 } 29 } 30 } 31 } 32 if(node->flags&BEINGMADE) 33 waitup(-1, (int *)0); 34 while(jobs) 35 waitup(-2, (int *)0); 36 assert("target didn't get done", runerrs || (node->flags&MADE)); 37 if(did == 0) 38 Bprint(&bout, "mk: '%s' is up to date\n", node->name); 39 } 40 41 void 42 clrmade(Node *n) 43 { 44 Arc *a; 45 46 n->flags &= ~(CANPRETEND|PRETENDING); 47 if(strchr(n->name, '(') ==0 || n->time) 48 n->flags |= CANPRETEND; 49 MADESET(n, NOTMADE); 50 for(a = n->prereqs; a; a = a->next) 51 if(a->n) 52 clrmade(a->n); 53 } 54 55 static void 56 unpretend(Node *n) 57 { 58 MADESET(n, NOTMADE); 59 n->flags &= ~(CANPRETEND|PRETENDING); 60 n->time = 0; 61 } 62 63 static char* 64 dir(void) 65 { 66 static char buf[1024]; 67 68 return getcwd(buf, sizeof buf); 69 } 70 71 int 72 work(Node *node, Node *p, Arc *parc) 73 { 74 Arc *a, *ra; 75 int weoutofdate; 76 int ready; 77 int did = 0; 78 79 /*print("work(%s) flags=0x%x time=%ld\n", node->name, node->flags, node->time); */ 80 if(node->flags&BEINGMADE) 81 return(did); 82 if((node->flags&MADE) && (node->flags&PRETENDING) && p && outofdate(p, parc, 0)){ 83 if(explain) 84 fprint(1, "unpretending %s(%ld) because %s is out of date(%ld)\n", 85 node->name, node->time, p->name, p->time); 86 unpretend(node); 87 } 88 /* 89 have a look if we are pretending in case 90 someone has been unpretended out from underneath us 91 */ 92 if(node->flags&MADE){ 93 if(node->flags&PRETENDING){ 94 node->time = 0; 95 }else 96 return(did); 97 } 98 /* consider no prerequsite case */ 99 if(node->prereqs == 0){ 100 if(node->time == 0){ 101 fprint(2, "mk: don't know how to make '%s' in %s\n", node->name, dir()); 102 if(kflag){ 103 node->flags |= BEINGMADE; 104 runerrs++; 105 } else 106 Exit(); 107 } else 108 MADESET(node, MADE); 109 return(did); 110 } 111 /* 112 now see if we are out of date or what 113 */ 114 ready = 1; 115 weoutofdate = aflag; 116 ra = 0; 117 for(a = node->prereqs; a; a = a->next) 118 if(a->n){ 119 did = work(a->n, node, a) || did; 120 if(a->n->flags&(NOTMADE|BEINGMADE)) 121 ready = 0; 122 if(outofdate(node, a, 0)){ 123 weoutofdate = 1; 124 if((ra == 0) || (ra->n == 0) 125 || (ra->n->time < a->n->time)) 126 ra = a; 127 } 128 } else { 129 if(node->time == 0){ 130 if(ra == 0) 131 ra = a; 132 weoutofdate = 1; 133 } 134 } 135 if(ready == 0) /* can't do anything now */ 136 return(did); 137 if(weoutofdate == 0){ 138 MADESET(node, MADE); 139 return(did); 140 } 141 /* 142 can we pretend to be made? 143 */ 144 if((iflag == 0) && (node->time == 0) && (node->flags&(PRETENDING|CANPRETEND)) 145 && p && ra->n && !outofdate(p, ra, 0)){ 146 node->flags &= ~CANPRETEND; 147 MADESET(node, MADE); 148 if(explain && ((node->flags&PRETENDING) == 0)) 149 fprint(1, "pretending %s has time %ld\n", node->name, node->time); 150 node->flags |= PRETENDING; 151 return(did); 152 } 153 /* 154 node is out of date and we REALLY do have to do something. 155 quickly rescan for pretenders 156 */ 157 for(a = node->prereqs; a; a = a->next) 158 if(a->n && (a->n->flags&PRETENDING)){ 159 if(explain) 160 Bprint(&bout, "unpretending %s because of %s because of %s\n", 161 a->n->name, node->name, ra->n? ra->n->name : "rule with no prerequisites"); 162 163 unpretend(a->n); 164 did = work(a->n, node, a) || did; 165 ready = 0; 166 } 167 if(ready == 0) /* try later unless nothing has happened for -k's sake */ 168 return(did || work(node, p, parc)); 169 did = dorecipe(node) || did; 170 return(did); 171 } 172 173 void 174 update(int fake, Node *node) 175 { 176 Arc *a; 177 178 MADESET(node, fake? BEINGMADE : MADE); 179 if(((node->flags&VIRTUAL) == 0) && (access(node->name, 0) == 0)){ 180 node->time = timeof(node->name, 1); 181 node->flags &= ~(CANPRETEND|PRETENDING); 182 for(a = node->prereqs; a; a = a->next) 183 if(a->prog) 184 outofdate(node, a, 1); 185 } else { 186 node->time = 1; 187 for(a = node->prereqs; a; a = a->next) 188 if(a->n && outofdate(node, a, 1)) 189 node->time = a->n->time; 190 } 191 /* print("----node %s time=%ld flags=0x%x\n", node->name, node->time, node->flags);*/ 192 } 193 194 static int 195 pcmp(char *prog, char *p, char *q, Shell *sh, Word *shcmd) 196 { 197 char buf[3*NAMEBLOCK]; 198 int pid; 199 200 Bflush(&bout); 201 snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q); 202 pid = pipecmd(buf, 0, 0, sh, shcmd); 203 while(waitup(-3, &pid) >= 0) 204 ; 205 return(pid? 2:1); 206 } 207 208 int 209 outofdate(Node *node, Arc *arc, int eval) 210 { 211 char buf[3*NAMEBLOCK], *str; 212 Symtab *sym; 213 int ret; 214 215 str = 0; 216 if(arc->prog){ 217 snprint(buf, sizeof buf, "%s%c%s", node->name, 0377, arc->n->name); 218 sym = symlook(buf, S_OUTOFDATE, 0); 219 if(sym == 0 || eval){ 220 if(sym == 0) 221 str = strdup(buf); 222 ret = pcmp(arc->prog, node->name, arc->n->name, arc->r->shellt, arc->r->shellcmd); 223 if(sym) 224 sym->u.value = ret; 225 else 226 symlook(str, S_OUTOFDATE, (void *)(uintptr)ret); 227 } else 228 ret = sym->u.value; 229 return(ret-1); 230 } else if(strchr(arc->n->name, '(') && arc->n->time == 0) /* missing archive member */ 231 return 1; 232 else 233 return node->time <= arc->n->time; 234 }