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