rules.c (9699B)
1 #include <signal.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include "make.h" 7 8 #define TABSIZ 128 9 #define FORCE 1 10 #define NOFORCE 0 11 12 static Target *htab[TABSIZ], *deftarget; 13 14 void 15 dumprules(void) 16 { 17 int i; 18 Target **pp, **q, *p; 19 20 for (pp = htab; pp < &htab[TABSIZ]; ++pp) { 21 for (p = *pp; p; p = p->next) { 22 if (!p->defined) 23 continue; 24 printf("%s:", p->name); 25 for (q = p->deps; q && *q; ++q) 26 printf(" %s", (*q)->name); 27 putchar('\n'); 28 for (i = 0; i < p->nactions; i++) 29 printf("\t%s\n", p->actions[i].line); 30 putchar('\n'); 31 } 32 } 33 } 34 35 static Target * 36 lookup(char *name) 37 { 38 Target *tp; 39 int h = hash(name) & TABSIZ-1; 40 41 for (tp = htab[h]; tp && strcmp(tp->name, name); tp = tp->next) 42 ; 43 44 if (tp) 45 return tp; 46 47 tp = emalloc(sizeof(*tp)); 48 tp->name = estrdup(name); 49 tp->target = tp->name; 50 tp->req = NULL; 51 tp->ndeps = 0; 52 tp->deps = NULL; 53 tp->actions = NULL; 54 tp->nactions = 0; 55 tp->next = htab[h]; 56 tp->defined = 0; 57 htab[h] = tp; 58 59 return tp; 60 } 61 62 static void 63 cleanup(Target *tp) 64 { 65 int sig, precious; 66 Target *p, **q; 67 68 sig = stop; 69 printf("make: signal %d arrived\n", sig); 70 71 precious = 0; 72 p = lookup(".PRECIOUS"); 73 for (q = p->deps; q && *q; q++) { 74 if (strcmp((*q)->name, tp->name) == 0) { 75 precious = 1; 76 break; 77 } 78 } 79 80 if (!precious && !nflag && !qflag && !is_dir(tp->name)) { 81 printf("make: trying to remove target %s\n", tp->name); 82 remove(tp->name); 83 } 84 85 signal(sig, SIG_DFL); 86 raise(sig); 87 } 88 89 static int 90 depends(char *dep, char *target) 91 { 92 93 int i; 94 char *dname; 95 Target **p, *tp; 96 97 if (strcmp(target, dep) == 0) 98 return 1; 99 100 tp = lookup(dep); 101 for (p = tp->deps; p && *p; ++p) { 102 dname = (*p)->name; 103 if (depends(dname, target)) 104 return 1; 105 } 106 107 return 0; 108 } 109 110 static int 111 is_suffix(char *s) 112 { 113 int n; 114 115 if (s[0] != '.') 116 return 0; 117 118 for (n = 0; s = strchr(s, '.'); n++) 119 s++; 120 121 return n == 2; 122 } 123 124 void 125 addtarget(char *target, int ndeps) 126 { 127 Target *tp = lookup(target); 128 129 tp->defined = 1; 130 if (!deftarget && target[0] != '.') { 131 deftarget = tp; 132 return; 133 } 134 135 if (strcmp(target, ".SUFFIXES") == 0 && ndeps == 0) { 136 free(tp->deps); 137 tp->deps = NULL; 138 tp->ndeps = 0; 139 return; 140 } 141 142 if (strcmp(target, ".DEFAULT") == 0) { 143 if (ndeps > 0) 144 error("DEFAULT rule with prerequisites"); 145 return; 146 } 147 148 if (strcmp(target, ".SILENT") == 0 && ndeps == 0) { 149 sflag = 1; 150 return; 151 } 152 153 if (strcmp(target, ".IGNORE") == 0 && ndeps == 0) { 154 iflag = 1; 155 return; 156 } 157 } 158 159 void 160 adddep(char *target, char *dep) 161 { 162 int i; 163 size_t siz; 164 Target **p, *tp = lookup(target); 165 166 if (depends(dep, target)) { 167 warning("circular dependency %s <- %s dropped", target, dep); 168 return; 169 } 170 171 for (p = tp->deps; p && *p; ++p) { 172 if (strcmp((*p)->name, dep) == 0) 173 return; 174 } 175 176 tp->ndeps++; 177 siz = (tp->ndeps + 1) * sizeof(Target *); 178 tp->deps = erealloc(tp->deps, siz); 179 tp->deps[tp->ndeps-1] = lookup(dep); 180 tp->deps[tp->ndeps] = NULL; 181 182 debug("adding dependency %s <- %s", target, dep); 183 } 184 185 static void 186 freeaction(struct action *act) 187 { 188 free(act->line); 189 freeloc(&act->loc); 190 } 191 192 void 193 addrule(char *target, struct action *acts, int n) 194 { 195 int i; 196 struct action *v; 197 Target *tp = lookup(target); 198 199 debug("adding actions for target %s", target); 200 201 if (tp->actions) { 202 debug("overring actions of target %s", target); 203 for (i = 0; i < tp->nactions; i++) 204 freeaction(&tp->actions[i]); 205 free(tp->actions); 206 } 207 208 v = emalloc(n * sizeof(*v)); 209 for (i = 0; i < n; i++) { 210 v[i].line = estrdup(acts[i].line); 211 v[i].loc.lineno = acts[i].loc.lineno; 212 v[i].loc.fname = estrdup(acts[i].loc.fname); 213 } 214 215 tp->nactions = n; 216 tp->actions = v; 217 } 218 219 static int 220 execline(Target *tp, char *line, int ignore, int silence) 221 { 222 char *s, *t; 223 Target *p, **q; 224 int r, at, plus, minus, l; 225 226 debug("executing '%s'", line); 227 228 at = plus = minus = 0; 229 for (s = line; ; s++) { 230 switch (*s) { 231 case '@': 232 at = 1; 233 break; 234 case '-': 235 minus = 1; 236 break; 237 case '+': 238 plus = 1; 239 break; 240 default: 241 goto out_loop; 242 } 243 } 244 245 out_loop: 246 /* unescape $$ */ 247 for (l = strlen(s)+1, t = s; *t; --l, ++t) { 248 if (t[0] == '$' && t[1] == '$') { 249 memmove(t+1, t+2, l-2); 250 l--; 251 } 252 } 253 254 if (tflag && !plus) 255 return 0; 256 257 if (sflag || silence || (qflag && !plus)) 258 at = 1; 259 if (nflag) 260 at = 0; 261 if (!at) { 262 puts(s); 263 fflush(stdout); 264 } 265 266 if ((nflag || qflag) && !plus) { 267 if (qflag) 268 exitstatus = 1; 269 return 0; 270 } 271 272 if (minus || iflag || ignore) 273 ignore = 1; 274 275 r = launch(s, ignore); 276 if (ignore) 277 return 0; 278 279 return r; 280 } 281 282 static int 283 touch(char *name, int ignore, int silence) 284 { 285 char *cmd; 286 int r, n; 287 288 n = snprintf(NULL, 0, "touch %s", name) + 1; 289 cmd = emalloc(n); 290 snprintf(cmd, n, "touch %s", name); 291 292 if (!sflag && !silence) 293 puts(cmd); 294 295 r = system(cmd); 296 free(cmd); 297 298 if (ignore || iflag) 299 return 0; 300 301 return r; 302 } 303 304 static int 305 touchdeps(Target *tp, int ignore, int silent) 306 { 307 int r; 308 Target **p; 309 310 if (tp->req) { 311 r = touch(tp->req, silent, ignore); 312 if (r) 313 return r; 314 } 315 316 for (p = tp->deps; p && *p; ++p) { 317 r = touch((*p)->name, silent, ignore); 318 if (r) 319 return r; 320 } 321 322 return 0; 323 } 324 325 static int 326 run(Target *tp) 327 { 328 int r, i, ignore, silent; 329 char *s; 330 Target *p, **q; 331 332 silent = 0; 333 p = lookup(".SILENT"); 334 for (q = p->deps; q && *q; ++q) { 335 if (strcmp((*q)->name, tp->name) == 0) { 336 debug("target %s error silent by .SILENT", tp->name); 337 silent = 1; 338 } 339 } 340 341 ignore = 0; 342 p = lookup(".IGNORE"); 343 for (q = p->deps; q && *q; ++q) { 344 if (strcmp((*q)->name, tp->name) == 0) { 345 debug("target %s error ignored by .IGNORE", tp->name); 346 ignore = 1; 347 } 348 } 349 350 if (tflag) { 351 r = touchdeps(tp, ignore, silent); 352 if (r) 353 return r; 354 } 355 356 for (i = 0; i < tp->nactions; i++) { 357 struct action *p; 358 359 if (stop) 360 cleanup(tp); 361 362 p = &tp->actions[i]; 363 debug("executing action '%s'", p->line); 364 s = expandstring(p->line, tp, &p->loc); 365 r = execline(tp, s, ignore, silent); 366 free(s); 367 368 if (r) 369 return r; 370 } 371 372 if (tflag) { 373 r = touch(tp->target, ignore, silent); 374 if (r) 375 return r; 376 } 377 378 return 0; 379 } 380 381 static int 382 enabled(char *suffix) 383 { 384 Target **p, *tp = lookup(".SUFFIXES"); 385 386 for (p = tp->deps; p && *p; ++p) { 387 if (strcmp(suffix, (*p)->name) == 0) 388 return 1; 389 } 390 391 return 0; 392 } 393 394 static Target * 395 inference(Target *tp, int force) 396 { 397 time_t t; 398 int tolen, r; 399 char *to, *from; 400 Target *q, **p, *suffixes; 401 char buf[FILENAME_MAX], fname[FILENAME_MAX]; 402 403 debug("searching an inference rule for %s", tp->name); 404 405 to = strrchr(tp->name, '.'); 406 if (to && !enabled(to)) 407 return NULL; 408 tolen = to ? to - tp->name : strlen(tp->name); 409 410 if (!to) 411 to = ""; 412 413 suffixes = lookup(".SUFFIXES"); 414 for (p = suffixes->deps; p && *p; ++p) { 415 from = (*p)->name; 416 debug("trying suffix %s", from); 417 418 r = snprintf(buf, 419 sizeof(buf), 420 "%s%s", 421 from, to); 422 423 if (r < 0 || r >= sizeof(buf)) 424 error("suffixes too long %s %s", from, to); 425 426 q = lookup(buf); 427 if (!q->actions) 428 continue; 429 430 r = snprintf(fname, 431 sizeof(fname), 432 "%*.*s%s", 433 tolen, tolen, tp->name, from); 434 435 if (r < 0 || r >= sizeof(fname)) { 436 error("prerequisite name too long %s %s", 437 tp->name, from); 438 } 439 440 debug("\tsearching prerequisite %s", fname); 441 442 t = stamp(fname); 443 if (t == -1) { 444 debug("\tprerequisite %s not found", fname); 445 continue; 446 } 447 448 if (!force && t <= tp->stamp) { 449 debug("\tdiscarded because is newer"); 450 debug("\t%s: %s", tp->name, ctime(&tp->stamp)); 451 debug("\t%s: %s", fname, ctime(&t)); 452 continue; 453 } 454 455 free(q->req); 456 q->req = estrdup(fname); 457 q->deps = tp->deps; 458 q->target = tp->name; 459 q->stamp = tp->stamp; 460 461 debug("using inference rule %s with %s", q->name, fname); 462 return q; 463 } 464 465 return NULL; 466 } 467 468 static int 469 update(Target *tp) 470 { 471 Target *p; 472 473 debug("%s needs to be updated", tp->name); 474 475 if (tp->actions) { 476 debug("using target rule to build %s", tp->name); 477 return run(tp); 478 } 479 480 if ((p = inference(tp, FORCE)) != NULL) { 481 debug("using inference rule %s", p->name); 482 return run(p); 483 } 484 485 p = lookup(".DEFAULT"); 486 if (p->defined) { 487 debug("using default rule"); 488 return run(p); 489 } 490 491 debug("not rule found to update %s", tp->name); 492 493 if (!tp->defined) 494 error("don't know how to make %s", tp->name); 495 496 return 0; 497 } 498 499 static int 500 rebuild(Target *tp, int *buildp) 501 { 502 Target **p, *q;; 503 int r, need, build, err, def; 504 505 debug("checking rebuild of %s", tp->name); 506 507 tp->stamp = stamp(tp->name); 508 509 def = err = need = 0; 510 for (p = tp->deps; p && *p; ++p) { 511 if (stop) 512 cleanup(tp); 513 514 q = *p; 515 debug("checking dependency %s", q->name); 516 517 if (strcmp(q->name, tp->name) == 0 && q->actions) 518 def = 1; 519 520 build = 0; 521 if (rebuild(q, &build) != 0) { 522 err = 1; 523 continue; 524 } 525 526 if (build) { 527 debug("rebuild of %s forces rebuild of %s", 528 q->name, tp->name); 529 need = 1; 530 } else if (q->stamp > tp->stamp) { 531 debug("dependency %s is newer than %s", 532 q->name, tp->name); 533 need = 1; 534 } 535 } 536 537 if (tp->stamp == -1) { 538 need = 1; 539 } else if (!def) { 540 debug("no action found for %s, looking a inference rule", 541 tp->name); 542 if (inference(tp, NOFORCE)) 543 need = 1; 544 } 545 546 if (err) { 547 warning("target %s not remade because of errors", tp->name); 548 return 1; 549 } else if (need) { 550 *buildp = 1; 551 552 debug("target %s needs updating", tp->name); 553 r = update(tp); 554 if (r == 0) 555 return 0; 556 557 if (stop) 558 cleanup(tp); 559 560 exitstatus = 1; 561 562 if (!kflag) 563 error("target %s: error %d", tp->name, r); 564 else 565 warning("target %s: error %d", tp->name, r); 566 return r; 567 } 568 569 return 0; 570 } 571 572 int 573 build(char *name) 574 { 575 int build, r; 576 577 if (!name) { 578 if (!deftarget) { 579 printf("make: no target to make\n"); 580 return 0; 581 } 582 name = deftarget->name; 583 } 584 585 debug("checking target %s", name); 586 587 build = 0; 588 return rebuild(lookup(name), &build); 589 }