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