1 /* $NetBSD: make.c,v 1.19 1997/09/28 03:31:07 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * Copyright (c) 1989 by Berkeley Softworks 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Adam de Boor. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by the University of 23 * California, Berkeley and its contributors. 24 * 4. Neither the name of the University nor the names of its contributors 25 * may be used to endorse or promote products derived from this software 26 * without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 */ 40 41 #ifdef MAKE_BOOTSTRAP 42 static char rcsid[] = "$NetBSD: make.c,v 1.19 1997/09/28 03:31:07 lukem Exp $"; 43 #else 44 #include <sys/cdefs.h> 45 #ifndef lint 46 #if 0 47 static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; 48 #else 49 __RCSID("$NetBSD: make.c,v 1.19 1997/09/28 03:31:07 lukem Exp $"); 50 #endif 51 #endif /* not lint */ 52 #endif 53 54 /*- 55 * make.c -- 56 * The functions which perform the examination of targets and 57 * their suitability for creation 58 * 59 * Interface: 60 * Make_Run Initialize things for the module and recreate 61 * whatever needs recreating. Returns TRUE if 62 * work was (or would have been) done and FALSE 63 * otherwise. 64 * 65 * Make_Update Update all parents of a given child. Performs 66 * various bookkeeping chores like the updating 67 * of the cmtime field of the parent, filling 68 * of the IMPSRC context variable, etc. It will 69 * place the parent on the toBeMade queue if it 70 * should be. 71 * 72 * Make_TimeStamp Function to set the parent's cmtime field 73 * based on a child's modification time. 74 * 75 * Make_DoAllVar Set up the various local variables for a 76 * target, including the .ALLSRC variable, making 77 * sure that any variable that needs to exist 78 * at the very least has the empty value. 79 * 80 * Make_OODate Determine if a target is out-of-date. 81 * 82 * Make_HandleUse See if a child is a .USE node for a parent 83 * and perform the .USE actions if so. 84 * 85 * Make_ExpandUse Expand .USE nodes and return the new list of 86 * targets. 87 */ 88 89 #include "make.h" 90 #include "hash.h" 91 #include "dir.h" 92 #include "job.h" 93 94 static Lst toBeMade; /* The current fringe of the graph. These 95 * are nodes which await examination by 96 * MakeOODate. It is added to by 97 * Make_Update and subtracted from by 98 * MakeStartJobs */ 99 static int numNodes; /* Number of nodes to be processed. If this 100 * is non-zero when Job_Empty() returns 101 * TRUE, there's a cycle in the graph */ 102 103 static int MakeAddChild __P((ClientData, ClientData)); 104 static int MakeFindChild __P((ClientData, ClientData)); 105 static int MakeAddAllSrc __P((ClientData, ClientData)); 106 static int MakeTimeStamp __P((ClientData, ClientData)); 107 static int MakeHandleUse __P((ClientData, ClientData)); 108 static Boolean MakeStartJobs __P((void)); 109 static int MakePrintStatus __P((ClientData, ClientData)); 110 /*- 111 *----------------------------------------------------------------------- 112 * Make_TimeStamp -- 113 * Set the cmtime field of a parent node based on the mtime stamp in its 114 * child. Called from MakeOODate via Lst_ForEach. 115 * 116 * Results: 117 * Always returns 0. 118 * 119 * Side Effects: 120 * The cmtime of the parent node will be changed if the mtime 121 * field of the child is greater than it. 122 *----------------------------------------------------------------------- 123 */ 124 int 125 Make_TimeStamp (pgn, cgn) 126 GNode *pgn; /* the current parent */ 127 GNode *cgn; /* the child we've just examined */ 128 { 129 if (cgn->mtime > pgn->cmtime) { 130 pgn->cmtime = cgn->mtime; 131 } 132 return (0); 133 } 134 135 static int 136 MakeTimeStamp (pgn, cgn) 137 ClientData pgn; /* the current parent */ 138 ClientData cgn; /* the child we've just examined */ 139 { 140 return Make_TimeStamp((GNode *) pgn, (GNode *) cgn); 141 } 142 143 /*- 144 *----------------------------------------------------------------------- 145 * Make_OODate -- 146 * See if a given node is out of date with respect to its sources. 147 * Used by Make_Run when deciding which nodes to place on the 148 * toBeMade queue initially and by Make_Update to screen out USE and 149 * EXEC nodes. In the latter case, however, any other sort of node 150 * must be considered out-of-date since at least one of its children 151 * will have been recreated. 152 * 153 * Results: 154 * TRUE if the node is out of date. FALSE otherwise. 155 * 156 * Side Effects: 157 * The mtime field of the node and the cmtime field of its parents 158 * will/may be changed. 159 *----------------------------------------------------------------------- 160 */ 161 Boolean 162 Make_OODate (gn) 163 register GNode *gn; /* the node to check */ 164 { 165 Boolean oodate; 166 167 /* 168 * Certain types of targets needn't even be sought as their datedness 169 * doesn't depend on their modification time... 170 */ 171 if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) { 172 (void) Dir_MTime (gn); 173 if (DEBUG(MAKE)) { 174 if (gn->mtime != 0) { 175 printf ("modified %s...", Targ_FmtTime(gn->mtime)); 176 } else { 177 printf ("non-existent..."); 178 } 179 } 180 } 181 182 /* 183 * A target is remade in one of the following circumstances: 184 * its modification time is smaller than that of its youngest child 185 * and it would actually be run (has commands or type OP_NOP) 186 * it's the object of a force operator 187 * it has no children, was on the lhs of an operator and doesn't exist 188 * already. 189 * 190 * Libraries are only considered out-of-date if the archive module says 191 * they are. 192 * 193 * These weird rules are brought to you by Backward-Compatability and 194 * the strange people who wrote 'Make'. 195 */ 196 if (gn->type & OP_USE) { 197 /* 198 * If the node is a USE node it is *never* out of date 199 * no matter *what*. 200 */ 201 if (DEBUG(MAKE)) { 202 printf(".USE node..."); 203 } 204 oodate = FALSE; 205 } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) { 206 if (DEBUG(MAKE)) { 207 printf("library..."); 208 } 209 210 /* 211 * always out of date if no children and :: target 212 */ 213 214 oodate = Arch_LibOODate (gn) || 215 ((gn->cmtime == 0) && (gn->type & OP_DOUBLEDEP)); 216 } else if (gn->type & OP_JOIN) { 217 /* 218 * A target with the .JOIN attribute is only considered 219 * out-of-date if any of its children was out-of-date. 220 */ 221 if (DEBUG(MAKE)) { 222 printf(".JOIN node..."); 223 } 224 oodate = gn->childMade; 225 } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { 226 /* 227 * A node which is the object of the force (!) operator or which has 228 * the .EXEC attribute is always considered out-of-date. 229 */ 230 if (DEBUG(MAKE)) { 231 if (gn->type & OP_FORCE) { 232 printf("! operator..."); 233 } else if (gn->type & OP_PHONY) { 234 printf(".PHONY node..."); 235 } else { 236 printf(".EXEC node..."); 237 } 238 } 239 oodate = TRUE; 240 } else if ((gn->mtime < gn->cmtime) || 241 ((gn->cmtime == 0) && 242 ((gn->mtime==0) || (gn->type & OP_DOUBLEDEP)))) 243 { 244 /* 245 * A node whose modification time is less than that of its 246 * youngest child or that has no children (cmtime == 0) and 247 * either doesn't exist (mtime == 0) or was the object of a 248 * :: operator is out-of-date. Why? Because that's the way Make does 249 * it. 250 */ 251 if (DEBUG(MAKE)) { 252 if (gn->mtime < gn->cmtime) { 253 printf("modified before source..."); 254 } else if (gn->mtime == 0) { 255 printf("non-existent and no sources..."); 256 } else { 257 printf(":: operator and no sources..."); 258 } 259 } 260 oodate = TRUE; 261 } else { 262 #if 0 263 /* WHY? */ 264 if (DEBUG(MAKE)) { 265 printf("source %smade...", gn->childMade ? "" : "not "); 266 } 267 oodate = gn->childMade; 268 #else 269 oodate = FALSE; 270 #endif /* 0 */ 271 } 272 273 /* 274 * If the target isn't out-of-date, the parents need to know its 275 * modification time. Note that targets that appear to be out-of-date 276 * but aren't, because they have no commands and aren't of type OP_NOP, 277 * have their mtime stay below their children's mtime to keep parents from 278 * thinking they're out-of-date. 279 */ 280 if (!oodate) { 281 Lst_ForEach (gn->parents, MakeTimeStamp, (ClientData)gn); 282 } 283 284 return (oodate); 285 } 286 287 /*- 288 *----------------------------------------------------------------------- 289 * MakeAddChild -- 290 * Function used by Make_Run to add a child to the list l. 291 * It will only add the child if its make field is FALSE. 292 * 293 * Results: 294 * Always returns 0 295 * 296 * Side Effects: 297 * The given list is extended 298 *----------------------------------------------------------------------- 299 */ 300 static int 301 MakeAddChild (gnp, lp) 302 ClientData gnp; /* the node to add */ 303 ClientData lp; /* the list to which to add it */ 304 { 305 GNode *gn = (GNode *) gnp; 306 Lst l = (Lst) lp; 307 308 if (!gn->make && !(gn->type & OP_USE)) { 309 (void)Lst_EnQueue (l, (ClientData)gn); 310 } 311 return (0); 312 } 313 314 /*- 315 *----------------------------------------------------------------------- 316 * MakeFindChild -- 317 * Function used by Make_Run to find the pathname of a child 318 * that was already made. 319 * 320 * Results: 321 * Always returns 0 322 * 323 * Side Effects: 324 * The path and mtime of the node and the cmtime of the parent are 325 * updated 326 *----------------------------------------------------------------------- 327 */ 328 static int 329 MakeFindChild (gnp, pgnp) 330 ClientData gnp; /* the node to find */ 331 ClientData pgnp; 332 { 333 GNode *gn = (GNode *) gnp; 334 GNode *pgn = (GNode *) pgnp; 335 336 (void) Dir_MTime(gn); 337 if (pgn->cmtime < gn->mtime) 338 pgn->cmtime = gn->mtime; 339 gn->made = UPTODATE; 340 341 return (0); 342 } 343 344 /*- 345 *----------------------------------------------------------------------- 346 * Make_HandleUse -- 347 * Function called by Make_Run and SuffApplyTransform on the downward 348 * pass to handle .USE and transformation nodes. A callback function 349 * for Lst_ForEach, it implements the .USE and transformation 350 * functionality by copying the node's commands, type flags 351 * and children to the parent node. Should be called before the 352 * children are enqueued to be looked at by MakeAddChild. 353 * 354 * A .USE node is much like an explicit transformation rule, except 355 * its commands are always added to the target node, even if the 356 * target already has commands. 357 * 358 * Results: 359 * returns 0. 360 * 361 * Side Effects: 362 * Children and commands may be added to the parent and the parent's 363 * type may be changed. 364 * 365 *----------------------------------------------------------------------- 366 */ 367 int 368 Make_HandleUse (cgn, pgn) 369 register GNode *cgn; /* The .USE node */ 370 register GNode *pgn; /* The target of the .USE node */ 371 { 372 register LstNode ln; /* An element in the children list */ 373 374 if (cgn->type & (OP_USE|OP_TRANSFORM)) { 375 if ((cgn->type & OP_USE) || Lst_IsEmpty(pgn->commands)) { 376 /* 377 * .USE or transformation and target has no commands -- append 378 * the child's commands to the parent. 379 */ 380 (void) Lst_Concat (pgn->commands, cgn->commands, LST_CONCNEW); 381 } 382 383 if (Lst_Open (cgn->children) == SUCCESS) { 384 while ((ln = Lst_Next (cgn->children)) != NILLNODE) { 385 register GNode *tgn, *gn = (GNode *)Lst_Datum (ln); 386 387 /* 388 * Expand variables in the .USE node's name 389 * and save the unexpanded form. 390 * We don't need to do this for commands. 391 * They get expanded properly when we execute. 392 */ 393 if (gn->uname == NULL) { 394 gn->uname = gn->name; 395 } else { 396 if (gn->name) 397 free(gn->name); 398 } 399 gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE); 400 if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) { 401 /* See if we have a target for this node. */ 402 tgn = Targ_FindNode(gn->name, TARG_NOCREATE); 403 if (tgn != NILGNODE) 404 gn = tgn; 405 } 406 407 if (Lst_Member (pgn->children, gn) == NILLNODE) { 408 (void) Lst_AtEnd (pgn->children, gn); 409 (void) Lst_AtEnd (gn->parents, pgn); 410 pgn->unmade += 1; 411 } 412 } 413 Lst_Close (cgn->children); 414 } 415 416 pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM); 417 418 /* 419 * This child node is now "made", so we decrement the count of 420 * unmade children in the parent... We also remove the child 421 * from the parent's list to accurately reflect the number of decent 422 * children the parent has. This is used by Make_Run to decide 423 * whether to queue the parent or examine its children... 424 */ 425 if ((cgn->type & OP_USE) && 426 (ln = Lst_Member (pgn->children, (ClientData) cgn)) != NILLNODE) { 427 Lst_Remove(pgn->children, ln); 428 pgn->unmade--; 429 } 430 } 431 return (0); 432 } 433 static int 434 MakeHandleUse (pgn, cgn) 435 ClientData pgn; /* the current parent */ 436 ClientData cgn; /* the child we've just examined */ 437 { 438 return Make_HandleUse((GNode *) pgn, (GNode *) cgn); 439 } 440 441 /*- 442 *----------------------------------------------------------------------- 443 * Make_Update -- 444 * Perform update on the parents of a node. Used by JobFinish once 445 * a node has been dealt with and by MakeStartJobs if it finds an 446 * up-to-date node. 447 * 448 * Results: 449 * Always returns 0 450 * 451 * Side Effects: 452 * The unmade field of pgn is decremented and pgn may be placed on 453 * the toBeMade queue if this field becomes 0. 454 * 455 * If the child was made, the parent's childMade field will be set true 456 * and its cmtime set to now. 457 * 458 * If the child wasn't made, the cmtime field of the parent will be 459 * altered if the child's mtime is big enough. 460 * 461 * Finally, if the child is the implied source for the parent, the 462 * parent's IMPSRC variable is set appropriately. 463 * 464 *----------------------------------------------------------------------- 465 */ 466 void 467 Make_Update (cgn) 468 register GNode *cgn; /* the child node */ 469 { 470 register GNode *pgn; /* the parent node */ 471 register char *cname; /* the child's name */ 472 register LstNode ln; /* Element in parents and iParents lists */ 473 char *p1; 474 475 cname = Var_Value (TARGET, cgn, &p1); 476 if (p1) 477 free(p1); 478 479 /* 480 * If the child was actually made, see what its modification time is 481 * now -- some rules won't actually update the file. If the file still 482 * doesn't exist, make its mtime now. 483 */ 484 if (cgn->made != UPTODATE) { 485 #ifndef RECHECK 486 /* 487 * We can't re-stat the thing, but we can at least take care of rules 488 * where a target depends on a source that actually creates the 489 * target, but only if it has changed, e.g. 490 * 491 * parse.h : parse.o 492 * 493 * parse.o : parse.y 494 * yacc -d parse.y 495 * cc -c y.tab.c 496 * mv y.tab.o parse.o 497 * cmp -s y.tab.h parse.h || mv y.tab.h parse.h 498 * 499 * In this case, if the definitions produced by yacc haven't changed 500 * from before, parse.h won't have been updated and cgn->mtime will 501 * reflect the current modification time for parse.h. This is 502 * something of a kludge, I admit, but it's a useful one.. 503 * XXX: People like to use a rule like 504 * 505 * FRC: 506 * 507 * To force things that depend on FRC to be made, so we have to 508 * check for gn->children being empty as well... 509 */ 510 if (!Lst_IsEmpty(cgn->commands) || Lst_IsEmpty(cgn->children)) { 511 cgn->mtime = now; 512 } 513 #else 514 /* 515 * This is what Make does and it's actually a good thing, as it 516 * allows rules like 517 * 518 * cmp -s y.tab.h parse.h || cp y.tab.h parse.h 519 * 520 * to function as intended. Unfortunately, thanks to the stateless 521 * nature of NFS (by which I mean the loose coupling of two clients 522 * using the same file from a common server), there are times 523 * when the modification time of a file created on a remote 524 * machine will not be modified before the local stat() implied by 525 * the Dir_MTime occurs, thus leading us to believe that the file 526 * is unchanged, wreaking havoc with files that depend on this one. 527 * 528 * I have decided it is better to make too much than to make too 529 * little, so this stuff is commented out unless you're sure it's ok. 530 * -- ardeb 1/12/88 531 */ 532 /* 533 * Christos, 4/9/92: If we are saving commands pretend that 534 * the target is made now. Otherwise archives with ... rules 535 * don't work! 536 */ 537 if ((noExecute && !(cgn->type & OP_MAKE)) || 538 (cgn->type & OP_SAVE_CMDS) || Dir_MTime(cgn) == 0) { 539 cgn->mtime = now; 540 } 541 if (DEBUG(MAKE)) { 542 printf("update time: %s\n", Targ_FmtTime(cgn->mtime)); 543 } 544 #endif 545 } 546 547 if (Lst_Open (cgn->parents) == SUCCESS) { 548 while ((ln = Lst_Next (cgn->parents)) != NILLNODE) { 549 pgn = (GNode *)Lst_Datum (ln); 550 if (pgn->make) { 551 pgn->unmade -= 1; 552 553 if ( ! (cgn->type & (OP_EXEC|OP_USE))) { 554 if (cgn->made == MADE) { 555 pgn->childMade = TRUE; 556 if (pgn->cmtime < cgn->mtime) { 557 pgn->cmtime = cgn->mtime; 558 } 559 } else { 560 (void)Make_TimeStamp (pgn, cgn); 561 } 562 } 563 if (pgn->unmade == 0) { 564 /* 565 * Queue the node up -- any unmade predecessors will 566 * be dealt with in MakeStartJobs. 567 */ 568 (void)Lst_EnQueue (toBeMade, (ClientData)pgn); 569 } else if (pgn->unmade < 0) { 570 Error ("Graph cycles through %s", pgn->name); 571 } 572 } 573 } 574 Lst_Close (cgn->parents); 575 } 576 /* 577 * Deal with successor nodes. If any is marked for making and has an unmade 578 * count of 0, has not been made and isn't in the examination queue, 579 * it means we need to place it in the queue as it restrained itself 580 * before. 581 */ 582 for (ln = Lst_First(cgn->successors); ln != NILLNODE; ln = Lst_Succ(ln)) { 583 GNode *succ = (GNode *)Lst_Datum(ln); 584 585 if (succ->make && succ->unmade == 0 && succ->made == UNMADE && 586 Lst_Member(toBeMade, (ClientData)succ) == NILLNODE) 587 { 588 (void)Lst_EnQueue(toBeMade, (ClientData)succ); 589 } 590 } 591 592 /* 593 * Set the .PREFIX and .IMPSRC variables for all the implied parents 594 * of this node. 595 */ 596 if (Lst_Open (cgn->iParents) == SUCCESS) { 597 char *p1; 598 char *cpref = Var_Value(PREFIX, cgn, &p1); 599 600 while ((ln = Lst_Next (cgn->iParents)) != NILLNODE) { 601 pgn = (GNode *)Lst_Datum (ln); 602 if (pgn->make) { 603 Var_Set (IMPSRC, cname, pgn); 604 Var_Set (PREFIX, cpref, pgn); 605 } 606 } 607 if (p1) 608 free(p1); 609 Lst_Close (cgn->iParents); 610 } 611 } 612 613 /*- 614 *----------------------------------------------------------------------- 615 * MakeAddAllSrc -- 616 * Add a child's name to the ALLSRC and OODATE variables of the given 617 * node. Called from Make_DoAllVar via Lst_ForEach. A child is added only 618 * if it has not been given the .EXEC, .USE or .INVISIBLE attributes. 619 * .EXEC and .USE children are very rarely going to be files, so... 620 * A child is added to the OODATE variable if its modification time is 621 * later than that of its parent, as defined by Make, except if the 622 * parent is a .JOIN node. In that case, it is only added to the OODATE 623 * variable if it was actually made (since .JOIN nodes don't have 624 * modification times, the comparison is rather unfair...).. 625 * 626 * Results: 627 * Always returns 0 628 * 629 * Side Effects: 630 * The ALLSRC variable for the given node is extended. 631 *----------------------------------------------------------------------- 632 */ 633 static int 634 MakeAddAllSrc (cgnp, pgnp) 635 ClientData cgnp; /* The child to add */ 636 ClientData pgnp; /* The parent to whose ALLSRC variable it should be */ 637 /* added */ 638 { 639 GNode *cgn = (GNode *) cgnp; 640 GNode *pgn = (GNode *) pgnp; 641 if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) { 642 char *child; 643 char *p1 = NULL; 644 645 if (cgn->type & OP_ARCHV) 646 child = Var_Value (MEMBER, cgn, &p1); 647 else 648 child = cgn->path ? cgn->path : cgn->name; 649 Var_Append (ALLSRC, child, pgn); 650 if (pgn->type & OP_JOIN) { 651 if (cgn->made == MADE) { 652 Var_Append(OODATE, child, pgn); 653 } 654 } else if ((pgn->mtime < cgn->mtime) || 655 (cgn->mtime >= now && cgn->made == MADE)) 656 { 657 /* 658 * It goes in the OODATE variable if the parent is younger than the 659 * child or if the child has been modified more recently than 660 * the start of the make. This is to keep pmake from getting 661 * confused if something else updates the parent after the 662 * make starts (shouldn't happen, I know, but sometimes it 663 * does). In such a case, if we've updated the kid, the parent 664 * is likely to have a modification time later than that of 665 * the kid and anything that relies on the OODATE variable will 666 * be hosed. 667 * 668 * XXX: This will cause all made children to go in the OODATE 669 * variable, even if they're not touched, if RECHECK isn't defined, 670 * since cgn->mtime is set to now in Make_Update. According to 671 * some people, this is good... 672 */ 673 Var_Append(OODATE, child, pgn); 674 } 675 if (p1) 676 free(p1); 677 } 678 return (0); 679 } 680 681 /*- 682 *----------------------------------------------------------------------- 683 * Make_DoAllVar -- 684 * Set up the ALLSRC and OODATE variables. Sad to say, it must be 685 * done separately, rather than while traversing the graph. This is 686 * because Make defined OODATE to contain all sources whose modification 687 * times were later than that of the target, *not* those sources that 688 * were out-of-date. Since in both compatibility and native modes, 689 * the modification time of the parent isn't found until the child 690 * has been dealt with, we have to wait until now to fill in the 691 * variable. As for ALLSRC, the ordering is important and not 692 * guaranteed when in native mode, so it must be set here, too. 693 * 694 * Results: 695 * None 696 * 697 * Side Effects: 698 * The ALLSRC and OODATE variables of the given node is filled in. 699 * If the node is a .JOIN node, its TARGET variable will be set to 700 * match its ALLSRC variable. 701 *----------------------------------------------------------------------- 702 */ 703 void 704 Make_DoAllVar (gn) 705 GNode *gn; 706 { 707 Lst_ForEach (gn->children, MakeAddAllSrc, (ClientData) gn); 708 709 if (!Var_Exists (OODATE, gn)) { 710 Var_Set (OODATE, "", gn); 711 } 712 if (!Var_Exists (ALLSRC, gn)) { 713 Var_Set (ALLSRC, "", gn); 714 } 715 716 if (gn->type & OP_JOIN) { 717 char *p1; 718 Var_Set (TARGET, Var_Value (ALLSRC, gn, &p1), gn); 719 if (p1) 720 free(p1); 721 } 722 } 723 724 /*- 725 *----------------------------------------------------------------------- 726 * MakeStartJobs -- 727 * Start as many jobs as possible. 728 * 729 * Results: 730 * If the query flag was given to pmake, no job will be started, 731 * but as soon as an out-of-date target is found, this function 732 * returns TRUE. At all other times, this function returns FALSE. 733 * 734 * Side Effects: 735 * Nodes are removed from the toBeMade queue and job table slots 736 * are filled. 737 * 738 *----------------------------------------------------------------------- 739 */ 740 static Boolean 741 MakeStartJobs () 742 { 743 register GNode *gn; 744 745 while (!Job_Full() && !Lst_IsEmpty (toBeMade)) { 746 gn = (GNode *) Lst_DeQueue (toBeMade); 747 if (DEBUG(MAKE)) { 748 printf ("Examining %s...", gn->name); 749 } 750 /* 751 * Make sure any and all predecessors that are going to be made, 752 * have been. 753 */ 754 if (!Lst_IsEmpty(gn->preds)) { 755 LstNode ln; 756 757 for (ln = Lst_First(gn->preds); ln != NILLNODE; ln = Lst_Succ(ln)){ 758 GNode *pgn = (GNode *)Lst_Datum(ln); 759 760 if (pgn->make && pgn->made == UNMADE) { 761 if (DEBUG(MAKE)) { 762 printf("predecessor %s not made yet.\n", pgn->name); 763 } 764 break; 765 } 766 } 767 /* 768 * If ln isn't nil, there's a predecessor as yet unmade, so we 769 * just drop this node on the floor. When the node in question 770 * has been made, it will notice this node as being ready to 771 * make but as yet unmade and will place the node on the queue. 772 */ 773 if (ln != NILLNODE) { 774 continue; 775 } 776 } 777 778 numNodes--; 779 if (Make_OODate (gn)) { 780 if (DEBUG(MAKE)) { 781 printf ("out-of-date\n"); 782 } 783 if (queryFlag) { 784 return (TRUE); 785 } 786 Make_DoAllVar (gn); 787 Job_Make (gn); 788 } else { 789 if (DEBUG(MAKE)) { 790 printf ("up-to-date\n"); 791 } 792 gn->made = UPTODATE; 793 if (gn->type & OP_JOIN) { 794 /* 795 * Even for an up-to-date .JOIN node, we need it to have its 796 * context variables so references to it get the correct 797 * value for .TARGET when building up the context variables 798 * of its parent(s)... 799 */ 800 Make_DoAllVar (gn); 801 } 802 803 Make_Update (gn); 804 } 805 } 806 return (FALSE); 807 } 808 809 /*- 810 *----------------------------------------------------------------------- 811 * MakePrintStatus -- 812 * Print the status of a top-level node, viz. it being up-to-date 813 * already or not created due to an error in a lower level. 814 * Callback function for Make_Run via Lst_ForEach. 815 * 816 * Results: 817 * Always returns 0. 818 * 819 * Side Effects: 820 * A message may be printed. 821 * 822 *----------------------------------------------------------------------- 823 */ 824 static int 825 MakePrintStatus(gnp, cyclep) 826 ClientData gnp; /* Node to examine */ 827 ClientData cyclep; /* True if gn->unmade being non-zero implies 828 * a cycle in the graph, not an error in an 829 * inferior */ 830 { 831 GNode *gn = (GNode *) gnp; 832 Boolean cycle = *(Boolean *) cyclep; 833 if (gn->made == UPTODATE) { 834 printf ("`%s' is up to date.\n", gn->name); 835 } else if (gn->unmade != 0) { 836 if (cycle) { 837 Boolean t = TRUE; 838 /* 839 * If printing cycles and came to one that has unmade children, 840 * print out the cycle by recursing on its children. Note a 841 * cycle like: 842 * a : b 843 * b : c 844 * c : b 845 * will cause this to erroneously complain about a being in 846 * the cycle, but this is a good approximation. 847 */ 848 if (gn->made == CYCLE) { 849 Error("Graph cycles through `%s'", gn->name); 850 gn->made = ENDCYCLE; 851 Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); 852 gn->made = UNMADE; 853 } else if (gn->made != ENDCYCLE) { 854 gn->made = CYCLE; 855 Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); 856 } 857 } else { 858 printf ("`%s' not remade because of errors.\n", gn->name); 859 } 860 } 861 return (0); 862 } 863 864 865 /*- 866 *----------------------------------------------------------------------- 867 * Make_ExpandUse -- 868 * Expand .USE nodes and create a new targets list 869 * Results: 870 * The new list of targets. 871 * 872 * Side Effects: 873 * numNodes is set to the number of elements in the list of targets. 874 *----------------------------------------------------------------------- 875 */ 876 Lst 877 Make_ExpandUse (targs) 878 Lst targs; /* the initial list of targets */ 879 { 880 register GNode *gn; /* a temporary pointer */ 881 register Lst examine; /* List of targets to examine */ 882 register Lst ntargs; /* List of new targets to be made */ 883 884 ntargs = Lst_Init (FALSE); 885 886 examine = Lst_Duplicate(targs, NOCOPY); 887 numNodes = 0; 888 889 /* 890 * Make an initial downward pass over the graph, marking nodes to be made 891 * as we go down. We call Suff_FindDeps to find where a node is and 892 * to get some children for it if it has none and also has no commands. 893 * If the node is a leaf, we stick it on the toBeMade queue to 894 * be looked at in a minute, otherwise we add its children to our queue 895 * and go on about our business. 896 */ 897 while (!Lst_IsEmpty (examine)) { 898 gn = (GNode *) Lst_DeQueue (examine); 899 900 if (!gn->make) { 901 gn->make = TRUE; 902 numNodes++; 903 904 /* 905 * Apply any .USE rules before looking for implicit dependencies 906 * to make sure everything has commands that should... 907 * Make sure that the TARGET is set, so that we can make 908 * expansions. 909 */ 910 if (gn->type & OP_ARCHV) { 911 char *eoa, *eon; 912 eoa = strchr(gn->name, '('); 913 eon = strchr(gn->name, ')'); 914 if (eoa == NULL || eon == NULL) 915 continue; 916 *eoa = '\0'; 917 *eon = '\0'; 918 Var_Set (MEMBER, eoa + 1, gn); 919 Var_Set (ARCHIVE, gn->name, gn); 920 *eoa = '('; 921 *eon = ')'; 922 } 923 924 Dir_MTime(gn); 925 Var_Set (TARGET, gn->path ? gn->path : gn->name, gn); 926 Lst_ForEach (gn->children, MakeHandleUse, (ClientData)gn); 927 Suff_FindDeps (gn); 928 929 if (gn->unmade != 0 && (gn->type & OP_MADE) == 0) { 930 Lst_ForEach (gn->children, MakeAddChild, (ClientData)examine); 931 } else { 932 (void)Lst_EnQueue (ntargs, (ClientData)gn); 933 if (gn->type & OP_MADE) 934 Lst_ForEach (gn->children, MakeFindChild, (ClientData)gn); 935 } 936 } 937 } 938 939 Lst_Destroy (examine, NOFREE); 940 return ntargs; 941 } 942 943 /*- 944 *----------------------------------------------------------------------- 945 * Make_Run -- 946 * Initialize the nodes to remake and the list of nodes which are 947 * ready to be made by doing a breadth-first traversal of the graph 948 * starting from the nodes in the given list. Once this traversal 949 * is finished, all the 'leaves' of the graph are in the toBeMade 950 * queue. 951 * Using this queue and the Job module, work back up the graph, 952 * calling on MakeStartJobs to keep the job table as full as 953 * possible. 954 * 955 * Results: 956 * TRUE if work was done. FALSE otherwise. 957 * 958 * Side Effects: 959 * The make field of all nodes involved in the creation of the given 960 * targets is set to 1. The toBeMade list is set to contain all the 961 * 'leaves' of these subgraphs. 962 *----------------------------------------------------------------------- 963 */ 964 Boolean 965 Make_Run (targs) 966 Lst targs; /* the initial list of targets */ 967 { 968 int errors; /* Number of errors the Job module reports */ 969 970 toBeMade = Make_ExpandUse (targs); 971 972 if (queryFlag) { 973 /* 974 * We wouldn't do any work unless we could start some jobs in the 975 * next loop... (we won't actually start any, of course, this is just 976 * to see if any of the targets was out of date) 977 */ 978 return (MakeStartJobs()); 979 } else { 980 /* 981 * Initialization. At the moment, no jobs are running and until some 982 * get started, nothing will happen since the remaining upward 983 * traversal of the graph is performed by the routines in job.c upon 984 * the finishing of a job. So we fill the Job table as much as we can 985 * before going into our loop. 986 */ 987 (void) MakeStartJobs(); 988 } 989 990 /* 991 * Main Loop: The idea here is that the ending of jobs will take 992 * care of the maintenance of data structures and the waiting for output 993 * will cause us to be idle most of the time while our children run as 994 * much as possible. Because the job table is kept as full as possible, 995 * the only time when it will be empty is when all the jobs which need 996 * running have been run, so that is the end condition of this loop. 997 * Note that the Job module will exit if there were any errors unless the 998 * keepgoing flag was given. 999 */ 1000 while (!Job_Empty ()) { 1001 Job_CatchOutput (); 1002 Job_CatchChildren (!usePipes); 1003 (void)MakeStartJobs(); 1004 } 1005 1006 errors = Job_End(); 1007 1008 /* 1009 * Print the final status of each target. E.g. if it wasn't made 1010 * because some inferior reported an error. 1011 */ 1012 errors = ((errors == 0) && (numNodes != 0)); 1013 Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors); 1014 1015 return (TRUE); 1016 } 1017