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