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