rules.c (8472B)
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]); 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 void 142 addrule(char *target, char **actions, int n) 143 { 144 int i; 145 char **v; 146 Target *tp = lookup(target); 147 148 debug("adding actions for target %s", target); 149 150 if (tp->actions) { 151 debug("overring actions of target %s", target); 152 for (i = 0; i < tp->nactions; i++) 153 free(tp->actions[i]); 154 free(tp->actions); 155 } 156 157 v = emalloc(n * sizeof(char *)); 158 for (i = 0; i < n; i++) 159 v[i] = estrdup(actions[i]); 160 161 tp->nactions = n; 162 tp->actions = v; 163 } 164 165 static int 166 execline(Target *tp, char *line, int ignore, int silence) 167 { 168 char *s; 169 Target *p, **q; 170 int r, at, plus, minus; 171 172 debug("executing '%s'", line); 173 174 at = plus = minus = 0; 175 for (s = line; ; s++) { 176 switch (*s) { 177 case '@': 178 at = 1; 179 break; 180 case '-': 181 minus = 1; 182 break; 183 case '+': 184 plus = 1; 185 break; 186 default: 187 goto out_loop; 188 } 189 } 190 191 out_loop: 192 if (tflag && !plus) 193 return 0; 194 195 if (sflag || silence || (qflag && !plus)) 196 at = 1; 197 if (nflag) 198 at = 0; 199 if (!at) { 200 puts(s); 201 fflush(stdout); 202 } 203 204 if ((nflag || qflag) && !plus) { 205 if (qflag) 206 exitstatus = 1; 207 return 0; 208 } 209 210 if (minus || iflag || ignore) 211 ignore = 1; 212 213 r = launch(s, ignore); 214 if (ignore) 215 return 0; 216 217 return r; 218 } 219 220 static int 221 touch(char *name, int ignore, int silence) 222 { 223 char *cmd; 224 int r, n; 225 226 n = snprintf(NULL, 0, "touch %s", name) + 1; 227 cmd = emalloc(n); 228 snprintf(cmd, n, "touch %s", name); 229 230 if (!sflag && !silence) 231 puts(cmd); 232 233 r = system(cmd); 234 free(cmd); 235 236 if (ignore || iflag) 237 return 0; 238 239 return r; 240 } 241 242 static int 243 touchdeps(Target *tp, int ignore, int silent) 244 { 245 int r; 246 Target **p; 247 248 if (tp->req) { 249 r = touch(tp->req, silent, ignore); 250 if (r) 251 return r; 252 } 253 254 for (p = tp->deps; p && *p; ++p) { 255 r = touch((*p)->name, silent, ignore); 256 if (r) 257 return r; 258 } 259 260 return 0; 261 } 262 263 static int 264 run(Target *tp) 265 { 266 int r, i, ignore, silent; 267 char *s; 268 Target *p, **q; 269 270 silent = 0; 271 p = lookup(".SILENT"); 272 for (q = p->deps; q && *q; ++q) { 273 if (strcmp((*q)->name, tp->name) == 0) { 274 debug("target %s error silent by .SILENT", tp->name); 275 silent = 1; 276 } 277 } 278 279 ignore = 0; 280 p = lookup(".IGNORE"); 281 for (q = p->deps; q && *q; ++q) { 282 if (strcmp((*q)->name, tp->name) == 0) { 283 debug("target %s error ignored by .IGNORE", tp->name); 284 ignore = 1; 285 } 286 } 287 288 if (tflag) { 289 r = touchdeps(tp, ignore, silent); 290 if (r) 291 return r; 292 } 293 294 for (i = 0; i < tp->nactions; i++) { 295 s = expandstring(tp->actions[i], tp); 296 r = execline(tp, s, ignore, silent); 297 free(s); 298 299 if (r) 300 return r; 301 } 302 303 if (tflag) { 304 r = touch(tp->target, ignore, silent); 305 if (r) 306 return r; 307 } 308 309 return 0; 310 } 311 312 static int 313 enabled(char *suffix) 314 { 315 Target **p, *tp = lookup(".SUFFIXES"); 316 317 for (p = tp->deps; p && *p; ++p) { 318 if (strcmp(suffix, (*p)->name) == 0) 319 return 1; 320 } 321 322 return 0; 323 } 324 325 static Target * 326 inference(Target *tp) 327 { 328 time_t t; 329 int tolen, r; 330 char *to, *from; 331 Target *q, **p, *suffixes; 332 char buf[20], fname[FILENAME_MAX]; 333 334 debug("searching an inference rule for %s", tp->name); 335 336 to = strrchr(tp->name, '.'); 337 if (to && !enabled(to)) 338 return NULL; 339 tolen = to ? to - tp->name : strlen(tp->name); 340 341 if (!to) 342 to = ""; 343 344 suffixes = lookup(".SUFFIXES"); 345 for (p = suffixes->deps; p && *p; ++p) { 346 from = (*p)->name; 347 debug("trying suffix %s", from); 348 349 r = snprintf(buf, 350 sizeof(buf), 351 "%s%s", 352 from, to); 353 354 if (r < 0 || r >= sizeof(buf)) 355 error("suffixes too long %s %s", from, to); 356 357 q = lookup(buf); 358 if (!q->actions) 359 continue; 360 361 r = snprintf(fname, 362 sizeof(fname), 363 "%*.*s%s", 364 tolen, tolen, tp->name, from); 365 366 if (r < 0 || r >= sizeof(fname)) { 367 error("prerequisite name too long %s %s", 368 tp->name, from); 369 } 370 371 debug("\tsearching prerequisite %s", fname); 372 373 t = stamp(fname); 374 if (t == -1 || t <= tp->stamp) 375 continue; 376 377 free(q->req); 378 q->req = estrdup(fname); 379 q->deps = tp->deps; 380 q->target = tp->name; 381 q->stamp = tp->stamp; 382 383 debug("using inference rule %s with %s", q->name, fname); 384 return q; 385 } 386 387 return NULL; 388 } 389 390 static int 391 update(Target *tp) 392 { 393 Target *p; 394 395 debug("%s needs to be updated", tp->name); 396 397 if (tp->actions) { 398 debug("using target rule to build %s", tp->name); 399 return run(tp); 400 } 401 402 if ((p = inference(tp)) != NULL) { 403 debug("using inference rule %s", p->name); 404 return run(p); 405 } 406 407 p = lookup(".DEFAULT"); 408 if (p->defined) { 409 debug("using default rule"); 410 return run(p); 411 } 412 413 debug("not rule found to update %s", tp->name); 414 415 if (!tp->defined) 416 error("don't know how to make %s", tp->name); 417 418 return 0; 419 } 420 421 static int 422 cleanup(Target *tp) 423 { 424 int precious; 425 Target *p, **q; 426 427 printf("make: signal %d arrived\n", stop); 428 429 precious = 0; 430 p = lookup(".PRECIOUS"); 431 for (q = p->deps; q && *q; q++) { 432 if (strcmp((*q)->name, tp->name) == 0) { 433 precious = 1; 434 break; 435 } 436 } 437 438 if (!precious) { 439 printf("make: trying to remove target %s\n", tp->name); 440 remove(tp->name); 441 } 442 443 signal(stop, SIG_DFL); 444 raise(stop); 445 } 446 447 static int 448 rebuild(Target *tp, int *buildp) 449 { 450 Target **p, *q;; 451 int r, need, build, err; 452 453 debug("checking rebuild of %s", tp->name); 454 455 tp->stamp = stamp(tp->name); 456 457 err = need = 0; 458 for (p = tp->deps; p && *p; ++p) { 459 if (stop) 460 cleanup(tp); 461 462 q = *p; 463 debug("checking dependency %s", q->name); 464 465 build = 0; 466 if (rebuild(q, &build) != 0) { 467 err = 1; 468 continue; 469 } 470 471 if (build) { 472 debug("rebuild of %s forces rebuild of %s", 473 q->name, tp->name); 474 need = 1; 475 } else if (q->stamp > tp->stamp) { 476 debug("dependency %s is newer than %s", 477 q->name, tp->name); 478 need = 1; 479 } 480 } 481 482 if (tp->stamp == -1) 483 need = 1; 484 485 if (err) { 486 warning("target %s not remade because of errors", tp->name); 487 return 1; 488 } else if (need) { 489 *buildp = 1; 490 491 r = update(tp); 492 if (r == 0) 493 return 0; 494 495 if (stop) 496 cleanup(tp); 497 498 exitstatus = 1; 499 500 if (!kflag) 501 error("target %s: error %d", tp->name, r); 502 else 503 warning("target %s: error %d", tp->name, r); 504 return r; 505 } 506 507 return 0; 508 } 509 510 int 511 build(char *name) 512 { 513 int build, r;; 514 515 if (!name) { 516 if (!deftarget) { 517 printf("make: no target to make\n"); 518 return 0; 519 } 520 name = deftarget->name; 521 } 522 523 debug("checking target %s", name); 524 525 build = 0; 526 return rebuild(lookup(name), &build); 527 }