make.c revision 1.121 1 1.121 rillig /* $NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $ */
2 1.7 christos
3 1.1 cgd /*
4 1.10 christos * Copyright (c) 1988, 1989, 1990, 1993
5 1.10 christos * The Regents of the University of California. All rights reserved.
6 1.51 agc *
7 1.51 agc * This code is derived from software contributed to Berkeley by
8 1.51 agc * Adam de Boor.
9 1.51 agc *
10 1.51 agc * Redistribution and use in source and binary forms, with or without
11 1.51 agc * modification, are permitted provided that the following conditions
12 1.51 agc * are met:
13 1.51 agc * 1. Redistributions of source code must retain the above copyright
14 1.51 agc * notice, this list of conditions and the following disclaimer.
15 1.51 agc * 2. Redistributions in binary form must reproduce the above copyright
16 1.51 agc * notice, this list of conditions and the following disclaimer in the
17 1.51 agc * documentation and/or other materials provided with the distribution.
18 1.51 agc * 3. Neither the name of the University nor the names of its contributors
19 1.51 agc * may be used to endorse or promote products derived from this software
20 1.51 agc * without specific prior written permission.
21 1.51 agc *
22 1.51 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 1.51 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 1.51 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 1.51 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 1.51 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 1.51 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 1.51 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 1.51 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 1.51 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 1.51 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 1.51 agc * SUCH DAMAGE.
33 1.51 agc */
34 1.51 agc
35 1.51 agc /*
36 1.1 cgd * Copyright (c) 1989 by Berkeley Softworks
37 1.1 cgd * All rights reserved.
38 1.1 cgd *
39 1.1 cgd * This code is derived from software contributed to Berkeley by
40 1.1 cgd * Adam de Boor.
41 1.1 cgd *
42 1.1 cgd * Redistribution and use in source and binary forms, with or without
43 1.1 cgd * modification, are permitted provided that the following conditions
44 1.1 cgd * are met:
45 1.1 cgd * 1. Redistributions of source code must retain the above copyright
46 1.1 cgd * notice, this list of conditions and the following disclaimer.
47 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
48 1.1 cgd * notice, this list of conditions and the following disclaimer in the
49 1.1 cgd * documentation and/or other materials provided with the distribution.
50 1.1 cgd * 3. All advertising materials mentioning features or use of this software
51 1.1 cgd * must display the following acknowledgement:
52 1.1 cgd * This product includes software developed by the University of
53 1.1 cgd * California, Berkeley and its contributors.
54 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
55 1.1 cgd * may be used to endorse or promote products derived from this software
56 1.1 cgd * without specific prior written permission.
57 1.1 cgd *
58 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 1.1 cgd * SUCH DAMAGE.
69 1.1 cgd */
70 1.1 cgd
71 1.53 ross #ifndef MAKE_NATIVE
72 1.121 rillig static char rcsid[] = "$NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $";
73 1.19 lukem #else
74 1.18 christos #include <sys/cdefs.h>
75 1.1 cgd #ifndef lint
76 1.7 christos #if 0
77 1.10 christos static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
78 1.7 christos #else
79 1.121 rillig __RCSID("$NetBSD: make.c,v 1.121 2020/08/22 22:57:53 rillig Exp $");
80 1.7 christos #endif
81 1.1 cgd #endif /* not lint */
82 1.19 lukem #endif
83 1.1 cgd
84 1.1 cgd /*-
85 1.1 cgd * make.c --
86 1.1 cgd * The functions which perform the examination of targets and
87 1.1 cgd * their suitability for creation
88 1.1 cgd *
89 1.1 cgd * Interface:
90 1.1 cgd * Make_Run Initialize things for the module and recreate
91 1.1 cgd * whatever needs recreating. Returns TRUE if
92 1.1 cgd * work was (or would have been) done and FALSE
93 1.1 cgd * otherwise.
94 1.1 cgd *
95 1.1 cgd * Make_Update Update all parents of a given child. Performs
96 1.1 cgd * various bookkeeping chores like the updating
97 1.83 christos * of the cmgn field of the parent, filling
98 1.1 cgd * of the IMPSRC context variable, etc. It will
99 1.1 cgd * place the parent on the toBeMade queue if it
100 1.1 cgd * should be.
101 1.1 cgd *
102 1.83 christos * Make_TimeStamp Function to set the parent's cmgn field
103 1.1 cgd * based on a child's modification time.
104 1.1 cgd *
105 1.1 cgd * Make_DoAllVar Set up the various local variables for a
106 1.1 cgd * target, including the .ALLSRC variable, making
107 1.1 cgd * sure that any variable that needs to exist
108 1.1 cgd * at the very least has the empty value.
109 1.1 cgd *
110 1.1 cgd * Make_OODate Determine if a target is out-of-date.
111 1.1 cgd *
112 1.1 cgd * Make_HandleUse See if a child is a .USE node for a parent
113 1.1 cgd * and perform the .USE actions if so.
114 1.11 christos *
115 1.68 dsl * Make_ExpandUse Expand .USE nodes
116 1.1 cgd */
117 1.1 cgd
118 1.1 cgd #include "make.h"
119 1.4 cgd #include "hash.h"
120 1.4 cgd #include "dir.h"
121 1.4 cgd #include "job.h"
122 1.1 cgd
123 1.70 dsl static unsigned int checked = 1;/* Sequence # to detect recursion */
124 1.1 cgd static Lst toBeMade; /* The current fringe of the graph. These
125 1.1 cgd * are nodes which await examination by
126 1.1 cgd * MakeOODate. It is added to by
127 1.1 cgd * Make_Update and subtracted from by
128 1.1 cgd * MakeStartJobs */
129 1.1 cgd
130 1.78 dsl static int MakeAddChild(void *, void *);
131 1.78 dsl static int MakeFindChild(void *, void *);
132 1.78 dsl static int MakeUnmark(void *, void *);
133 1.78 dsl static int MakeAddAllSrc(void *, void *);
134 1.78 dsl static int MakeTimeStamp(void *, void *);
135 1.78 dsl static int MakeHandleUse(void *, void *);
136 1.50 wiz static Boolean MakeStartJobs(void);
137 1.78 dsl static int MakePrintStatus(void *, void *);
138 1.78 dsl static int MakeCheckOrder(void *, void *);
139 1.78 dsl static int MakeBuildChild(void *, void *);
140 1.78 dsl static int MakeBuildParent(void *, void *);
141 1.68 dsl
142 1.87 joerg MAKE_ATTR_DEAD static void
143 1.68 dsl make_abort(GNode *gn, int line)
144 1.68 dsl {
145 1.74 dsl static int two = 2;
146 1.74 dsl
147 1.68 dsl fprintf(debug_file, "make_abort from line %d\n", line);
148 1.74 dsl Targ_PrintNode(gn, &two);
149 1.74 dsl Lst_ForEach(toBeMade, Targ_PrintNode, &two);
150 1.68 dsl Targ_PrintGraph(3);
151 1.68 dsl abort();
152 1.68 dsl }
153 1.68 dsl
154 1.1 cgd /*-
155 1.1 cgd *-----------------------------------------------------------------------
156 1.1 cgd * Make_TimeStamp --
157 1.83 christos * Set the cmgn field of a parent node based on the mtime stamp in its
158 1.10 christos * child. Called from MakeOODate via Lst_ForEach.
159 1.1 cgd *
160 1.50 wiz * Input:
161 1.50 wiz * pgn the current parent
162 1.50 wiz * cgn the child we've just examined
163 1.50 wiz *
164 1.1 cgd * Results:
165 1.10 christos * Always returns 0.
166 1.1 cgd *
167 1.1 cgd * Side Effects:
168 1.83 christos * The cmgn of the parent node will be changed if the mtime
169 1.1 cgd * field of the child is greater than it.
170 1.1 cgd *-----------------------------------------------------------------------
171 1.1 cgd */
172 1.1 cgd int
173 1.50 wiz Make_TimeStamp(GNode *pgn, GNode *cgn)
174 1.1 cgd {
175 1.83 christos if (pgn->cmgn == NULL || cgn->mtime > pgn->cmgn->mtime) {
176 1.83 christos pgn->cmgn = cgn;
177 1.1 cgd }
178 1.98 rillig return 0;
179 1.1 cgd }
180 1.5 jtc
181 1.50 wiz /*
182 1.50 wiz * Input:
183 1.50 wiz * pgn the current parent
184 1.50 wiz * cgn the child we've just examined
185 1.50 wiz *
186 1.50 wiz */
187 1.5 jtc static int
188 1.78 dsl MakeTimeStamp(void *pgn, void *cgn)
189 1.5 jtc {
190 1.58 christos return Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
191 1.5 jtc }
192 1.108 rillig
193 1.1 cgd /*-
194 1.1 cgd *-----------------------------------------------------------------------
195 1.1 cgd * Make_OODate --
196 1.1 cgd * See if a given node is out of date with respect to its sources.
197 1.1 cgd * Used by Make_Run when deciding which nodes to place on the
198 1.1 cgd * toBeMade queue initially and by Make_Update to screen out USE and
199 1.1 cgd * EXEC nodes. In the latter case, however, any other sort of node
200 1.1 cgd * must be considered out-of-date since at least one of its children
201 1.1 cgd * will have been recreated.
202 1.1 cgd *
203 1.50 wiz * Input:
204 1.50 wiz * gn the node to check
205 1.50 wiz *
206 1.1 cgd * Results:
207 1.10 christos * TRUE if the node is out of date. FALSE otherwise.
208 1.1 cgd *
209 1.1 cgd * Side Effects:
210 1.83 christos * The mtime field of the node and the cmgn field of its parents
211 1.1 cgd * will/may be changed.
212 1.1 cgd *-----------------------------------------------------------------------
213 1.1 cgd */
214 1.1 cgd Boolean
215 1.50 wiz Make_OODate(GNode *gn)
216 1.1 cgd {
217 1.1 cgd Boolean oodate;
218 1.1 cgd
219 1.1 cgd /*
220 1.1 cgd * Certain types of targets needn't even be sought as their datedness
221 1.1 cgd * doesn't depend on their modification time...
222 1.1 cgd */
223 1.39 christos if ((gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC)) == 0) {
224 1.86 christos (void)Dir_MTime(gn, 1);
225 1.1 cgd if (DEBUG(MAKE)) {
226 1.1 cgd if (gn->mtime != 0) {
227 1.66 dsl fprintf(debug_file, "modified %s...", Targ_FmtTime(gn->mtime));
228 1.1 cgd } else {
229 1.66 dsl fprintf(debug_file, "non-existent...");
230 1.1 cgd }
231 1.1 cgd }
232 1.1 cgd }
233 1.1 cgd
234 1.1 cgd /*
235 1.1 cgd * A target is remade in one of the following circumstances:
236 1.1 cgd * its modification time is smaller than that of its youngest child
237 1.1 cgd * and it would actually be run (has commands or type OP_NOP)
238 1.1 cgd * it's the object of a force operator
239 1.1 cgd * it has no children, was on the lhs of an operator and doesn't exist
240 1.1 cgd * already.
241 1.1 cgd *
242 1.1 cgd * Libraries are only considered out-of-date if the archive module says
243 1.1 cgd * they are.
244 1.1 cgd *
245 1.37 wiz * These weird rules are brought to you by Backward-Compatibility and
246 1.1 cgd * the strange people who wrote 'Make'.
247 1.1 cgd */
248 1.39 christos if (gn->type & (OP_USE|OP_USEBEFORE)) {
249 1.1 cgd /*
250 1.1 cgd * If the node is a USE node it is *never* out of date
251 1.1 cgd * no matter *what*.
252 1.1 cgd */
253 1.1 cgd if (DEBUG(MAKE)) {
254 1.66 dsl fprintf(debug_file, ".USE node...");
255 1.1 cgd }
256 1.1 cgd oodate = FALSE;
257 1.25 sjg } else if ((gn->type & OP_LIB) &&
258 1.25 sjg ((gn->mtime==0) || Arch_IsLib(gn))) {
259 1.1 cgd if (DEBUG(MAKE)) {
260 1.66 dsl fprintf(debug_file, "library...");
261 1.1 cgd }
262 1.6 christos
263 1.6 christos /*
264 1.6 christos * always out of date if no children and :: target
265 1.26 sjg * or non-existent.
266 1.6 christos */
267 1.99 rillig oodate = (gn->mtime == 0 || Arch_LibOODate(gn) ||
268 1.83 christos (gn->cmgn == NULL && (gn->type & OP_DOUBLEDEP)));
269 1.1 cgd } else if (gn->type & OP_JOIN) {
270 1.1 cgd /*
271 1.1 cgd * A target with the .JOIN attribute is only considered
272 1.1 cgd * out-of-date if any of its children was out-of-date.
273 1.1 cgd */
274 1.1 cgd if (DEBUG(MAKE)) {
275 1.66 dsl fprintf(debug_file, ".JOIN node...");
276 1.1 cgd }
277 1.22 christos if (DEBUG(MAKE)) {
278 1.66 dsl fprintf(debug_file, "source %smade...", gn->flags & CHILDMADE ? "" : "not ");
279 1.22 christos }
280 1.52 dsl oodate = (gn->flags & CHILDMADE) ? TRUE : FALSE;
281 1.8 christos } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
282 1.1 cgd /*
283 1.1 cgd * A node which is the object of the force (!) operator or which has
284 1.1 cgd * the .EXEC attribute is always considered out-of-date.
285 1.1 cgd */
286 1.1 cgd if (DEBUG(MAKE)) {
287 1.1 cgd if (gn->type & OP_FORCE) {
288 1.66 dsl fprintf(debug_file, "! operator...");
289 1.8 christos } else if (gn->type & OP_PHONY) {
290 1.66 dsl fprintf(debug_file, ".PHONY node...");
291 1.1 cgd } else {
292 1.66 dsl fprintf(debug_file, ".EXEC node...");
293 1.1 cgd }
294 1.1 cgd }
295 1.1 cgd oodate = TRUE;
296 1.83 christos } else if ((gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) ||
297 1.83 christos (gn->cmgn == NULL &&
298 1.52 dsl ((gn->mtime == 0 && !(gn->type & OP_OPTIONAL))
299 1.52 dsl || gn->type & OP_DOUBLEDEP)))
300 1.1 cgd {
301 1.1 cgd /*
302 1.1 cgd * A node whose modification time is less than that of its
303 1.83 christos * youngest child or that has no children (cmgn == NULL) and
304 1.52 dsl * either doesn't exist (mtime == 0) and it isn't optional
305 1.52 dsl * or was the object of a * :: operator is out-of-date.
306 1.52 dsl * Why? Because that's the way Make does it.
307 1.1 cgd */
308 1.1 cgd if (DEBUG(MAKE)) {
309 1.83 christos if (gn->cmgn != NULL && gn->mtime < gn->cmgn->mtime) {
310 1.83 christos fprintf(debug_file, "modified before source %s...",
311 1.96 sjg gn->cmgn->path ? gn->cmgn->path : gn->cmgn->name);
312 1.1 cgd } else if (gn->mtime == 0) {
313 1.66 dsl fprintf(debug_file, "non-existent and no sources...");
314 1.1 cgd } else {
315 1.66 dsl fprintf(debug_file, ":: operator and no sources...");
316 1.1 cgd }
317 1.1 cgd }
318 1.1 cgd oodate = TRUE;
319 1.1 cgd } else {
320 1.99 rillig /*
321 1.22 christos * When a non-existing child with no sources
322 1.21 christos * (such as a typically used FORCE source) has been made and
323 1.21 christos * the target of the child (usually a directory) has the same
324 1.21 christos * timestamp as the timestamp just given to the non-existing child
325 1.21 christos * after it was considered made.
326 1.21 christos */
327 1.1 cgd if (DEBUG(MAKE)) {
328 1.22 christos if (gn->flags & FORCE)
329 1.66 dsl fprintf(debug_file, "non existing child...");
330 1.1 cgd }
331 1.52 dsl oodate = (gn->flags & FORCE) ? TRUE : FALSE;
332 1.1 cgd }
333 1.1 cgd
334 1.82 sjg #ifdef USE_META
335 1.82 sjg if (useMeta) {
336 1.82 sjg oodate = meta_oodate(gn, oodate);
337 1.82 sjg }
338 1.82 sjg #endif
339 1.82 sjg
340 1.1 cgd /*
341 1.1 cgd * If the target isn't out-of-date, the parents need to know its
342 1.1 cgd * modification time. Note that targets that appear to be out-of-date
343 1.1 cgd * but aren't, because they have no commands and aren't of type OP_NOP,
344 1.1 cgd * have their mtime stay below their children's mtime to keep parents from
345 1.1 cgd * thinking they're out-of-date.
346 1.1 cgd */
347 1.1 cgd if (!oodate) {
348 1.67 dsl Lst_ForEach(gn->parents, MakeTimeStamp, gn);
349 1.1 cgd }
350 1.1 cgd
351 1.98 rillig return oodate;
352 1.1 cgd }
353 1.108 rillig
354 1.1 cgd /*-
355 1.1 cgd *-----------------------------------------------------------------------
356 1.1 cgd * MakeAddChild --
357 1.1 cgd * Function used by Make_Run to add a child to the list l.
358 1.1 cgd * It will only add the child if its make field is FALSE.
359 1.1 cgd *
360 1.50 wiz * Input:
361 1.50 wiz * gnp the node to add
362 1.50 wiz * lp the list to which to add it
363 1.50 wiz *
364 1.1 cgd * Results:
365 1.1 cgd * Always returns 0
366 1.1 cgd *
367 1.1 cgd * Side Effects:
368 1.1 cgd * The given list is extended
369 1.1 cgd *-----------------------------------------------------------------------
370 1.1 cgd */
371 1.1 cgd static int
372 1.78 dsl MakeAddChild(void *gnp, void *lp)
373 1.1 cgd {
374 1.58 christos GNode *gn = (GNode *)gnp;
375 1.5 jtc Lst l = (Lst) lp;
376 1.14 christos
377 1.39 christos if ((gn->flags & REMAKE) == 0 && !(gn->type & (OP_USE|OP_USEBEFORE))) {
378 1.68 dsl if (DEBUG(MAKE))
379 1.68 dsl fprintf(debug_file, "MakeAddChild: need to examine %s%s\n",
380 1.68 dsl gn->name, gn->cohort_num);
381 1.115 rillig Lst_EnqueueS(l, gn);
382 1.1 cgd }
383 1.98 rillig return 0;
384 1.1 cgd }
385 1.108 rillig
386 1.13 christos /*-
387 1.13 christos *-----------------------------------------------------------------------
388 1.13 christos * MakeFindChild --
389 1.13 christos * Function used by Make_Run to find the pathname of a child
390 1.13 christos * that was already made.
391 1.13 christos *
392 1.50 wiz * Input:
393 1.50 wiz * gnp the node to find
394 1.50 wiz *
395 1.13 christos * Results:
396 1.13 christos * Always returns 0
397 1.13 christos *
398 1.13 christos * Side Effects:
399 1.83 christos * The path and mtime of the node and the cmgn of the parent are
400 1.42 pk * updated; the unmade children count of the parent is decremented.
401 1.13 christos *-----------------------------------------------------------------------
402 1.13 christos */
403 1.13 christos static int
404 1.78 dsl MakeFindChild(void *gnp, void *pgnp)
405 1.13 christos {
406 1.58 christos GNode *gn = (GNode *)gnp;
407 1.58 christos GNode *pgn = (GNode *)pgnp;
408 1.14 christos
409 1.85 christos (void)Dir_MTime(gn, 0);
410 1.22 christos Make_TimeStamp(pgn, gn);
411 1.42 pk pgn->unmade--;
412 1.14 christos
413 1.98 rillig return 0;
414 1.13 christos }
415 1.108 rillig
416 1.109 rillig /* Called by Make_Run and SuffApplyTransform on the downward pass to handle
417 1.109 rillig * .USE and transformation nodes, by copying the child node's commands, type
418 1.109 rillig * flags and children to the parent node.
419 1.109 rillig *
420 1.109 rillig * A .USE node is much like an explicit transformation rule, except its
421 1.109 rillig * commands are always added to the target node, even if the target already
422 1.109 rillig * has commands.
423 1.1 cgd *
424 1.50 wiz * Input:
425 1.50 wiz * cgn The .USE node
426 1.50 wiz * pgn The target of the .USE node
427 1.1 cgd */
428 1.43 pk void
429 1.50 wiz Make_HandleUse(GNode *cgn, GNode *pgn)
430 1.1 cgd {
431 1.44 pk LstNode ln; /* An element in the children list */
432 1.44 pk
433 1.44 pk #ifdef DEBUG_SRC
434 1.44 pk if ((cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) == 0) {
435 1.66 dsl fprintf(debug_file, "Make_HandleUse: called for plain node %s\n", cgn->name);
436 1.44 pk return;
437 1.44 pk }
438 1.44 pk #endif
439 1.1 cgd
440 1.44 pk if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) {
441 1.39 christos if (cgn->type & OP_USEBEFORE) {
442 1.112 rillig /* .USEBEFORE */
443 1.112 rillig Lst_PrependAllS(pgn->commands, cgn->commands);
444 1.39 christos } else {
445 1.112 rillig /* .USE, or target has no commands */
446 1.112 rillig Lst_AppendAllS(pgn->commands, cgn->commands);
447 1.39 christos }
448 1.44 pk }
449 1.10 christos
450 1.119 rillig Lst_OpenS(cgn->children);
451 1.119 rillig while ((ln = Lst_NextS(cgn->children)) != NULL) {
452 1.119 rillig GNode *gn = Lst_DatumS(ln);
453 1.11 christos
454 1.119 rillig /*
455 1.119 rillig * Expand variables in the .USE node's name
456 1.119 rillig * and save the unexpanded form.
457 1.119 rillig * We don't need to do this for commands.
458 1.119 rillig * They get expanded properly when we execute.
459 1.119 rillig */
460 1.119 rillig if (gn->uname == NULL) {
461 1.119 rillig gn->uname = gn->name;
462 1.119 rillig } else {
463 1.119 rillig free(gn->name);
464 1.119 rillig }
465 1.119 rillig gn->name = Var_Subst(gn->uname, pgn, VARE_WANTRES);
466 1.119 rillig if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) {
467 1.119 rillig /* See if we have a target for this node. */
468 1.119 rillig GNode *tgn = Targ_FindNode(gn->name, TARG_NOCREATE);
469 1.119 rillig if (tgn != NULL)
470 1.119 rillig gn = tgn;
471 1.119 rillig }
472 1.1 cgd
473 1.119 rillig Lst_AppendS(pgn->children, gn);
474 1.119 rillig Lst_AppendS(gn->parents, pgn);
475 1.119 rillig pgn->unmade += 1;
476 1.44 pk }
477 1.119 rillig Lst_CloseS(cgn->children);
478 1.10 christos
479 1.90 joerg pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM);
480 1.1 cgd }
481 1.31 mycroft
482 1.44 pk /*-
483 1.44 pk *-----------------------------------------------------------------------
484 1.44 pk * MakeHandleUse --
485 1.44 pk * Callback function for Lst_ForEach, used by Make_Run on the downward
486 1.44 pk * pass to handle .USE nodes. Should be called before the children
487 1.44 pk * are enqueued to be looked at by MakeAddChild.
488 1.44 pk * This function calls Make_HandleUse to copy the .USE node's commands,
489 1.44 pk * type flags and children to the parent node.
490 1.44 pk *
491 1.50 wiz * Input:
492 1.50 wiz * cgnp the child we've just examined
493 1.50 wiz * pgnp the current parent
494 1.50 wiz *
495 1.44 pk * Results:
496 1.44 pk * returns 0.
497 1.44 pk *
498 1.44 pk * Side Effects:
499 1.44 pk * After expansion, .USE child nodes are removed from the parent
500 1.44 pk *
501 1.44 pk *-----------------------------------------------------------------------
502 1.44 pk */
503 1.5 jtc static int
504 1.78 dsl MakeHandleUse(void *cgnp, void *pgnp)
505 1.5 jtc {
506 1.58 christos GNode *cgn = (GNode *)cgnp;
507 1.58 christos GNode *pgn = (GNode *)pgnp;
508 1.43 pk LstNode ln; /* An element in the children list */
509 1.44 pk int unmarked;
510 1.44 pk
511 1.44 pk unmarked = ((cgn->type & OP_MARK) == 0);
512 1.44 pk cgn->type |= OP_MARK;
513 1.31 mycroft
514 1.44 pk if ((cgn->type & (OP_USE|OP_USEBEFORE)) == 0)
515 1.98 rillig return 0;
516 1.44 pk
517 1.44 pk if (unmarked)
518 1.43 pk Make_HandleUse(cgn, pgn);
519 1.31 mycroft
520 1.43 pk /*
521 1.43 pk * This child node is now "made", so we decrement the count of
522 1.43 pk * unmade children in the parent... We also remove the child
523 1.43 pk * from the parent's list to accurately reflect the number of decent
524 1.43 pk * children the parent has. This is used by Make_Run to decide
525 1.43 pk * whether to queue the parent or examine its children...
526 1.43 pk */
527 1.118 rillig if ((ln = Lst_MemberS(pgn->children, cgn)) != NULL) {
528 1.105 rillig Lst_RemoveS(pgn->children, ln);
529 1.43 pk pgn->unmade--;
530 1.43 pk }
531 1.98 rillig return 0;
532 1.5 jtc }
533 1.22 christos
534 1.22 christos
535 1.22 christos /*-
536 1.22 christos *-----------------------------------------------------------------------
537 1.22 christos * Make_Recheck --
538 1.22 christos * Check the modification time of a gnode, and update it as described
539 1.22 christos * in the comments below.
540 1.22 christos *
541 1.22 christos * Results:
542 1.91 snj * returns 0 if the gnode does not exist, or its filesystem
543 1.22 christos * time if it does.
544 1.22 christos *
545 1.22 christos * Side Effects:
546 1.22 christos * the gnode's modification time and path name are affected.
547 1.22 christos *
548 1.22 christos *-----------------------------------------------------------------------
549 1.22 christos */
550 1.22 christos time_t
551 1.50 wiz Make_Recheck(GNode *gn)
552 1.22 christos {
553 1.85 christos time_t mtime = Dir_MTime(gn, 1);
554 1.22 christos
555 1.22 christos #ifndef RECHECK
556 1.22 christos /*
557 1.22 christos * We can't re-stat the thing, but we can at least take care of rules
558 1.22 christos * where a target depends on a source that actually creates the
559 1.22 christos * target, but only if it has changed, e.g.
560 1.22 christos *
561 1.22 christos * parse.h : parse.o
562 1.22 christos *
563 1.22 christos * parse.o : parse.y
564 1.22 christos * yacc -d parse.y
565 1.22 christos * cc -c y.tab.c
566 1.22 christos * mv y.tab.o parse.o
567 1.22 christos * cmp -s y.tab.h parse.h || mv y.tab.h parse.h
568 1.22 christos *
569 1.22 christos * In this case, if the definitions produced by yacc haven't changed
570 1.22 christos * from before, parse.h won't have been updated and gn->mtime will
571 1.22 christos * reflect the current modification time for parse.h. This is
572 1.22 christos * something of a kludge, I admit, but it's a useful one..
573 1.22 christos * XXX: People like to use a rule like
574 1.22 christos *
575 1.22 christos * FRC:
576 1.22 christos *
577 1.22 christos * To force things that depend on FRC to be made, so we have to
578 1.22 christos * check for gn->children being empty as well...
579 1.22 christos */
580 1.22 christos if (!Lst_IsEmpty(gn->commands) || Lst_IsEmpty(gn->children)) {
581 1.22 christos gn->mtime = now;
582 1.22 christos }
583 1.22 christos #else
584 1.22 christos /*
585 1.22 christos * This is what Make does and it's actually a good thing, as it
586 1.22 christos * allows rules like
587 1.22 christos *
588 1.22 christos * cmp -s y.tab.h parse.h || cp y.tab.h parse.h
589 1.22 christos *
590 1.22 christos * to function as intended. Unfortunately, thanks to the stateless
591 1.22 christos * nature of NFS (by which I mean the loose coupling of two clients
592 1.22 christos * using the same file from a common server), there are times
593 1.22 christos * when the modification time of a file created on a remote
594 1.22 christos * machine will not be modified before the local stat() implied by
595 1.22 christos * the Dir_MTime occurs, thus leading us to believe that the file
596 1.22 christos * is unchanged, wreaking havoc with files that depend on this one.
597 1.22 christos *
598 1.22 christos * I have decided it is better to make too much than to make too
599 1.22 christos * little, so this stuff is commented out unless you're sure it's ok.
600 1.22 christos * -- ardeb 1/12/88
601 1.22 christos */
602 1.22 christos /*
603 1.22 christos * Christos, 4/9/92: If we are saving commands pretend that
604 1.22 christos * the target is made now. Otherwise archives with ... rules
605 1.22 christos * don't work!
606 1.22 christos */
607 1.73 dsl if (NoExecute(gn) || (gn->type & OP_SAVE_CMDS) ||
608 1.73 dsl (mtime == 0 && !(gn->type & OP_WAIT))) {
609 1.22 christos if (DEBUG(MAKE)) {
610 1.73 dsl fprintf(debug_file, " recheck(%s): update time from %s to now\n",
611 1.42 pk gn->name, Targ_FmtTime(gn->mtime));
612 1.22 christos }
613 1.22 christos gn->mtime = now;
614 1.22 christos }
615 1.22 christos else {
616 1.22 christos if (DEBUG(MAKE)) {
617 1.66 dsl fprintf(debug_file, " recheck(%s): current update time: %s\n",
618 1.42 pk gn->name, Targ_FmtTime(gn->mtime));
619 1.22 christos }
620 1.22 christos }
621 1.22 christos #endif
622 1.22 christos return mtime;
623 1.22 christos }
624 1.22 christos
625 1.1 cgd /*-
626 1.1 cgd *-----------------------------------------------------------------------
627 1.1 cgd * Make_Update --
628 1.1 cgd * Perform update on the parents of a node. Used by JobFinish once
629 1.1 cgd * a node has been dealt with and by MakeStartJobs if it finds an
630 1.10 christos * up-to-date node.
631 1.1 cgd *
632 1.50 wiz * Input:
633 1.50 wiz * cgn the child node
634 1.50 wiz *
635 1.1 cgd * Results:
636 1.1 cgd * Always returns 0
637 1.1 cgd *
638 1.1 cgd * Side Effects:
639 1.1 cgd * The unmade field of pgn is decremented and pgn may be placed on
640 1.1 cgd * the toBeMade queue if this field becomes 0.
641 1.1 cgd *
642 1.22 christos * If the child was made, the parent's flag CHILDMADE field will be
643 1.83 christos * set true.
644 1.22 christos *
645 1.22 christos * If the child is not up-to-date and still does not exist,
646 1.22 christos * set the FORCE flag on the parents.
647 1.1 cgd *
648 1.83 christos * If the child wasn't made, the cmgn field of the parent will be
649 1.1 cgd * altered if the child's mtime is big enough.
650 1.1 cgd *
651 1.1 cgd * Finally, if the child is the implied source for the parent, the
652 1.1 cgd * parent's IMPSRC variable is set appropriately.
653 1.1 cgd *
654 1.1 cgd *-----------------------------------------------------------------------
655 1.1 cgd */
656 1.1 cgd void
657 1.50 wiz Make_Update(GNode *cgn)
658 1.1 cgd {
659 1.44 pk GNode *pgn; /* the parent node */
660 1.102 rillig const char *cname; /* the child's name */
661 1.44 pk LstNode ln; /* Element in parents and iParents lists */
662 1.44 pk time_t mtime = -1;
663 1.44 pk char *p1;
664 1.47 pk Lst parents;
665 1.47 pk GNode *centurion;
666 1.1 cgd
667 1.70 dsl /* It is save to re-examine any nodes again */
668 1.70 dsl checked++;
669 1.70 dsl
670 1.56 christos cname = Var_Value(TARGET, cgn, &p1);
671 1.103 rillig bmake_free(p1);
672 1.1 cgd
673 1.68 dsl if (DEBUG(MAKE))
674 1.68 dsl fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);
675 1.68 dsl
676 1.1 cgd /*
677 1.1 cgd * If the child was actually made, see what its modification time is
678 1.1 cgd * now -- some rules won't actually update the file. If the file still
679 1.1 cgd * doesn't exist, make its mtime now.
680 1.1 cgd */
681 1.1 cgd if (cgn->made != UPTODATE) {
682 1.22 christos mtime = Make_Recheck(cgn);
683 1.1 cgd }
684 1.10 christos
685 1.47 pk /*
686 1.47 pk * If this is a `::' node, we must consult its first instance
687 1.47 pk * which is where all parents are linked.
688 1.47 pk */
689 1.47 pk if ((centurion = cgn->centurion) != NULL) {
690 1.47 pk if (!Lst_IsEmpty(cgn->parents))
691 1.68 dsl Punt("%s%s: cohort has parents", cgn->name, cgn->cohort_num);
692 1.47 pk centurion->unmade_cohorts -= 1;
693 1.47 pk if (centurion->unmade_cohorts < 0)
694 1.56 christos Error("Graph cycles through centurion %s", centurion->name);
695 1.47 pk } else {
696 1.47 pk centurion = cgn;
697 1.47 pk }
698 1.68 dsl parents = centurion->parents;
699 1.68 dsl
700 1.68 dsl /* If this was a .ORDER node, schedule the RHS */
701 1.68 dsl Lst_ForEach(centurion->order_succ, MakeBuildParent, Lst_First(toBeMade));
702 1.68 dsl
703 1.68 dsl /* Now mark all the parents as having one less unmade child */
704 1.119 rillig Lst_OpenS(parents);
705 1.119 rillig while ((ln = Lst_NextS(parents)) != NULL) {
706 1.119 rillig pgn = Lst_DatumS(ln);
707 1.119 rillig if (DEBUG(MAKE))
708 1.119 rillig fprintf(debug_file, "inspect parent %s%s: flags %x, "
709 1.119 rillig "type %x, made %d, unmade %d ",
710 1.119 rillig pgn->name, pgn->cohort_num, pgn->flags,
711 1.119 rillig pgn->type, pgn->made, pgn->unmade-1);
712 1.119 rillig
713 1.119 rillig if (!(pgn->flags & REMAKE)) {
714 1.119 rillig /* This parent isn't needed */
715 1.119 rillig if (DEBUG(MAKE))
716 1.119 rillig fprintf(debug_file, "- not needed\n");
717 1.119 rillig continue;
718 1.119 rillig }
719 1.119 rillig if (mtime == 0 && !(cgn->type & OP_WAIT))
720 1.119 rillig pgn->flags |= FORCE;
721 1.119 rillig
722 1.119 rillig /*
723 1.119 rillig * If the parent has the .MADE attribute, its timestamp got
724 1.119 rillig * updated to that of its newest child, and its unmake
725 1.119 rillig * child count got set to zero in Make_ExpandUse().
726 1.119 rillig * However other things might cause us to build one of its
727 1.119 rillig * children - and so we mustn't do any processing here when
728 1.119 rillig * the child build finishes.
729 1.119 rillig */
730 1.119 rillig if (pgn->type & OP_MADE) {
731 1.68 dsl if (DEBUG(MAKE))
732 1.119 rillig fprintf(debug_file, "- .MADE\n");
733 1.119 rillig continue;
734 1.119 rillig }
735 1.119 rillig
736 1.119 rillig if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
737 1.119 rillig if (cgn->made == MADE)
738 1.119 rillig pgn->flags |= CHILDMADE;
739 1.119 rillig (void)Make_TimeStamp(pgn, cgn);
740 1.119 rillig }
741 1.68 dsl
742 1.119 rillig /*
743 1.119 rillig * A parent must wait for the completion of all instances
744 1.119 rillig * of a `::' dependency.
745 1.119 rillig */
746 1.119 rillig if (centurion->unmade_cohorts != 0 || centurion->made < MADE) {
747 1.119 rillig if (DEBUG(MAKE))
748 1.119 rillig fprintf(debug_file,
749 1.119 rillig "- centurion made %d, %d unmade cohorts\n",
750 1.119 rillig centurion->made, centurion->unmade_cohorts);
751 1.119 rillig continue;
752 1.119 rillig }
753 1.47 pk
754 1.119 rillig /* One more child of this parent is now made */
755 1.119 rillig pgn->unmade -= 1;
756 1.119 rillig if (pgn->unmade < 0) {
757 1.119 rillig if (DEBUG(MAKE)) {
758 1.119 rillig fprintf(debug_file, "Graph cycles through %s%s\n",
759 1.119 rillig pgn->name, pgn->cohort_num);
760 1.119 rillig Targ_PrintGraph(2);
761 1.47 pk }
762 1.119 rillig Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num);
763 1.119 rillig }
764 1.1 cgd
765 1.119 rillig /* We must always rescan the parents of .WAIT and .ORDER nodes. */
766 1.119 rillig if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)
767 1.119 rillig && !(centurion->flags & DONE_ORDER)) {
768 1.119 rillig if (DEBUG(MAKE))
769 1.119 rillig fprintf(debug_file, "- unmade children\n");
770 1.119 rillig continue;
771 1.119 rillig }
772 1.119 rillig if (pgn->made != DEFERRED) {
773 1.47 pk /*
774 1.119 rillig * Either this parent is on a different branch of the tree,
775 1.119 rillig * or it on the RHS of a .WAIT directive
776 1.119 rillig * or it is already on the toBeMade list.
777 1.47 pk */
778 1.119 rillig if (DEBUG(MAKE))
779 1.119 rillig fprintf(debug_file, "- not deferred\n");
780 1.119 rillig continue;
781 1.119 rillig }
782 1.119 rillig if (pgn->order_pred
783 1.119 rillig && Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) {
784 1.119 rillig /* A .ORDER rule stops us building this */
785 1.119 rillig continue;
786 1.1 cgd }
787 1.119 rillig if (DEBUG(MAKE)) {
788 1.119 rillig static int two = 2;
789 1.119 rillig fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n",
790 1.119 rillig cgn->name, cgn->cohort_num,
791 1.119 rillig pgn->name, pgn->cohort_num, pgn->made);
792 1.119 rillig Targ_PrintNode(pgn, &two);
793 1.119 rillig }
794 1.119 rillig /* Ok, we can schedule the parent again */
795 1.119 rillig pgn->made = REQUESTED;
796 1.119 rillig Lst_EnqueueS(toBeMade, pgn);
797 1.1 cgd }
798 1.119 rillig Lst_CloseS(parents);
799 1.10 christos
800 1.1 cgd /*
801 1.1 cgd * Set the .PREFIX and .IMPSRC variables for all the implied parents
802 1.1 cgd * of this node.
803 1.1 cgd */
804 1.119 rillig Lst_OpenS(cgn->iParents);
805 1.119 rillig {
806 1.102 rillig const char *cpref = Var_Value(PREFIX, cgn, &p1);
807 1.1 cgd
808 1.106 rillig while ((ln = Lst_NextS(cgn->iParents)) != NULL) {
809 1.117 rillig pgn = Lst_DatumS(ln);
810 1.22 christos if (pgn->flags & REMAKE) {
811 1.97 rillig Var_Set(IMPSRC, cname, pgn);
812 1.35 christos if (cpref != NULL)
813 1.97 rillig Var_Set(PREFIX, cpref, pgn);
814 1.1 cgd }
815 1.1 cgd }
816 1.103 rillig bmake_free(p1);
817 1.107 rillig Lst_CloseS(cgn->iParents);
818 1.1 cgd }
819 1.1 cgd }
820 1.108 rillig
821 1.1 cgd /*-
822 1.1 cgd *-----------------------------------------------------------------------
823 1.1 cgd * MakeAddAllSrc --
824 1.1 cgd * Add a child's name to the ALLSRC and OODATE variables of the given
825 1.1 cgd * node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
826 1.1 cgd * if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
827 1.1 cgd * .EXEC and .USE children are very rarely going to be files, so...
828 1.45 pk * If the child is a .JOIN node, its ALLSRC is propagated to the parent.
829 1.45 pk *
830 1.1 cgd * A child is added to the OODATE variable if its modification time is
831 1.1 cgd * later than that of its parent, as defined by Make, except if the
832 1.1 cgd * parent is a .JOIN node. In that case, it is only added to the OODATE
833 1.1 cgd * variable if it was actually made (since .JOIN nodes don't have
834 1.1 cgd * modification times, the comparison is rather unfair...)..
835 1.1 cgd *
836 1.1 cgd * Results:
837 1.1 cgd * Always returns 0
838 1.1 cgd *
839 1.1 cgd * Side Effects:
840 1.1 cgd * The ALLSRC variable for the given node is extended.
841 1.1 cgd *-----------------------------------------------------------------------
842 1.1 cgd */
843 1.1 cgd static int
844 1.87 joerg MakeUnmark(void *cgnp, void *pgnp MAKE_ATTR_UNUSED)
845 1.31 mycroft {
846 1.58 christos GNode *cgn = (GNode *)cgnp;
847 1.31 mycroft
848 1.31 mycroft cgn->type &= ~OP_MARK;
849 1.98 rillig return 0;
850 1.31 mycroft }
851 1.31 mycroft
852 1.50 wiz /*
853 1.50 wiz * Input:
854 1.50 wiz * cgnp The child to add
855 1.50 wiz * pgnp The parent to whose ALLSRC variable it should
856 1.50 wiz * be added
857 1.50 wiz *
858 1.50 wiz */
859 1.31 mycroft static int
860 1.78 dsl MakeAddAllSrc(void *cgnp, void *pgnp)
861 1.1 cgd {
862 1.58 christos GNode *cgn = (GNode *)cgnp;
863 1.58 christos GNode *pgn = (GNode *)pgnp;
864 1.31 mycroft
865 1.31 mycroft if (cgn->type & OP_MARK)
866 1.98 rillig return 0;
867 1.31 mycroft cgn->type |= OP_MARK;
868 1.31 mycroft
869 1.39 christos if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) {
870 1.102 rillig const char *child, *allsrc;
871 1.45 pk char *p1 = NULL, *p2 = NULL;
872 1.1 cgd
873 1.17 christos if (cgn->type & OP_ARCHV)
874 1.56 christos child = Var_Value(MEMBER, cgn, &p1);
875 1.17 christos else
876 1.17 christos child = cgn->path ? cgn->path : cgn->name;
877 1.45 pk if (cgn->type & OP_JOIN) {
878 1.56 christos allsrc = Var_Value(ALLSRC, cgn, &p2);
879 1.45 pk } else {
880 1.45 pk allsrc = child;
881 1.45 pk }
882 1.46 pk if (allsrc != NULL)
883 1.56 christos Var_Append(ALLSRC, allsrc, pgn);
884 1.103 rillig bmake_free(p2);
885 1.1 cgd if (pgn->type & OP_JOIN) {
886 1.1 cgd if (cgn->made == MADE) {
887 1.1 cgd Var_Append(OODATE, child, pgn);
888 1.1 cgd }
889 1.1 cgd } else if ((pgn->mtime < cgn->mtime) ||
890 1.1 cgd (cgn->mtime >= now && cgn->made == MADE))
891 1.1 cgd {
892 1.1 cgd /*
893 1.1 cgd * It goes in the OODATE variable if the parent is younger than the
894 1.1 cgd * child or if the child has been modified more recently than
895 1.1 cgd * the start of the make. This is to keep pmake from getting
896 1.1 cgd * confused if something else updates the parent after the
897 1.1 cgd * make starts (shouldn't happen, I know, but sometimes it
898 1.1 cgd * does). In such a case, if we've updated the kid, the parent
899 1.1 cgd * is likely to have a modification time later than that of
900 1.1 cgd * the kid and anything that relies on the OODATE variable will
901 1.1 cgd * be hosed.
902 1.1 cgd *
903 1.1 cgd * XXX: This will cause all made children to go in the OODATE
904 1.1 cgd * variable, even if they're not touched, if RECHECK isn't defined,
905 1.1 cgd * since cgn->mtime is set to now in Make_Update. According to
906 1.1 cgd * some people, this is good...
907 1.1 cgd */
908 1.1 cgd Var_Append(OODATE, child, pgn);
909 1.1 cgd }
910 1.103 rillig bmake_free(p1);
911 1.1 cgd }
912 1.98 rillig return 0;
913 1.1 cgd }
914 1.108 rillig
915 1.1 cgd /*-
916 1.1 cgd *-----------------------------------------------------------------------
917 1.1 cgd * Make_DoAllVar --
918 1.1 cgd * Set up the ALLSRC and OODATE variables. Sad to say, it must be
919 1.1 cgd * done separately, rather than while traversing the graph. This is
920 1.1 cgd * because Make defined OODATE to contain all sources whose modification
921 1.1 cgd * times were later than that of the target, *not* those sources that
922 1.1 cgd * were out-of-date. Since in both compatibility and native modes,
923 1.1 cgd * the modification time of the parent isn't found until the child
924 1.1 cgd * has been dealt with, we have to wait until now to fill in the
925 1.1 cgd * variable. As for ALLSRC, the ordering is important and not
926 1.1 cgd * guaranteed when in native mode, so it must be set here, too.
927 1.1 cgd *
928 1.1 cgd * Results:
929 1.1 cgd * None
930 1.1 cgd *
931 1.1 cgd * Side Effects:
932 1.1 cgd * The ALLSRC and OODATE variables of the given node is filled in.
933 1.1 cgd * If the node is a .JOIN node, its TARGET variable will be set to
934 1.1 cgd * match its ALLSRC variable.
935 1.1 cgd *-----------------------------------------------------------------------
936 1.1 cgd */
937 1.1 cgd void
938 1.50 wiz Make_DoAllVar(GNode *gn)
939 1.1 cgd {
940 1.79 sjg if (gn->flags & DONE_ALLSRC)
941 1.79 sjg return;
942 1.99 rillig
943 1.67 dsl Lst_ForEach(gn->children, MakeUnmark, gn);
944 1.67 dsl Lst_ForEach(gn->children, MakeAddAllSrc, gn);
945 1.1 cgd
946 1.1 cgd if (!Var_Exists (OODATE, gn)) {
947 1.97 rillig Var_Set(OODATE, "", gn);
948 1.1 cgd }
949 1.1 cgd if (!Var_Exists (ALLSRC, gn)) {
950 1.97 rillig Var_Set(ALLSRC, "", gn);
951 1.1 cgd }
952 1.1 cgd
953 1.1 cgd if (gn->type & OP_JOIN) {
954 1.5 jtc char *p1;
955 1.97 rillig Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn);
956 1.103 rillig bmake_free(p1);
957 1.1 cgd }
958 1.79 sjg gn->flags |= DONE_ALLSRC;
959 1.1 cgd }
960 1.108 rillig
961 1.1 cgd /*-
962 1.1 cgd *-----------------------------------------------------------------------
963 1.1 cgd * MakeStartJobs --
964 1.1 cgd * Start as many jobs as possible.
965 1.1 cgd *
966 1.1 cgd * Results:
967 1.1 cgd * If the query flag was given to pmake, no job will be started,
968 1.1 cgd * but as soon as an out-of-date target is found, this function
969 1.1 cgd * returns TRUE. At all other times, this function returns FALSE.
970 1.1 cgd *
971 1.1 cgd * Side Effects:
972 1.1 cgd * Nodes are removed from the toBeMade queue and job table slots
973 1.1 cgd * are filled.
974 1.1 cgd *
975 1.1 cgd *-----------------------------------------------------------------------
976 1.1 cgd */
977 1.68 dsl
978 1.68 dsl static int
979 1.87 joerg MakeCheckOrder(void *v_bn, void *ignore MAKE_ATTR_UNUSED)
980 1.68 dsl {
981 1.68 dsl GNode *bn = v_bn;
982 1.68 dsl
983 1.68 dsl if (bn->made >= MADE || !(bn->flags & REMAKE))
984 1.68 dsl return 0;
985 1.68 dsl if (DEBUG(MAKE))
986 1.68 dsl fprintf(debug_file, "MakeCheckOrder: Waiting for .ORDER node %s%s\n",
987 1.68 dsl bn->name, bn->cohort_num);
988 1.68 dsl return 1;
989 1.68 dsl }
990 1.68 dsl
991 1.68 dsl static int
992 1.78 dsl MakeBuildChild(void *v_cn, void *toBeMade_next)
993 1.68 dsl {
994 1.68 dsl GNode *cn = v_cn;
995 1.68 dsl
996 1.68 dsl if (DEBUG(MAKE))
997 1.68 dsl fprintf(debug_file, "MakeBuildChild: inspect %s%s, made %d, type %x\n",
998 1.68 dsl cn->name, cn->cohort_num, cn->made, cn->type);
999 1.68 dsl if (cn->made > DEFERRED)
1000 1.68 dsl return 0;
1001 1.68 dsl
1002 1.68 dsl /* If this node is on the RHS of a .ORDER, check LHSs. */
1003 1.68 dsl if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
1004 1.68 dsl /* Can't build this (or anything else in this child list) yet */
1005 1.68 dsl cn->made = DEFERRED;
1006 1.88 sjg return 0; /* but keep looking */
1007 1.68 dsl }
1008 1.68 dsl
1009 1.68 dsl if (DEBUG(MAKE))
1010 1.68 dsl fprintf(debug_file, "MakeBuildChild: schedule %s%s\n",
1011 1.68 dsl cn->name, cn->cohort_num);
1012 1.68 dsl
1013 1.68 dsl cn->made = REQUESTED;
1014 1.77 dsl if (toBeMade_next == NULL)
1015 1.113 rillig Lst_AppendS(toBeMade, cn);
1016 1.68 dsl else
1017 1.116 rillig Lst_InsertBeforeS(toBeMade, toBeMade_next, cn);
1018 1.68 dsl
1019 1.68 dsl if (cn->unmade_cohorts != 0)
1020 1.68 dsl Lst_ForEach(cn->cohorts, MakeBuildChild, toBeMade_next);
1021 1.68 dsl
1022 1.68 dsl /*
1023 1.68 dsl * If this node is a .WAIT node with unmade chlidren
1024 1.68 dsl * then don't add the next sibling.
1025 1.68 dsl */
1026 1.68 dsl return cn->type & OP_WAIT && cn->unmade > 0;
1027 1.68 dsl }
1028 1.68 dsl
1029 1.88 sjg /* When a .ORDER LHS node completes we do this on each RHS */
1030 1.68 dsl static int
1031 1.78 dsl MakeBuildParent(void *v_pn, void *toBeMade_next)
1032 1.68 dsl {
1033 1.68 dsl GNode *pn = v_pn;
1034 1.68 dsl
1035 1.68 dsl if (pn->made != DEFERRED)
1036 1.68 dsl return 0;
1037 1.68 dsl
1038 1.68 dsl if (MakeBuildChild(pn, toBeMade_next) == 0) {
1039 1.68 dsl /* Mark so that when this node is built we reschedule its parents */
1040 1.68 dsl pn->flags |= DONE_ORDER;
1041 1.68 dsl }
1042 1.68 dsl
1043 1.68 dsl return 0;
1044 1.68 dsl }
1045 1.68 dsl
1046 1.1 cgd static Boolean
1047 1.50 wiz MakeStartJobs(void)
1048 1.1 cgd {
1049 1.44 pk GNode *gn;
1050 1.59 dsl int have_token = 0;
1051 1.10 christos
1052 1.115 rillig while (!Lst_IsEmpty(toBeMade)) {
1053 1.60 dsl /* Get token now to avoid cycling job-list when we only have 1 token */
1054 1.60 dsl if (!have_token && !Job_TokenWithdraw())
1055 1.60 dsl break;
1056 1.60 dsl have_token = 1;
1057 1.60 dsl
1058 1.115 rillig gn = Lst_DequeueS(toBeMade);
1059 1.68 dsl if (DEBUG(MAKE))
1060 1.68 dsl fprintf(debug_file, "Examining %s%s...\n",
1061 1.68 dsl gn->name, gn->cohort_num);
1062 1.68 dsl
1063 1.68 dsl if (gn->made != REQUESTED) {
1064 1.68 dsl if (DEBUG(MAKE))
1065 1.68 dsl fprintf(debug_file, "state %d\n", gn->made);
1066 1.68 dsl
1067 1.68 dsl make_abort(gn, __LINE__);
1068 1.1 cgd }
1069 1.1 cgd
1070 1.70 dsl if (gn->checked == checked) {
1071 1.70 dsl /* We've already looked at this node since a job finished... */
1072 1.70 dsl if (DEBUG(MAKE))
1073 1.71 dsl fprintf(debug_file, "already checked %s%s\n",
1074 1.70 dsl gn->name, gn->cohort_num);
1075 1.71 dsl gn->made = DEFERRED;
1076 1.70 dsl continue;
1077 1.70 dsl }
1078 1.70 dsl gn->checked = checked;
1079 1.70 dsl
1080 1.68 dsl if (gn->unmade != 0) {
1081 1.1 cgd /*
1082 1.68 dsl * We can't build this yet, add all unmade children to toBeMade,
1083 1.68 dsl * just before the current first element.
1084 1.1 cgd */
1085 1.68 dsl gn->made = DEFERRED;
1086 1.68 dsl Lst_ForEach(gn->children, MakeBuildChild, Lst_First(toBeMade));
1087 1.68 dsl /* and drop this node on the floor */
1088 1.68 dsl if (DEBUG(MAKE))
1089 1.68 dsl fprintf(debug_file, "dropped %s%s\n", gn->name, gn->cohort_num);
1090 1.68 dsl continue;
1091 1.1 cgd }
1092 1.10 christos
1093 1.68 dsl gn->made = BEINGMADE;
1094 1.56 christos if (Make_OODate(gn)) {
1095 1.1 cgd if (DEBUG(MAKE)) {
1096 1.66 dsl fprintf(debug_file, "out-of-date\n");
1097 1.1 cgd }
1098 1.1 cgd if (queryFlag) {
1099 1.98 rillig return TRUE;
1100 1.1 cgd }
1101 1.56 christos Make_DoAllVar(gn);
1102 1.56 christos Job_Make(gn);
1103 1.59 dsl have_token = 0;
1104 1.1 cgd } else {
1105 1.1 cgd if (DEBUG(MAKE)) {
1106 1.66 dsl fprintf(debug_file, "up-to-date\n");
1107 1.1 cgd }
1108 1.1 cgd gn->made = UPTODATE;
1109 1.1 cgd if (gn->type & OP_JOIN) {
1110 1.1 cgd /*
1111 1.1 cgd * Even for an up-to-date .JOIN node, we need it to have its
1112 1.1 cgd * context variables so references to it get the correct
1113 1.1 cgd * value for .TARGET when building up the context variables
1114 1.1 cgd * of its parent(s)...
1115 1.1 cgd */
1116 1.56 christos Make_DoAllVar(gn);
1117 1.1 cgd }
1118 1.56 christos Make_Update(gn);
1119 1.1 cgd }
1120 1.1 cgd }
1121 1.59 dsl
1122 1.59 dsl if (have_token)
1123 1.59 dsl Job_TokenReturn();
1124 1.59 dsl
1125 1.98 rillig return FALSE;
1126 1.1 cgd }
1127 1.108 rillig
1128 1.1 cgd /*-
1129 1.1 cgd *-----------------------------------------------------------------------
1130 1.1 cgd * MakePrintStatus --
1131 1.1 cgd * Print the status of a top-level node, viz. it being up-to-date
1132 1.1 cgd * already or not created due to an error in a lower level.
1133 1.1 cgd * Callback function for Make_Run via Lst_ForEach.
1134 1.1 cgd *
1135 1.50 wiz * Input:
1136 1.50 wiz * gnp Node to examine
1137 1.50 wiz * cyclep True if gn->unmade being non-zero implies a
1138 1.50 wiz * cycle in the graph, not an error in an
1139 1.50 wiz * inferior.
1140 1.50 wiz *
1141 1.1 cgd * Results:
1142 1.1 cgd * Always returns 0.
1143 1.1 cgd *
1144 1.1 cgd * Side Effects:
1145 1.1 cgd * A message may be printed.
1146 1.1 cgd *
1147 1.1 cgd *-----------------------------------------------------------------------
1148 1.1 cgd */
1149 1.1 cgd static int
1150 1.78 dsl MakePrintStatusOrder(void *ognp, void *gnp)
1151 1.68 dsl {
1152 1.68 dsl GNode *ogn = ognp;
1153 1.68 dsl GNode *gn = gnp;
1154 1.68 dsl
1155 1.68 dsl if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED)
1156 1.68 dsl /* not waiting for this one */
1157 1.68 dsl return 0;
1158 1.68 dsl
1159 1.68 dsl printf(" `%s%s' has .ORDER dependency against %s%s "
1160 1.68 dsl "(made %d, flags %x, type %x)\n",
1161 1.68 dsl gn->name, gn->cohort_num,
1162 1.68 dsl ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type);
1163 1.68 dsl if (DEBUG(MAKE) && debug_file != stdout)
1164 1.68 dsl fprintf(debug_file, " `%s%s' has .ORDER dependency against %s%s "
1165 1.68 dsl "(made %d, flags %x, type %x)\n",
1166 1.68 dsl gn->name, gn->cohort_num,
1167 1.68 dsl ogn->name, ogn->cohort_num, ogn->made, ogn->flags, ogn->type);
1168 1.68 dsl return 0;
1169 1.68 dsl }
1170 1.68 dsl
1171 1.68 dsl static int
1172 1.78 dsl MakePrintStatus(void *gnp, void *v_errors)
1173 1.1 cgd {
1174 1.58 christos GNode *gn = (GNode *)gnp;
1175 1.68 dsl int *errors = v_errors;
1176 1.68 dsl
1177 1.68 dsl if (gn->flags & DONECYCLE)
1178 1.68 dsl /* We've completely processed this node before, don't do it again. */
1179 1.68 dsl return 0;
1180 1.68 dsl
1181 1.68 dsl if (gn->unmade == 0) {
1182 1.68 dsl gn->flags |= DONECYCLE;
1183 1.68 dsl switch (gn->made) {
1184 1.68 dsl case UPTODATE:
1185 1.68 dsl printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num);
1186 1.68 dsl break;
1187 1.68 dsl case MADE:
1188 1.68 dsl break;
1189 1.68 dsl case UNMADE:
1190 1.68 dsl case DEFERRED:
1191 1.68 dsl case REQUESTED:
1192 1.68 dsl case BEINGMADE:
1193 1.68 dsl (*errors)++;
1194 1.68 dsl printf("`%s%s' was not built (made %d, flags %x, type %x)!\n",
1195 1.68 dsl gn->name, gn->cohort_num, gn->made, gn->flags, gn->type);
1196 1.68 dsl if (DEBUG(MAKE) && debug_file != stdout)
1197 1.68 dsl fprintf(debug_file,
1198 1.68 dsl "`%s%s' was not built (made %d, flags %x, type %x)!\n",
1199 1.68 dsl gn->name, gn->cohort_num, gn->made, gn->flags, gn->type);
1200 1.68 dsl /* Most likely problem is actually caused by .ORDER */
1201 1.68 dsl Lst_ForEach(gn->order_pred, MakePrintStatusOrder, gn);
1202 1.68 dsl break;
1203 1.68 dsl default:
1204 1.68 dsl /* Errors - already counted */
1205 1.68 dsl printf("`%s%s' not remade because of errors.\n",
1206 1.68 dsl gn->name, gn->cohort_num);
1207 1.68 dsl if (DEBUG(MAKE) && debug_file != stdout)
1208 1.68 dsl fprintf(debug_file, "`%s%s' not remade because of errors.\n",
1209 1.68 dsl gn->name, gn->cohort_num);
1210 1.68 dsl break;
1211 1.1 cgd }
1212 1.68 dsl return 0;
1213 1.68 dsl }
1214 1.68 dsl
1215 1.68 dsl if (DEBUG(MAKE))
1216 1.68 dsl fprintf(debug_file, "MakePrintStatus: %s%s has %d unmade children\n",
1217 1.68 dsl gn->name, gn->cohort_num, gn->unmade);
1218 1.68 dsl /*
1219 1.68 dsl * If printing cycles and came to one that has unmade children,
1220 1.70 dsl * print out the cycle by recursing on its children.
1221 1.68 dsl */
1222 1.70 dsl if (!(gn->flags & CYCLE)) {
1223 1.70 dsl /* Fist time we've seen this node, check all children */
1224 1.68 dsl gn->flags |= CYCLE;
1225 1.68 dsl Lst_ForEach(gn->children, MakePrintStatus, errors);
1226 1.70 dsl /* Mark that this node needn't be processed again */
1227 1.68 dsl gn->flags |= DONECYCLE;
1228 1.70 dsl return 0;
1229 1.1 cgd }
1230 1.68 dsl
1231 1.70 dsl /* Only output the error once per node */
1232 1.70 dsl gn->flags |= DONECYCLE;
1233 1.70 dsl Error("Graph cycles through `%s%s'", gn->name, gn->cohort_num);
1234 1.70 dsl if ((*errors)++ > 100)
1235 1.70 dsl /* Abandon the whole error report */
1236 1.70 dsl return 1;
1237 1.70 dsl
1238 1.70 dsl /* Reporting for our children will give the rest of the loop */
1239 1.70 dsl Lst_ForEach(gn->children, MakePrintStatus, errors);
1240 1.70 dsl return 0;
1241 1.1 cgd }
1242 1.108 rillig
1243 1.11 christos
1244 1.1 cgd /*-
1245 1.1 cgd *-----------------------------------------------------------------------
1246 1.11 christos * Make_ExpandUse --
1247 1.11 christos * Expand .USE nodes and create a new targets list
1248 1.50 wiz *
1249 1.50 wiz * Input:
1250 1.50 wiz * targs the initial list of targets
1251 1.50 wiz *
1252 1.1 cgd * Side Effects:
1253 1.1 cgd *-----------------------------------------------------------------------
1254 1.1 cgd */
1255 1.68 dsl void
1256 1.50 wiz Make_ExpandUse(Lst targs)
1257 1.1 cgd {
1258 1.44 pk GNode *gn; /* a temporary pointer */
1259 1.44 pk Lst examine; /* List of targets to examine */
1260 1.1 cgd
1261 1.121 rillig examine = Lst_CopyS(targs, NULL);
1262 1.10 christos
1263 1.1 cgd /*
1264 1.1 cgd * Make an initial downward pass over the graph, marking nodes to be made
1265 1.1 cgd * as we go down. We call Suff_FindDeps to find where a node is and
1266 1.1 cgd * to get some children for it if it has none and also has no commands.
1267 1.1 cgd * If the node is a leaf, we stick it on the toBeMade queue to
1268 1.1 cgd * be looked at in a minute, otherwise we add its children to our queue
1269 1.10 christos * and go on about our business.
1270 1.1 cgd */
1271 1.115 rillig while (!Lst_IsEmpty(examine)) {
1272 1.115 rillig gn = Lst_DequeueS(examine);
1273 1.99 rillig
1274 1.68 dsl if (gn->flags & REMAKE)
1275 1.68 dsl /* We've looked at this one already */
1276 1.68 dsl continue;
1277 1.68 dsl gn->flags |= REMAKE;
1278 1.68 dsl if (DEBUG(MAKE))
1279 1.68 dsl fprintf(debug_file, "Make_ExpandUse: examine %s%s\n",
1280 1.68 dsl gn->name, gn->cohort_num);
1281 1.10 christos
1282 1.120 rillig if (gn->type & OP_DOUBLEDEP)
1283 1.120 rillig Lst_PrependAllS(examine, gn->cohorts);
1284 1.10 christos
1285 1.68 dsl /*
1286 1.68 dsl * Apply any .USE rules before looking for implicit dependencies
1287 1.68 dsl * to make sure everything has commands that should...
1288 1.68 dsl * Make sure that the TARGET is set, so that we can make
1289 1.68 dsl * expansions.
1290 1.68 dsl */
1291 1.68 dsl if (gn->type & OP_ARCHV) {
1292 1.68 dsl char *eoa, *eon;
1293 1.68 dsl eoa = strchr(gn->name, '(');
1294 1.68 dsl eon = strchr(gn->name, ')');
1295 1.68 dsl if (eoa == NULL || eon == NULL)
1296 1.68 dsl continue;
1297 1.68 dsl *eoa = '\0';
1298 1.68 dsl *eon = '\0';
1299 1.97 rillig Var_Set(MEMBER, eoa + 1, gn);
1300 1.97 rillig Var_Set(ARCHIVE, gn->name, gn);
1301 1.68 dsl *eoa = '(';
1302 1.68 dsl *eon = ')';
1303 1.68 dsl }
1304 1.68 dsl
1305 1.85 christos (void)Dir_MTime(gn, 0);
1306 1.97 rillig Var_Set(TARGET, gn->path ? gn->path : gn->name, gn);
1307 1.68 dsl Lst_ForEach(gn->children, MakeUnmark, gn);
1308 1.68 dsl Lst_ForEach(gn->children, MakeHandleUse, gn);
1309 1.68 dsl
1310 1.68 dsl if ((gn->type & OP_MADE) == 0)
1311 1.68 dsl Suff_FindDeps(gn);
1312 1.68 dsl else {
1313 1.68 dsl /* Pretend we made all this node's children */
1314 1.68 dsl Lst_ForEach(gn->children, MakeFindChild, gn);
1315 1.68 dsl if (gn->unmade != 0)
1316 1.68 dsl printf("Warning: %s%s still has %d unmade children\n",
1317 1.68 dsl gn->name, gn->cohort_num, gn->unmade);
1318 1.68 dsl }
1319 1.68 dsl
1320 1.68 dsl if (gn->unmade != 0)
1321 1.68 dsl Lst_ForEach(gn->children, MakeAddChild, examine);
1322 1.68 dsl }
1323 1.68 dsl
1324 1.77 dsl Lst_Destroy(examine, NULL);
1325 1.68 dsl }
1326 1.68 dsl
1327 1.68 dsl /*-
1328 1.68 dsl *-----------------------------------------------------------------------
1329 1.68 dsl * Make_ProcessWait --
1330 1.68 dsl * Convert .WAIT nodes into dependencies
1331 1.68 dsl *
1332 1.68 dsl * Input:
1333 1.68 dsl * targs the initial list of targets
1334 1.68 dsl *
1335 1.68 dsl *-----------------------------------------------------------------------
1336 1.68 dsl */
1337 1.68 dsl
1338 1.68 dsl static int
1339 1.78 dsl link_parent(void *cnp, void *pnp)
1340 1.68 dsl {
1341 1.68 dsl GNode *cn = cnp;
1342 1.68 dsl GNode *pn = pnp;
1343 1.68 dsl
1344 1.113 rillig Lst_AppendS(pn->children, cn);
1345 1.113 rillig Lst_AppendS(cn->parents, pn);
1346 1.68 dsl pn->unmade++;
1347 1.68 dsl return 0;
1348 1.68 dsl }
1349 1.68 dsl
1350 1.68 dsl static int
1351 1.68 dsl add_wait_dep(void *v_cn, void *v_wn)
1352 1.68 dsl {
1353 1.68 dsl GNode *cn = v_cn;
1354 1.68 dsl GNode *wn = v_wn;
1355 1.68 dsl
1356 1.68 dsl if (cn == wn)
1357 1.68 dsl return 1;
1358 1.68 dsl
1359 1.68 dsl if (cn == NULL || wn == NULL) {
1360 1.68 dsl printf("bad wait dep %p %p\n", cn, wn);
1361 1.68 dsl exit(4);
1362 1.68 dsl }
1363 1.68 dsl if (DEBUG(MAKE))
1364 1.68 dsl fprintf(debug_file, ".WAIT: add dependency %s%s -> %s\n",
1365 1.68 dsl cn->name, cn->cohort_num, wn->name);
1366 1.68 dsl
1367 1.113 rillig Lst_AppendS(wn->children, cn);
1368 1.68 dsl wn->unmade++;
1369 1.113 rillig Lst_AppendS(cn->parents, wn);
1370 1.68 dsl return 0;
1371 1.68 dsl }
1372 1.68 dsl
1373 1.68 dsl static void
1374 1.68 dsl Make_ProcessWait(Lst targs)
1375 1.68 dsl {
1376 1.68 dsl GNode *pgn; /* 'parent' node we are examining */
1377 1.68 dsl GNode *cgn; /* Each child in turn */
1378 1.68 dsl LstNode owln; /* Previous .WAIT node */
1379 1.68 dsl Lst examine; /* List of targets to examine */
1380 1.68 dsl LstNode ln;
1381 1.68 dsl
1382 1.68 dsl /*
1383 1.68 dsl * We need all the nodes to have a common parent in order for the
1384 1.68 dsl * .WAIT and .ORDER scheduling to work.
1385 1.68 dsl * Perhaps this should be done earlier...
1386 1.68 dsl */
1387 1.68 dsl
1388 1.68 dsl pgn = Targ_NewGN(".MAIN");
1389 1.68 dsl pgn->flags = REMAKE;
1390 1.68 dsl pgn->type = OP_PHONY | OP_DEPENDS;
1391 1.68 dsl /* Get it displayed in the diag dumps */
1392 1.114 rillig Lst_PrependS(Targ_List(), pgn);
1393 1.68 dsl
1394 1.68 dsl Lst_ForEach(targs, link_parent, pgn);
1395 1.68 dsl
1396 1.68 dsl /* Start building with the 'dummy' .MAIN' node */
1397 1.77 dsl MakeBuildChild(pgn, NULL);
1398 1.68 dsl
1399 1.104 rillig examine = Lst_Init();
1400 1.113 rillig Lst_AppendS(examine, pgn);
1401 1.68 dsl
1402 1.115 rillig while (!Lst_IsEmpty(examine)) {
1403 1.115 rillig pgn = Lst_DequeueS(examine);
1404 1.99 rillig
1405 1.68 dsl /* We only want to process each child-list once */
1406 1.68 dsl if (pgn->flags & DONE_WAIT)
1407 1.68 dsl continue;
1408 1.68 dsl pgn->flags |= DONE_WAIT;
1409 1.68 dsl if (DEBUG(MAKE))
1410 1.68 dsl fprintf(debug_file, "Make_ProcessWait: examine %s\n", pgn->name);
1411 1.68 dsl
1412 1.120 rillig if (pgn->type & OP_DOUBLEDEP)
1413 1.120 rillig Lst_PrependAllS(examine, pgn->cohorts);
1414 1.1 cgd
1415 1.68 dsl owln = Lst_First(pgn->children);
1416 1.107 rillig Lst_OpenS(pgn->children);
1417 1.106 rillig for (; (ln = Lst_NextS(pgn->children)) != NULL; ) {
1418 1.117 rillig cgn = Lst_DatumS(ln);
1419 1.68 dsl if (cgn->type & OP_WAIT) {
1420 1.68 dsl /* Make the .WAIT node depend on the previous children */
1421 1.68 dsl Lst_ForEachFrom(pgn->children, owln, add_wait_dep, cgn);
1422 1.68 dsl owln = ln;
1423 1.1 cgd } else {
1424 1.113 rillig Lst_AppendS(examine, cgn);
1425 1.1 cgd }
1426 1.1 cgd }
1427 1.107 rillig Lst_CloseS(pgn->children);
1428 1.1 cgd }
1429 1.10 christos
1430 1.77 dsl Lst_Destroy(examine, NULL);
1431 1.11 christos }
1432 1.11 christos
1433 1.11 christos /*-
1434 1.11 christos *-----------------------------------------------------------------------
1435 1.11 christos * Make_Run --
1436 1.11 christos * Initialize the nodes to remake and the list of nodes which are
1437 1.11 christos * ready to be made by doing a breadth-first traversal of the graph
1438 1.11 christos * starting from the nodes in the given list. Once this traversal
1439 1.11 christos * is finished, all the 'leaves' of the graph are in the toBeMade
1440 1.11 christos * queue.
1441 1.11 christos * Using this queue and the Job module, work back up the graph,
1442 1.11 christos * calling on MakeStartJobs to keep the job table as full as
1443 1.11 christos * possible.
1444 1.11 christos *
1445 1.50 wiz * Input:
1446 1.50 wiz * targs the initial list of targets
1447 1.50 wiz *
1448 1.11 christos * Results:
1449 1.11 christos * TRUE if work was done. FALSE otherwise.
1450 1.11 christos *
1451 1.11 christos * Side Effects:
1452 1.11 christos * The make field of all nodes involved in the creation of the given
1453 1.11 christos * targets is set to 1. The toBeMade list is set to contain all the
1454 1.11 christos * 'leaves' of these subgraphs.
1455 1.11 christos *-----------------------------------------------------------------------
1456 1.11 christos */
1457 1.11 christos Boolean
1458 1.50 wiz Make_Run(Lst targs)
1459 1.11 christos {
1460 1.11 christos int errors; /* Number of errors the Job module reports */
1461 1.11 christos
1462 1.68 dsl /* Start trying to make the current targets... */
1463 1.104 rillig toBeMade = Lst_Init();
1464 1.68 dsl
1465 1.68 dsl Make_ExpandUse(targs);
1466 1.68 dsl Make_ProcessWait(targs);
1467 1.68 dsl
1468 1.60 dsl if (DEBUG(MAKE)) {
1469 1.68 dsl fprintf(debug_file, "#***# full graph\n");
1470 1.68 dsl Targ_PrintGraph(1);
1471 1.60 dsl }
1472 1.1 cgd
1473 1.1 cgd if (queryFlag) {
1474 1.1 cgd /*
1475 1.1 cgd * We wouldn't do any work unless we could start some jobs in the
1476 1.1 cgd * next loop... (we won't actually start any, of course, this is just
1477 1.1 cgd * to see if any of the targets was out of date)
1478 1.1 cgd */
1479 1.98 rillig return MakeStartJobs();
1480 1.1 cgd }
1481 1.68 dsl /*
1482 1.68 dsl * Initialization. At the moment, no jobs are running and until some
1483 1.68 dsl * get started, nothing will happen since the remaining upward
1484 1.68 dsl * traversal of the graph is performed by the routines in job.c upon
1485 1.68 dsl * the finishing of a job. So we fill the Job table as much as we can
1486 1.68 dsl * before going into our loop.
1487 1.68 dsl */
1488 1.68 dsl (void)MakeStartJobs();
1489 1.1 cgd
1490 1.1 cgd /*
1491 1.1 cgd * Main Loop: The idea here is that the ending of jobs will take
1492 1.1 cgd * care of the maintenance of data structures and the waiting for output
1493 1.1 cgd * will cause us to be idle most of the time while our children run as
1494 1.1 cgd * much as possible. Because the job table is kept as full as possible,
1495 1.1 cgd * the only time when it will be empty is when all the jobs which need
1496 1.1 cgd * running have been run, so that is the end condition of this loop.
1497 1.1 cgd * Note that the Job module will exit if there were any errors unless the
1498 1.1 cgd * keepgoing flag was given.
1499 1.1 cgd */
1500 1.62 dsl while (!Lst_IsEmpty(toBeMade) || jobTokensRunning > 0) {
1501 1.56 christos Job_CatchOutput();
1502 1.1 cgd (void)MakeStartJobs();
1503 1.1 cgd }
1504 1.1 cgd
1505 1.20 christos errors = Job_Finish();
1506 1.1 cgd
1507 1.1 cgd /*
1508 1.1 cgd * Print the final status of each target. E.g. if it wasn't made
1509 1.1 cgd * because some inferior reported an error.
1510 1.1 cgd */
1511 1.68 dsl if (DEBUG(MAKE))
1512 1.68 dsl fprintf(debug_file, "done: errors %d\n", errors);
1513 1.68 dsl if (errors == 0) {
1514 1.68 dsl Lst_ForEach(targs, MakePrintStatus, &errors);
1515 1.68 dsl if (DEBUG(MAKE)) {
1516 1.68 dsl fprintf(debug_file, "done: errors %d\n", errors);
1517 1.68 dsl if (errors)
1518 1.68 dsl Targ_PrintGraph(4);
1519 1.68 dsl }
1520 1.68 dsl }
1521 1.68 dsl return errors != 0;
1522 1.1 cgd }
1523