1 /* $NetBSD: make.c,v 1.27 2000/02/29 22:00:02 sjg 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.27 2000/02/29 22:00:02 sjg 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.27 2000/02/29 22:00:02 sjg 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) && 206 ((gn->mtime==0) || Arch_IsLib(gn))) { 207 if (DEBUG(MAKE)) { 208 printf("library..."); 209 } 210 211 /* 212 * always out of date if no children and :: target 213 * or non-existent. 214 */ 215 oodate = (gn->cmtime == 0 || Arch_LibOODate (gn) || 216 (gn->cmtime == 0 && (gn->type & OP_DOUBLEDEP))); 217 } else if (gn->type & OP_JOIN) { 218 /* 219 * A target with the .JOIN attribute is only considered 220 * out-of-date if any of its children was out-of-date. 221 */ 222 if (DEBUG(MAKE)) { 223 printf(".JOIN node..."); 224 } 225 if (DEBUG(MAKE)) { 226 printf("source %smade...", gn->flags & CHILDMADE ? "" : "not "); 227 } 228 oodate = (gn->flags & CHILDMADE) ? 1 : 0; 229 } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) { 230 /* 231 * A node which is the object of the force (!) operator or which has 232 * the .EXEC attribute is always considered out-of-date. 233 */ 234 if (DEBUG(MAKE)) { 235 if (gn->type & OP_FORCE) { 236 printf("! operator..."); 237 } else if (gn->type & OP_PHONY) { 238 printf(".PHONY node..."); 239 } else { 240 printf(".EXEC node..."); 241 } 242 } 243 oodate = TRUE; 244 } else if ((gn->mtime < gn->cmtime) || 245 ((gn->cmtime == 0) && 246 ((gn->mtime==0) || (gn->type & OP_DOUBLEDEP)))) 247 { 248 /* 249 * A node whose modification time is less than that of its 250 * youngest child or that has no children (cmtime == 0) and 251 * either doesn't exist (mtime == 0) or was the object of a 252 * :: operator is out-of-date. Why? Because that's the way Make does 253 * it. 254 */ 255 if (DEBUG(MAKE)) { 256 if (gn->mtime < gn->cmtime) { 257 printf("modified before source..."); 258 } else if (gn->mtime == 0) { 259 printf("non-existent and no sources..."); 260 } else { 261 printf(":: operator and no sources..."); 262 } 263 } 264 oodate = TRUE; 265 } else { 266 /* 267 * When a non-existing child with no sources 268 * (such as a typically used FORCE source) has been made and 269 * the target of the child (usually a directory) has the same 270 * timestamp as the timestamp just given to the non-existing child 271 * after it was considered made. 272 */ 273 if (DEBUG(MAKE)) { 274 if (gn->flags & FORCE) 275 printf("non existing child..."); 276 } 277 oodate = (gn->flags & FORCE) ? 1 : 0; 278 } 279 280 /* 281 * If the target isn't out-of-date, the parents need to know its 282 * modification time. Note that targets that appear to be out-of-date 283 * but aren't, because they have no commands and aren't of type OP_NOP, 284 * have their mtime stay below their children's mtime to keep parents from 285 * thinking they're out-of-date. 286 */ 287 if (!oodate) { 288 Lst_ForEach (gn->parents, MakeTimeStamp, (ClientData)gn); 289 } 290 291 return (oodate); 292 } 293 294 /*- 295 *----------------------------------------------------------------------- 296 * MakeAddChild -- 297 * Function used by Make_Run to add a child to the list l. 298 * It will only add the child if its make field is FALSE. 299 * 300 * Results: 301 * Always returns 0 302 * 303 * Side Effects: 304 * The given list is extended 305 *----------------------------------------------------------------------- 306 */ 307 static int 308 MakeAddChild (gnp, lp) 309 ClientData gnp; /* the node to add */ 310 ClientData lp; /* the list to which to add it */ 311 { 312 GNode *gn = (GNode *) gnp; 313 Lst l = (Lst) lp; 314 315 if ((gn->flags & REMAKE) == 0 && !(gn->type & OP_USE)) { 316 (void)Lst_EnQueue (l, (ClientData)gn); 317 } 318 return (0); 319 } 320 321 /*- 322 *----------------------------------------------------------------------- 323 * MakeFindChild -- 324 * Function used by Make_Run to find the pathname of a child 325 * that was already made. 326 * 327 * Results: 328 * Always returns 0 329 * 330 * Side Effects: 331 * The path and mtime of the node and the cmtime of the parent are 332 * updated 333 *----------------------------------------------------------------------- 334 */ 335 static int 336 MakeFindChild (gnp, pgnp) 337 ClientData gnp; /* the node to find */ 338 ClientData pgnp; 339 { 340 GNode *gn = (GNode *) gnp; 341 GNode *pgn = (GNode *) pgnp; 342 343 (void) Dir_MTime(gn); 344 Make_TimeStamp(pgn, gn); 345 gn->made = UPTODATE; 346 347 return (0); 348 } 349 350 /*- 351 *----------------------------------------------------------------------- 352 * Make_HandleUse -- 353 * Function called by Make_Run and SuffApplyTransform on the downward 354 * pass to handle .USE and transformation nodes. A callback function 355 * for Lst_ForEach, it implements the .USE and transformation 356 * functionality by copying the node's commands, type flags 357 * and children to the parent node. Should be called before the 358 * children are enqueued to be looked at by MakeAddChild. 359 * 360 * A .USE node is much like an explicit transformation rule, except 361 * its commands are always added to the target node, even if the 362 * target already has commands. 363 * 364 * Results: 365 * returns 0. 366 * 367 * Side Effects: 368 * Children and commands may be added to the parent and the parent's 369 * type may be changed. 370 * 371 *----------------------------------------------------------------------- 372 */ 373 int 374 Make_HandleUse (cgn, pgn) 375 register GNode *cgn; /* The .USE node */ 376 register GNode *pgn; /* The target of the .USE node */ 377 { 378 register LstNode ln; /* An element in the children list */ 379 380 if (cgn->type & (OP_USE|OP_TRANSFORM)) { 381 if ((cgn->type & OP_USE) || Lst_IsEmpty(pgn->commands)) { 382 /* 383 * .USE or transformation and target has no commands -- append 384 * the child's commands to the parent. 385 */ 386 (void) Lst_Concat (pgn->commands, cgn->commands, LST_CONCNEW); 387 } 388 389 if (Lst_Open (cgn->children) == SUCCESS) { 390 while ((ln = Lst_Next (cgn->children)) != NILLNODE) { 391 register GNode *tgn, *gn = (GNode *)Lst_Datum (ln); 392 393 /* 394 * Expand variables in the .USE node's name 395 * and save the unexpanded form. 396 * We don't need to do this for commands. 397 * They get expanded properly when we execute. 398 */ 399 if (gn->uname == NULL) { 400 gn->uname = gn->name; 401 } else { 402 if (gn->name) 403 free(gn->name); 404 } 405 gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE); 406 if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) { 407 /* See if we have a target for this node. */ 408 tgn = Targ_FindNode(gn->name, TARG_NOCREATE); 409 if (tgn != NILGNODE) 410 gn = tgn; 411 } 412 413 if (Lst_Member (pgn->children, gn) == NILLNODE) { 414 (void) Lst_AtEnd (pgn->children, gn); 415 (void) Lst_AtEnd (gn->parents, pgn); 416 pgn->unmade += 1; 417 } 418 } 419 Lst_Close (cgn->children); 420 } 421 422 pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM); 423 424 /* 425 * This child node is now "made", so we decrement the count of 426 * unmade children in the parent... We also remove the child 427 * from the parent's list to accurately reflect the number of decent 428 * children the parent has. This is used by Make_Run to decide 429 * whether to queue the parent or examine its children... 430 */ 431 if ((cgn->type & OP_USE) && 432 (ln = Lst_Member (pgn->children, (ClientData) cgn)) != NILLNODE) { 433 Lst_Remove(pgn->children, ln); 434 pgn->unmade--; 435 } 436 } 437 return (0); 438 } 439 static int 440 MakeHandleUse (pgn, cgn) 441 ClientData pgn; /* the current parent */ 442 ClientData cgn; /* the child we've just examined */ 443 { 444 return Make_HandleUse((GNode *) pgn, (GNode *) cgn); 445 } 446 447 448 /*- 449 *----------------------------------------------------------------------- 450 * Make_Recheck -- 451 * Check the modification time of a gnode, and update it as described 452 * in the comments below. 453 * 454 * Results: 455 * returns 0 if the gnode does not exist, or it's filesystem 456 * time if it does. 457 * 458 * Side Effects: 459 * the gnode's modification time and path name are affected. 460 * 461 *----------------------------------------------------------------------- 462 */ 463 time_t 464 Make_Recheck (gn) 465 GNode *gn; 466 { 467 time_t mtime = Dir_MTime(gn); 468 469 #ifndef RECHECK 470 /* 471 * We can't re-stat the thing, but we can at least take care of rules 472 * where a target depends on a source that actually creates the 473 * target, but only if it has changed, e.g. 474 * 475 * parse.h : parse.o 476 * 477 * parse.o : parse.y 478 * yacc -d parse.y 479 * cc -c y.tab.c 480 * mv y.tab.o parse.o 481 * cmp -s y.tab.h parse.h || mv y.tab.h parse.h 482 * 483 * In this case, if the definitions produced by yacc haven't changed 484 * from before, parse.h won't have been updated and gn->mtime will 485 * reflect the current modification time for parse.h. This is 486 * something of a kludge, I admit, but it's a useful one.. 487 * XXX: People like to use a rule like 488 * 489 * FRC: 490 * 491 * To force things that depend on FRC to be made, so we have to 492 * check for gn->children being empty as well... 493 */ 494 if (!Lst_IsEmpty(gn->commands) || Lst_IsEmpty(gn->children)) { 495 gn->mtime = now; 496 } 497 #else 498 /* 499 * This is what Make does and it's actually a good thing, as it 500 * allows rules like 501 * 502 * cmp -s y.tab.h parse.h || cp y.tab.h parse.h 503 * 504 * to function as intended. Unfortunately, thanks to the stateless 505 * nature of NFS (by which I mean the loose coupling of two clients 506 * using the same file from a common server), there are times 507 * when the modification time of a file created on a remote 508 * machine will not be modified before the local stat() implied by 509 * the Dir_MTime occurs, thus leading us to believe that the file 510 * is unchanged, wreaking havoc with files that depend on this one. 511 * 512 * I have decided it is better to make too much than to make too 513 * little, so this stuff is commented out unless you're sure it's ok. 514 * -- ardeb 1/12/88 515 */ 516 /* 517 * Christos, 4/9/92: If we are saving commands pretend that 518 * the target is made now. Otherwise archives with ... rules 519 * don't work! 520 */ 521 if ((noExecute && !(gn->type & OP_MAKE)) || 522 (gn->type & OP_SAVE_CMDS) || mtime == 0) { 523 if (DEBUG(MAKE)) { 524 printf("update time to now: %s\n", Targ_FmtTime(gn->mtime)); 525 } 526 gn->mtime = now; 527 } 528 else { 529 if (DEBUG(MAKE)) { 530 printf("current update time: %s\n", Targ_FmtTime(gn->mtime)); 531 } 532 } 533 #endif 534 return mtime; 535 } 536 537 /*- 538 *----------------------------------------------------------------------- 539 * Make_Update -- 540 * Perform update on the parents of a node. Used by JobFinish once 541 * a node has been dealt with and by MakeStartJobs if it finds an 542 * up-to-date node. 543 * 544 * Results: 545 * Always returns 0 546 * 547 * Side Effects: 548 * The unmade field of pgn is decremented and pgn may be placed on 549 * the toBeMade queue if this field becomes 0. 550 * 551 * If the child was made, the parent's flag CHILDMADE field will be 552 * set true and its cmtime set to now. 553 * 554 * If the child is not up-to-date and still does not exist, 555 * set the FORCE flag on the parents. 556 * 557 * If the child wasn't made, the cmtime field of the parent will be 558 * altered if the child's mtime is big enough. 559 * 560 * Finally, if the child is the implied source for the parent, the 561 * parent's IMPSRC variable is set appropriately. 562 * 563 *----------------------------------------------------------------------- 564 */ 565 void 566 Make_Update (cgn) 567 register GNode *cgn; /* the child node */ 568 { 569 register GNode *pgn; /* the parent node */ 570 register char *cname; /* the child's name */ 571 register LstNode ln; /* Element in parents and iParents lists */ 572 time_t mtime = -1; 573 char *p1; 574 575 cname = Var_Value (TARGET, cgn, &p1); 576 if (p1) 577 free(p1); 578 579 /* 580 * If the child was actually made, see what its modification time is 581 * now -- some rules won't actually update the file. If the file still 582 * doesn't exist, make its mtime now. 583 */ 584 if (cgn->made != UPTODATE) { 585 mtime = Make_Recheck(cgn); 586 } 587 588 if (Lst_Open (cgn->parents) == SUCCESS) { 589 while ((ln = Lst_Next (cgn->parents)) != NILLNODE) { 590 pgn = (GNode *)Lst_Datum (ln); 591 if (mtime == 0) 592 pgn->flags |= FORCE; 593 if (pgn->flags & REMAKE) { 594 pgn->unmade -= 1; 595 596 if ( ! (cgn->type & (OP_EXEC|OP_USE))) { 597 if (cgn->made == MADE) 598 pgn->flags |= CHILDMADE; 599 (void)Make_TimeStamp (pgn, cgn); 600 } 601 if (pgn->unmade == 0) { 602 /* 603 * Queue the node up -- any unmade predecessors will 604 * be dealt with in MakeStartJobs. 605 */ 606 (void)Lst_EnQueue (toBeMade, (ClientData)pgn); 607 } else if (pgn->unmade < 0) { 608 Error ("Graph cycles through %s", pgn->name); 609 } 610 } 611 } 612 Lst_Close (cgn->parents); 613 } 614 /* 615 * Deal with successor nodes. If any is marked for making and has an unmade 616 * count of 0, has not been made and isn't in the examination queue, 617 * it means we need to place it in the queue as it restrained itself 618 * before. 619 */ 620 for (ln = Lst_First(cgn->successors); ln != NILLNODE; ln = Lst_Succ(ln)) { 621 GNode *succ = (GNode *)Lst_Datum(ln); 622 623 if ((succ->flags & REMAKE) && succ->unmade == 0 && succ->made == UNMADE && 624 Lst_Member(toBeMade, (ClientData)succ) == NILLNODE) 625 { 626 (void)Lst_EnQueue(toBeMade, (ClientData)succ); 627 } 628 } 629 630 /* 631 * Set the .PREFIX and .IMPSRC variables for all the implied parents 632 * of this node. 633 */ 634 if (Lst_Open (cgn->iParents) == SUCCESS) { 635 char *p1; 636 char *cpref = Var_Value(PREFIX, cgn, &p1); 637 638 while ((ln = Lst_Next (cgn->iParents)) != NILLNODE) { 639 pgn = (GNode *)Lst_Datum (ln); 640 if (pgn->flags & REMAKE) { 641 Var_Set (IMPSRC, cname, pgn); 642 Var_Set (PREFIX, cpref, pgn); 643 } 644 } 645 if (p1) 646 free(p1); 647 Lst_Close (cgn->iParents); 648 } 649 } 650 651 /*- 652 *----------------------------------------------------------------------- 653 * MakeAddAllSrc -- 654 * Add a child's name to the ALLSRC and OODATE variables of the given 655 * node. Called from Make_DoAllVar via Lst_ForEach. A child is added only 656 * if it has not been given the .EXEC, .USE or .INVISIBLE attributes. 657 * .EXEC and .USE children are very rarely going to be files, so... 658 * A child is added to the OODATE variable if its modification time is 659 * later than that of its parent, as defined by Make, except if the 660 * parent is a .JOIN node. In that case, it is only added to the OODATE 661 * variable if it was actually made (since .JOIN nodes don't have 662 * modification times, the comparison is rather unfair...).. 663 * 664 * Results: 665 * Always returns 0 666 * 667 * Side Effects: 668 * The ALLSRC variable for the given node is extended. 669 *----------------------------------------------------------------------- 670 */ 671 static int 672 MakeAddAllSrc (cgnp, pgnp) 673 ClientData cgnp; /* The child to add */ 674 ClientData pgnp; /* The parent to whose ALLSRC variable it should be */ 675 /* added */ 676 { 677 GNode *cgn = (GNode *) cgnp; 678 GNode *pgn = (GNode *) pgnp; 679 if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) { 680 char *child; 681 char *p1 = NULL; 682 683 if (cgn->type & OP_ARCHV) 684 child = Var_Value (MEMBER, cgn, &p1); 685 else 686 child = cgn->path ? cgn->path : cgn->name; 687 Var_Append (ALLSRC, child, pgn); 688 if (pgn->type & OP_JOIN) { 689 if (cgn->made == MADE) { 690 Var_Append(OODATE, child, pgn); 691 } 692 } else if ((pgn->mtime < cgn->mtime) || 693 (cgn->mtime >= now && cgn->made == MADE)) 694 { 695 /* 696 * It goes in the OODATE variable if the parent is younger than the 697 * child or if the child has been modified more recently than 698 * the start of the make. This is to keep pmake from getting 699 * confused if something else updates the parent after the 700 * make starts (shouldn't happen, I know, but sometimes it 701 * does). In such a case, if we've updated the kid, the parent 702 * is likely to have a modification time later than that of 703 * the kid and anything that relies on the OODATE variable will 704 * be hosed. 705 * 706 * XXX: This will cause all made children to go in the OODATE 707 * variable, even if they're not touched, if RECHECK isn't defined, 708 * since cgn->mtime is set to now in Make_Update. According to 709 * some people, this is good... 710 */ 711 Var_Append(OODATE, child, pgn); 712 } 713 if (p1) 714 free(p1); 715 } 716 return (0); 717 } 718 719 /*- 720 *----------------------------------------------------------------------- 721 * Make_DoAllVar -- 722 * Set up the ALLSRC and OODATE variables. Sad to say, it must be 723 * done separately, rather than while traversing the graph. This is 724 * because Make defined OODATE to contain all sources whose modification 725 * times were later than that of the target, *not* those sources that 726 * were out-of-date. Since in both compatibility and native modes, 727 * the modification time of the parent isn't found until the child 728 * has been dealt with, we have to wait until now to fill in the 729 * variable. As for ALLSRC, the ordering is important and not 730 * guaranteed when in native mode, so it must be set here, too. 731 * 732 * Results: 733 * None 734 * 735 * Side Effects: 736 * The ALLSRC and OODATE variables of the given node is filled in. 737 * If the node is a .JOIN node, its TARGET variable will be set to 738 * match its ALLSRC variable. 739 *----------------------------------------------------------------------- 740 */ 741 void 742 Make_DoAllVar (gn) 743 GNode *gn; 744 { 745 Lst_ForEach (gn->children, MakeAddAllSrc, (ClientData) gn); 746 747 if (!Var_Exists (OODATE, gn)) { 748 Var_Set (OODATE, "", gn); 749 } 750 if (!Var_Exists (ALLSRC, gn)) { 751 Var_Set (ALLSRC, "", gn); 752 } 753 754 if (gn->type & OP_JOIN) { 755 char *p1; 756 Var_Set (TARGET, Var_Value (ALLSRC, gn, &p1), gn); 757 if (p1) 758 free(p1); 759 } 760 } 761 762 /*- 763 *----------------------------------------------------------------------- 764 * MakeStartJobs -- 765 * Start as many jobs as possible. 766 * 767 * Results: 768 * If the query flag was given to pmake, no job will be started, 769 * but as soon as an out-of-date target is found, this function 770 * returns TRUE. At all other times, this function returns FALSE. 771 * 772 * Side Effects: 773 * Nodes are removed from the toBeMade queue and job table slots 774 * are filled. 775 * 776 *----------------------------------------------------------------------- 777 */ 778 static Boolean 779 MakeStartJobs () 780 { 781 register GNode *gn; 782 783 while (!Job_Full() && !Lst_IsEmpty (toBeMade)) { 784 gn = (GNode *) Lst_DeQueue (toBeMade); 785 if (DEBUG(MAKE)) { 786 printf ("Examining %s...", gn->name); 787 } 788 /* 789 * Make sure any and all predecessors that are going to be made, 790 * have been. 791 */ 792 if (!Lst_IsEmpty(gn->preds)) { 793 LstNode ln; 794 795 for (ln = Lst_First(gn->preds); ln != NILLNODE; ln = Lst_Succ(ln)){ 796 GNode *pgn = (GNode *)Lst_Datum(ln); 797 798 if ((pgn->flags & REMAKE) && pgn->made == UNMADE) { 799 if (DEBUG(MAKE)) { 800 printf("predecessor %s not made yet.\n", pgn->name); 801 } 802 break; 803 } 804 } 805 /* 806 * If ln isn't nil, there's a predecessor as yet unmade, so we 807 * just drop this node on the floor. When the node in question 808 * has been made, it will notice this node as being ready to 809 * make but as yet unmade and will place the node on the queue. 810 */ 811 if (ln != NILLNODE) { 812 continue; 813 } 814 } 815 816 numNodes--; 817 if (Make_OODate (gn)) { 818 if (DEBUG(MAKE)) { 819 printf ("out-of-date\n"); 820 } 821 if (queryFlag) { 822 return (TRUE); 823 } 824 Make_DoAllVar (gn); 825 Job_Make (gn); 826 } else { 827 if (DEBUG(MAKE)) { 828 printf ("up-to-date\n"); 829 } 830 gn->made = UPTODATE; 831 if (gn->type & OP_JOIN) { 832 /* 833 * Even for an up-to-date .JOIN node, we need it to have its 834 * context variables so references to it get the correct 835 * value for .TARGET when building up the context variables 836 * of its parent(s)... 837 */ 838 Make_DoAllVar (gn); 839 } 840 841 Make_Update (gn); 842 } 843 } 844 return (FALSE); 845 } 846 847 /*- 848 *----------------------------------------------------------------------- 849 * MakePrintStatus -- 850 * Print the status of a top-level node, viz. it being up-to-date 851 * already or not created due to an error in a lower level. 852 * Callback function for Make_Run via Lst_ForEach. 853 * 854 * Results: 855 * Always returns 0. 856 * 857 * Side Effects: 858 * A message may be printed. 859 * 860 *----------------------------------------------------------------------- 861 */ 862 static int 863 MakePrintStatus(gnp, cyclep) 864 ClientData gnp; /* Node to examine */ 865 ClientData cyclep; /* True if gn->unmade being non-zero implies 866 * a cycle in the graph, not an error in an 867 * inferior */ 868 { 869 GNode *gn = (GNode *) gnp; 870 Boolean cycle = *(Boolean *) cyclep; 871 if (gn->made == UPTODATE) { 872 printf ("`%s' is up to date.\n", gn->name); 873 } else if (gn->unmade != 0) { 874 if (cycle) { 875 Boolean t = TRUE; 876 /* 877 * If printing cycles and came to one that has unmade children, 878 * print out the cycle by recursing on its children. Note a 879 * cycle like: 880 * a : b 881 * b : c 882 * c : b 883 * will cause this to erroneously complain about a being in 884 * the cycle, but this is a good approximation. 885 */ 886 if (gn->made == CYCLE) { 887 Error("Graph cycles through `%s'", gn->name); 888 gn->made = ENDCYCLE; 889 Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); 890 gn->made = UNMADE; 891 } else if (gn->made != ENDCYCLE) { 892 gn->made = CYCLE; 893 Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); 894 } 895 } else { 896 printf ("`%s' not remade because of errors.\n", gn->name); 897 } 898 } 899 return (0); 900 } 901 902 903 /*- 904 *----------------------------------------------------------------------- 905 * Make_ExpandUse -- 906 * Expand .USE nodes and create a new targets list 907 * Results: 908 * The new list of targets. 909 * 910 * Side Effects: 911 * numNodes is set to the number of elements in the list of targets. 912 *----------------------------------------------------------------------- 913 */ 914 Lst 915 Make_ExpandUse (targs) 916 Lst targs; /* the initial list of targets */ 917 { 918 register GNode *gn; /* a temporary pointer */ 919 register Lst examine; /* List of targets to examine */ 920 register Lst ntargs; /* List of new targets to be made */ 921 922 ntargs = Lst_Init (FALSE); 923 924 examine = Lst_Duplicate(targs, NOCOPY); 925 numNodes = 0; 926 927 /* 928 * Make an initial downward pass over the graph, marking nodes to be made 929 * as we go down. We call Suff_FindDeps to find where a node is and 930 * to get some children for it if it has none and also has no commands. 931 * If the node is a leaf, we stick it on the toBeMade queue to 932 * be looked at in a minute, otherwise we add its children to our queue 933 * and go on about our business. 934 */ 935 while (!Lst_IsEmpty (examine)) { 936 gn = (GNode *) Lst_DeQueue (examine); 937 938 if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) { 939 Lst new; 940 new = Lst_Duplicate (gn->cohorts, NOCOPY); 941 Lst_Concat (new, examine, LST_CONCLINK); 942 examine = new; 943 } 944 945 if ((gn->flags & REMAKE) == 0) { 946 gn->flags |= REMAKE; 947 numNodes++; 948 949 /* 950 * Apply any .USE rules before looking for implicit dependencies 951 * to make sure everything has commands that should... 952 * Make sure that the TARGET is set, so that we can make 953 * expansions. 954 */ 955 if (gn->type & OP_ARCHV) { 956 char *eoa, *eon; 957 eoa = strchr(gn->name, '('); 958 eon = strchr(gn->name, ')'); 959 if (eoa == NULL || eon == NULL) 960 continue; 961 *eoa = '\0'; 962 *eon = '\0'; 963 Var_Set (MEMBER, eoa + 1, gn); 964 Var_Set (ARCHIVE, gn->name, gn); 965 *eoa = '('; 966 *eon = ')'; 967 } 968 969 (void)Dir_MTime(gn); 970 Var_Set (TARGET, gn->path ? gn->path : gn->name, gn); 971 Lst_ForEach (gn->children, MakeHandleUse, (ClientData)gn); 972 Suff_FindDeps (gn); 973 974 if (gn->unmade != 0 && (gn->type & OP_MADE) == 0) { 975 Lst_ForEach (gn->children, MakeAddChild, (ClientData)examine); 976 } else { 977 (void)Lst_EnQueue (ntargs, (ClientData)gn); 978 if (gn->type & OP_MADE) 979 Lst_ForEach (gn->children, MakeFindChild, (ClientData)gn); 980 } 981 } 982 } 983 984 Lst_Destroy (examine, NOFREE); 985 return ntargs; 986 } 987 988 /*- 989 *----------------------------------------------------------------------- 990 * Make_Run -- 991 * Initialize the nodes to remake and the list of nodes which are 992 * ready to be made by doing a breadth-first traversal of the graph 993 * starting from the nodes in the given list. Once this traversal 994 * is finished, all the 'leaves' of the graph are in the toBeMade 995 * queue. 996 * Using this queue and the Job module, work back up the graph, 997 * calling on MakeStartJobs to keep the job table as full as 998 * possible. 999 * 1000 * Results: 1001 * TRUE if work was done. FALSE otherwise. 1002 * 1003 * Side Effects: 1004 * The make field of all nodes involved in the creation of the given 1005 * targets is set to 1. The toBeMade list is set to contain all the 1006 * 'leaves' of these subgraphs. 1007 *----------------------------------------------------------------------- 1008 */ 1009 Boolean 1010 Make_Run (targs) 1011 Lst targs; /* the initial list of targets */ 1012 { 1013 int errors; /* Number of errors the Job module reports */ 1014 1015 toBeMade = Make_ExpandUse (targs); 1016 1017 if (queryFlag) { 1018 /* 1019 * We wouldn't do any work unless we could start some jobs in the 1020 * next loop... (we won't actually start any, of course, this is just 1021 * to see if any of the targets was out of date) 1022 */ 1023 return (MakeStartJobs()); 1024 } else { 1025 /* 1026 * Initialization. At the moment, no jobs are running and until some 1027 * get started, nothing will happen since the remaining upward 1028 * traversal of the graph is performed by the routines in job.c upon 1029 * the finishing of a job. So we fill the Job table as much as we can 1030 * before going into our loop. 1031 */ 1032 (void) MakeStartJobs(); 1033 } 1034 1035 /* 1036 * Main Loop: The idea here is that the ending of jobs will take 1037 * care of the maintenance of data structures and the waiting for output 1038 * will cause us to be idle most of the time while our children run as 1039 * much as possible. Because the job table is kept as full as possible, 1040 * the only time when it will be empty is when all the jobs which need 1041 * running have been run, so that is the end condition of this loop. 1042 * Note that the Job module will exit if there were any errors unless the 1043 * keepgoing flag was given. 1044 */ 1045 while (!Job_Empty ()) { 1046 Job_CatchOutput (); 1047 Job_CatchChildren (!usePipes); 1048 (void)MakeStartJobs(); 1049 } 1050 1051 errors = Job_Finish(); 1052 1053 /* 1054 * Print the final status of each target. E.g. if it wasn't made 1055 * because some inferior reported an error. 1056 */ 1057 errors = ((errors == 0) && (numNodes != 0)); 1058 Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors); 1059 1060 return (TRUE); 1061 } 1062