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