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