Annotation of src/usr.bin/make/engine.c, Revision 1.4
1.4 ! espie 1: /* $OpenBSD: engine.c,v 1.3 2007/09/16 14:36:57 espie Exp $ */
1.1 espie 2: /*
3: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
4: * Copyright (c) 1988, 1989 by Adam de Boor
5: * Copyright (c) 1989 by Berkeley Softworks
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to Berkeley by
9: * Adam de Boor.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
36: #include <limits.h>
37: #include <stdio.h>
38: #include <errno.h>
39: #include <fcntl.h>
40: #include <unistd.h>
41: #include <string.h>
42: #include "config.h"
43: #include "defines.h"
44: #include "dir.h"
45: #include "engine.h"
46: #include "arch.h"
47: #include "gnode.h"
48: #include "targ.h"
49: #include "var.h"
50: #include "extern.h"
51: #include "lst.h"
52: #include "timestamp.h"
53: #include "make.h"
54: #include "main.h"
55:
56: static void MakeTimeStamp(void *, void *);
57: static void MakeAddAllSrc(void *, void *);
58:
59: /*-
60: *-----------------------------------------------------------------------
61: * Job_CheckCommands --
62: * Make sure the given node has all the commands it needs.
63: *
64: * Results:
65: * true if the commands list is/was ok.
66: *
67: * Side Effects:
68: * The node will have commands from the .DEFAULT rule added to it
69: * if it needs them.
70: *-----------------------------------------------------------------------
71: */
72: bool
1.3 espie 73: Job_CheckCommands(GNode *gn, void (*abortProc)(char *, ...))
1.1 espie 74: {
1.3 espie 75: if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->commands) &&
76: (gn->type & OP_LIB) == 0) {
77: /*
78: * No commands. Look for .DEFAULT rule from which we might infer
79: * commands
80: */
81: if (DEFAULT != NULL && !Lst_IsEmpty(&DEFAULT->commands)) {
82: /*
83: * Make only looks for a .DEFAULT if the node was never
84: * the target of an operator, so that's what we do too.
85: * If a .DEFAULT was given, we substitute its commands
86: * for gn's commands and set the IMPSRC variable to be
87: * the target's name The DEFAULT node acts like a
88: * transformation rule, in that gn also inherits any
89: * attributes or sources attached to .DEFAULT itself.
90: */
91: Make_HandleUse(DEFAULT, gn);
92: Varq_Set(IMPSRC_INDEX, Varq_Value(TARGET_INDEX, gn), gn);
93: } else if (is_out_of_date(Dir_MTime(gn))) {
94: /*
95: * The node wasn't the target of an operator we have no
96: * .DEFAULT rule to go on and the target doesn't
97: * already exist. There's nothing more we can do for
98: * this branch. If the -k flag wasn't given, we stop in
99: * our tracks, otherwise we just don't update this
100: * node's parents so they never get examined.
101: */
102: static const char msg[] =
103: "make: don't know how to make";
104:
105: if (gn->type & OP_OPTIONAL) {
106: (void)fprintf(stdout, "%s %s(ignored)\n", msg,
107: gn->name);
108: (void)fflush(stdout);
109: } else if (keepgoing) {
110: (void)fprintf(stdout, "%s %s(continuing)\n",
111: msg, gn->name);
112: (void)fflush(stdout);
113: return false;
114: } else {
115: (*abortProc)("%s %s. Stop in %s.", msg,
116: gn->name, Var_Value(".CURDIR"));
117: return false;
118: }
119: }
1.1 espie 120: }
1.3 espie 121: return true;
1.1 espie 122: }
123:
124: /*-
125: *-----------------------------------------------------------------------
126: * Job_Touch --
127: * Touch the given target. Called by JobStart when the -t flag was
128: * given
129: *
130: * Side Effects:
131: * The data modification of the file is changed. In addition, if the
132: * file did not exist, it is created.
133: *-----------------------------------------------------------------------
134: */
135: void
1.3 espie 136: Job_Touch(GNode *gn, bool silent)
1.1 espie 137: {
1.3 espie 138: int streamID; /* ID of stream opened to do the touch */
1.1 espie 139:
1.3 espie 140: if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
141: /*
142: * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual"
143: * targets and, as such, shouldn't really be created.
144: */
145: return;
146: }
1.1 espie 147:
1.3 espie 148: if (!silent) {
149: (void)fprintf(stdout, "touch %s\n", gn->name);
150: (void)fflush(stdout);
151: }
1.1 espie 152:
1.3 espie 153: if (noExecute) {
154: return;
155: }
1.1 espie 156:
1.3 espie 157: if (gn->type & OP_ARCHV) {
158: Arch_Touch(gn);
159: } else if (gn->type & OP_LIB) {
160: Arch_TouchLib(gn);
161: } else {
162: const char *file = gn->path != NULL ? gn->path : gn->name;
163:
164: if (set_times(file) == -1){
165: streamID = open(file, O_RDWR | O_CREAT, 0666);
166:
167: if (streamID >= 0) {
168: char c;
169:
170: /*
171: * Read and write a byte to the file to change
172: * the modification time, then close the file.
173: */
174: if (read(streamID, &c, 1) == 1) {
175: (void)lseek(streamID, 0, SEEK_SET);
176: (void)write(streamID, &c, 1);
177: }
178:
179: (void)close(streamID);
180: } else {
181: (void)fprintf(stdout,
182: "*** couldn't touch %s: %s", file,
183: strerror(errno));
184: (void)fflush(stdout);
185: }
1.1 espie 186: }
187: }
188: }
189:
190: /*-
191: *-----------------------------------------------------------------------
192: * Make_TimeStamp --
193: * Set the cmtime field of a parent node based on the mtime stamp in its
194: * child.
195: *
196: * Side Effects:
197: * The cmtime of the parent node will be changed if the mtime
198: * field of the child is greater than it.
199: *-----------------------------------------------------------------------
200: */
201: void
202: Make_TimeStamp(
203: GNode *pgn, /* the current parent */
204: GNode *cgn) /* the child we've just examined */
205: {
1.3 espie 206: if (is_strictly_before(pgn->cmtime, cgn->mtime))
207: pgn->cmtime = cgn->mtime;
1.1 espie 208: }
209:
210: /*-
211: *-----------------------------------------------------------------------
212: * Make_HandleUse --
213: * Function called by Make_Run and SuffApplyTransform on the downward
214: * pass to handle .USE and transformation nodes. A callback function
215: * for Lst_ForEach, it implements the .USE and transformation
216: * functionality by copying the node's commands, type flags
217: * and children to the parent node. Should be called before the
218: * children are enqueued to be looked at by MakeAddChild.
219: *
220: * A .USE node is much like an explicit transformation rule, except
221: * its commands are always added to the target node, even if the
222: * target already has commands.
223: *
224: * Side Effects:
225: * Children and commands may be added to the parent and the parent's
226: * type may be changed.
227: *
228: *-----------------------------------------------------------------------
229: */
230: void
231: Make_HandleUse(
232: GNode *cgn, /* The .USE node */
233: GNode *pgn) /* The target of the .USE node */
234: {
1.3 espie 235: GNode *gn; /* A child of the .USE node */
236: LstNode ln; /* An element in the children list */
1.1 espie 237:
1.3 espie 238: if (cgn->type & (OP_USE|OP_TRANSFORM)) {
239: if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) {
240: /* .USE or transformation and target has no commands --
241: * append the child's commands to the parent. */
242: Lst_Concat(&pgn->commands, &cgn->commands);
243: }
1.1 espie 244:
1.3 espie 245: for (ln = Lst_First(&cgn->children); ln != NULL;
246: ln = Lst_Adv(ln)) {
247: gn = (GNode *)Lst_Datum(ln);
248:
249: if (Lst_AddNew(&pgn->children, gn)) {
250: Lst_AtEnd(&gn->parents, pgn);
1.4 ! espie 251: pgn->unmade++;
1.3 espie 252: }
253: }
1.1 espie 254:
1.3 espie 255: pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM);
1.1 espie 256:
1.3 espie 257: /*
258: * This child node is now "made", so we decrement the count of
259: * unmade children in the parent... We also remove the child
260: * from the parent's list to accurately reflect the number of
261: * decent children the parent has. This is used by Make_Run to
262: * decide whether to queue the parent or examine its
263: * children...
264: */
265: if (cgn->type & OP_USE) {
266: pgn->unmade--;
267: }
1.1 espie 268: }
269: }
270:
271: /*-
272: *-----------------------------------------------------------------------
273: * MakeAddAllSrc --
274: * Add a child's name to the ALLSRC and OODATE variables of the given
275: * node. Called from Make_DoAllVar via Lst_ForEach. A child is added only
276: * if it has not been given the .EXEC, .USE or .INVISIBLE attributes.
277: * .EXEC and .USE children are very rarely going to be files, so...
278: * A child is added to the OODATE variable if its modification time is
279: * later than that of its parent, as defined by Make, except if the
280: * parent is a .JOIN node. In that case, it is only added to the OODATE
281: * variable if it was actually made (since .JOIN nodes don't have
282: * modification times, the comparison is rather unfair...)..
283: *
284: * Side Effects:
285: * The ALLSRC variable for the given node is extended.
286: *-----------------------------------------------------------------------
287: */
288: static void
289: MakeAddAllSrc(
290: void *cgnp, /* The child to add */
291: void *pgnp) /* The parent to whose ALLSRC variable it should be */
292: /* added */
293: {
1.3 espie 294: GNode *cgn = (GNode *)cgnp;
295: GNode *pgn = (GNode *)pgnp;
296: if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
297: const char *child;
298:
299: if (OP_NOP(cgn->type) ||
300: (child = Varq_Value(TARGET_INDEX, cgn)) == NULL) {
301: /*
302: * this node is only source; use the specific pathname
303: * for it
304: */
305: child = cgn->path != NULL ? cgn->path : cgn->name;
306: }
1.1 espie 307:
1.3 espie 308: Varq_Append(ALLSRC_INDEX, child, pgn);
309: if (pgn->type & OP_JOIN) {
310: if (cgn->made == MADE) {
311: Varq_Append(OODATE_INDEX, child, pgn);
312: }
313: } else if (is_strictly_before(pgn->mtime, cgn->mtime) ||
314: (!is_strictly_before(cgn->mtime, now) &&
315: cgn->made == MADE)) {
316: /*
317: * It goes in the OODATE variable if the parent is
318: * younger than the child or if the child has been
319: * modified more recently than the start of the make.
320: * This is to keep pmake from getting confused if
321: * something else updates the parent after the make
322: * starts (shouldn't happen, I know, but sometimes it
323: * does). In such a case, if we've updated the kid, the
324: * parent is likely to have a modification time later
325: * than that of the kid and anything that relies on the
326: * OODATE variable will be hosed.
327: *
328: */
329: Varq_Append(OODATE_INDEX, child, pgn);
330: }
1.1 espie 331: }
332: }
333:
334: /*-
335: *-----------------------------------------------------------------------
336: * Make_DoAllVar --
337: * Set up the ALLSRC and OODATE variables. Sad to say, it must be
338: * done separately, rather than while traversing the graph. This is
339: * because Make defined OODATE to contain all sources whose modification
340: * times were later than that of the target, *not* those sources that
341: * were out-of-date. Since in both compatibility and native modes,
342: * the modification time of the parent isn't found until the child
343: * has been dealt with, we have to wait until now to fill in the
344: * variable. As for ALLSRC, the ordering is important and not
345: * guaranteed when in native mode, so it must be set here, too.
346: *
347: * Side Effects:
348: * The ALLSRC and OODATE variables of the given node is filled in.
349: * If the node is a .JOIN node, its TARGET variable will be set to
350: * match its ALLSRC variable.
351: *-----------------------------------------------------------------------
352: */
353: void
354: Make_DoAllVar(GNode *gn)
355: {
1.3 espie 356: Lst_ForEach(&gn->children, MakeAddAllSrc, gn);
1.1 espie 357:
1.3 espie 358: if (Varq_Value(OODATE_INDEX, gn) == NULL)
359: Varq_Set(OODATE_INDEX, "", gn);
360: if (Varq_Value(ALLSRC_INDEX, gn) == NULL)
361: Varq_Set(ALLSRC_INDEX, "", gn);
1.1 espie 362:
1.3 espie 363: if (gn->type & OP_JOIN)
364: Varq_Set(TARGET_INDEX, Varq_Value(ALLSRC_INDEX, gn), gn);
1.1 espie 365: }
366:
367: /* Wrapper to call Make_TimeStamp from a forEach loop. */
368: static void
369: MakeTimeStamp(
370: void *pgn, /* the current parent */
371: void *cgn) /* the child we've just examined */
372: {
1.3 espie 373: Make_TimeStamp((GNode *)pgn, (GNode *)cgn);
1.1 espie 374: }
375:
376: /*-
377: *-----------------------------------------------------------------------
378: * Make_OODate --
379: * See if a given node is out of date with respect to its sources.
380: * Used by Make_Run when deciding which nodes to place on the
381: * toBeMade queue initially and by Make_Update to screen out USE and
382: * EXEC nodes. In the latter case, however, any other sort of node
383: * must be considered out-of-date since at least one of its children
384: * will have been recreated.
385: *
386: * Results:
387: * true if the node is out of date. false otherwise.
388: *
389: * Side Effects:
390: * The mtime field of the node and the cmtime field of its parents
391: * will/may be changed.
392: *-----------------------------------------------------------------------
393: */
394: bool
395: Make_OODate(GNode *gn) /* the node to check */
396: {
1.3 espie 397: bool oodate;
1.1 espie 398:
399: /*
1.3 espie 400: * Certain types of targets needn't even be sought as their datedness
401: * doesn't depend on their modification time...
1.1 espie 402: */
1.3 espie 403: if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
404: (void)Dir_MTime(gn);
405: if (DEBUG(MAKE)) {
406: if (!is_out_of_date(gn->mtime)) {
407: printf("modified %s...",
408: time_to_string(gn->mtime));
409: } else {
410: printf("non-existent...");
411: }
412: }
1.1 espie 413: }
414:
415: /*
1.3 espie 416: * A target is remade in one of the following circumstances:
417: * its modification time is smaller than that of its youngest child
418: * and it would actually be run (has commands or type OP_NOP)
419: * it's the object of a force operator
420: * it has no children, was on the lhs of an operator and doesn't
421: * exist already.
422: *
423: * Libraries are only considered out-of-date if the archive module says
424: * they are.
425: *
426: * These weird rules are brought to you by Backward-Compatibility and
427: * the strange people who wrote 'Make'.
1.1 espie 428: */
1.3 espie 429: if (gn->type & OP_USE) {
430: /*
431: * If the node is a USE node it is *never* out of date
432: * no matter *what*.
433: */
434: if (DEBUG(MAKE)) {
435: printf(".USE node...");
436: }
437: oodate = false;
438: } else if ((gn->type & OP_LIB) && Arch_IsLib(gn)) {
439: if (DEBUG(MAKE)) {
440: printf("library...");
441: }
1.1 espie 442:
1.3 espie 443: /*
444: * always out of date if no children and :: target
445: */
446:
447: oodate = Arch_LibOODate(gn) ||
448: (is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP));
449: } else if (gn->type & OP_JOIN) {
450: /*
451: * A target with the .JOIN attribute is only considered
452: * out-of-date if any of its children was out-of-date.
453: */
454: if (DEBUG(MAKE)) {
455: printf(".JOIN node...");
456: }
457: oodate = gn->childMade;
458: } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
459: /*
460: * A node which is the object of the force (!) operator or
461: * which has the .EXEC attribute is always considered
462: * out-of-date.
463: */
464: if (DEBUG(MAKE)) {
465: if (gn->type & OP_FORCE) {
466: printf("! operator...");
467: } else if (gn->type & OP_PHONY) {
468: printf(".PHONY node...");
469: } else {
470: printf(".EXEC node...");
471: }
472: }
473: oodate = true;
474: } else if (is_strictly_before(gn->mtime, gn->cmtime) ||
475: (is_out_of_date(gn->cmtime) &&
476: (is_out_of_date(gn->mtime) || (gn->type & OP_DOUBLEDEP)))) {
477: /*
478: * A node whose modification time is less than that of its
479: * youngest child or that has no children (cmtime ==
480: * OUT_OF_DATE) and either doesn't exist (mtime == OUT_OF_DATE)
481: * or was the object of a :: operator is out-of-date. Why?
482: * Because that's the way Make does it.
483: */
484: if (DEBUG(MAKE)) {
485: if (is_strictly_before(gn->mtime, gn->cmtime)) {
486: printf("modified before source...");
487: } else if (is_out_of_date(gn->mtime)) {
488: printf("non-existent and no sources...");
489: } else {
490: printf(":: operator and no sources...");
491: }
492: }
493: oodate = true;
494: } else {
1.1 espie 495: #if 0
1.3 espie 496: /* WHY? */
497: if (DEBUG(MAKE)) {
498: printf("source %smade...", gn->childMade ? "" : "not ");
499: }
500: oodate = gn->childMade;
1.1 espie 501: #else
1.3 espie 502: oodate = false;
1.1 espie 503: #endif /* 0 */
1.3 espie 504: }
1.1 espie 505:
1.3 espie 506: /*
507: * If the target isn't out-of-date, the parents need to know its
508: * modification time. Note that targets that appear to be out-of-date
509: * but aren't, because they have no commands and aren't of type OP_NOP,
510: * have their mtime stay below their children's mtime to keep parents
511: * from thinking they're out-of-date.
512: */
513: if (!oodate)
514: Lst_ForEach(&gn->parents, MakeTimeStamp, gn);
1.1 espie 515:
1.3 espie 516: return oodate;
1.1 espie 517: }
518: