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