Annotation of src/usr.bin/make/compat.c, Revision 1.64
1.36 espie 1: /* $OpenPackages$ */
1.61 espie 2: /* $OpenBSD$ */
1.8 millert 3: /* $NetBSD: compat.c,v 1.14 1996/11/06 17:59:01 christos Exp $ */
1.1 deraadt 4:
5: /*
6: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
7: * Copyright (c) 1988, 1989 by Adam de Boor
8: * Copyright (c) 1989 by Berkeley Softworks
9: * All rights reserved.
10: *
11: * This code is derived from software contributed to Berkeley by
12: * Adam de Boor.
13: *
14: * Redistribution and use in source and binary forms, with or without
15: * modification, are permitted provided that the following conditions
16: * are met:
17: * 1. Redistributions of source code must retain the above copyright
18: * notice, this list of conditions and the following disclaimer.
19: * 2. Redistributions in binary form must reproduce the above copyright
20: * notice, this list of conditions and the following disclaimer in the
21: * documentation and/or other materials provided with the distribution.
1.49 millert 22: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: */
38:
1.39 espie 39: #include <limits.h>
1.37 espie 40: #include <signal.h>
41: #include <stdio.h>
1.39 espie 42: #include <stdlib.h>
1.37 espie 43: #include "config.h"
44: #include "defines.h"
45: #include "dir.h"
1.55 espie 46: #include "engine.h"
1.37 espie 47: #include "compat.h"
48: #include "suff.h"
49: #include "var.h"
50: #include "targ.h"
51: #include "error.h"
52: #include "extern.h"
53: #include "gnode.h"
54: #include "timestamp.h"
55: #include "lst.h"
1.1 deraadt 56:
1.36 espie 57: static void CompatMake(void *, void *);
1.60 espie 58:
1.1 deraadt 59: /*-
60: *-----------------------------------------------------------------------
61: * CompatMake --
62: * Make a target.
63: *
64: * Side Effects:
65: * If an error is detected and not being ignored, the process exits.
66: *-----------------------------------------------------------------------
67: */
1.26 espie 68: static void
1.50 espie 69: CompatMake(void *gnp, /* The node to make */
70: void *pgnp) /* Parent to abort if necessary */
1.1 deraadt 71: {
1.57 espie 72: GNode *gn = (GNode *)gnp;
73: GNode *pgn = (GNode *)pgnp;
74:
1.63 espie 75: look_harder_for_target(gn);
76:
1.57 espie 77: if (pgn->type & OP_MADE) {
78: (void)Dir_MTime(gn);
79: gn->made = UPTODATE;
80: }
81:
82: if (gn->type & OP_USE) {
83: Make_HandleUse(gn, pgn);
84: } else if (gn->made == UNMADE) {
85: /* First mark ourselves to be made, then apply whatever
1.60 espie 86: * transformations the suffix module thinks are necessary.
87: * Once that's done, we can descend and make all our children.
88: * If any of them has an error but the -k flag was given,
89: * our 'make' field will be set false again. This is our
90: * signal to not attempt to do anything but abort our
91: * parent as well. */
1.57 espie 92: gn->make = true;
93: gn->made = BEINGMADE;
94: Suff_FindDeps(gn);
95: Lst_ForEach(&gn->children, CompatMake, gn);
96: if (!gn->make) {
97: gn->made = ABORTED;
98: pgn->make = false;
99: return;
100: }
1.5 millert 101:
1.57 espie 102: if (Lst_Member(&gn->iParents, pgn) != NULL) {
1.59 espie 103: Varq_Set(IMPSRC_INDEX, Varq_Value(TARGET_INDEX, gn),
1.57 espie 104: pgn);
105: }
1.1 deraadt 106:
1.57 espie 107: /* All the children were made ok. Now cmtime contains the
108: * modification time of the newest child, we need to find out
1.60 espie 109: * if we exist and when we were modified last. The criteria
110: * for datedness are defined by the Make_OODate function. */
1.57 espie 111: if (DEBUG(MAKE))
112: printf("Examining %s...", gn->name);
1.60 espie 113: if (!Make_OODate(gn)) {
1.57 espie 114: gn->made = UPTODATE;
115: if (DEBUG(MAKE))
116: printf("up-to-date.\n");
117: return;
118: } else if (DEBUG(MAKE))
119: printf("out-of-date.\n");
120:
1.60 espie 121: /* If the user is just seeing if something is out-of-date,
122: * exit now to tell him/her "yes". */
1.57 espie 123: if (queryFlag)
124: exit(-1);
125:
1.60 espie 126: /* We need to be re-made. We also have to make sure we've
127: * got a $? variable. To be nice, we also define the $>
128: * variable using Make_DoAllVar(). */
1.57 espie 129: Make_DoAllVar(gn);
130:
131: if (Job_CheckCommands(gn, Fatal)) {
1.62 espie 132: /* Our commands are ok, but we still have to worry
133: * about the -t flag... */
134: if (!touchFlag)
1.63 espie 135: run_gnode(gn, 0);
1.62 espie 136: else
137: Job_Touch(gn, gn->type & OP_SILENT);
1.57 espie 138: } else
139: gn->made = ERROR;
140:
141: if (gn->made != ERROR) {
142: /* If the node was made successfully, mark it so,
1.60 espie 143: * update its modification time and timestamp all
144: * its parents.
145: * This is to keep its state from affecting that of
146: * its parent. */
1.57 espie 147: gn->made = MADE;
148: /* This is what Make does and it's actually a good
149: * thing, as it allows rules like
150: *
151: * cmp -s y.tab.h parse.h || cp y.tab.h parse.h
152: *
153: * to function as intended. Unfortunately, thanks to
1.60 espie 154: * the stateless nature of NFS (and the speed of
155: * this program), there are times when the
156: * modification time of a file created on a remote
157: * machine will not be modified before the stat()
158: * implied by the Dir_MTime occurs, thus leading us
159: * to believe that the file is unchanged, wreaking
160: * havoc with files that depend on this one.
1.57 espie 161: */
162: if (noExecute || is_out_of_date(Dir_MTime(gn)))
163: gn->mtime = now;
164: if (is_strictly_before(gn->mtime, gn->cmtime))
165: gn->mtime = gn->cmtime;
166: if (DEBUG(MAKE))
1.59 espie 167: printf("update time: %s\n",
1.57 espie 168: time_to_string(gn->mtime));
169: if (!(gn->type & OP_EXEC)) {
170: pgn->childMade = true;
171: Make_TimeStamp(pgn, gn);
172: }
173: } else if (keepgoing)
174: pgn->make = false;
175: else {
1.36 espie 176:
1.57 espie 177: if (gn->lineno)
178: printf("\n\nStop in %s (line %lu of %s).\n",
179: Var_Value(".CURDIR"),
180: (unsigned long)gn->lineno,
181: gn->fname);
182: else
1.59 espie 183: printf("\n\nStop in %s.\n",
1.57 espie 184: Var_Value(".CURDIR"));
185: exit(1);
186: }
187: } else if (gn->made == ERROR)
1.60 espie 188: /* Already had an error when making this beastie. Tell the parent
189: * to abort. */
1.37 espie 190: pgn->make = false;
1.57 espie 191: else {
192: if (Lst_Member(&gn->iParents, pgn) != NULL) {
1.59 espie 193: Varq_Set(IMPSRC_INDEX, Varq_Value(TARGET_INDEX, gn),
1.57 espie 194: pgn);
195: }
196: switch (gn->made) {
197: case BEINGMADE:
198: Error("Graph cycles through %s\n", gn->name);
199: gn->made = ERROR;
200: pgn->make = false;
201: break;
202: case MADE:
203: if ((gn->type & OP_EXEC) == 0) {
204: pgn->childMade = true;
205: Make_TimeStamp(pgn, gn);
206: }
207: break;
208: case UPTODATE:
209: if ((gn->type & OP_EXEC) == 0)
210: Make_TimeStamp(pgn, gn);
211: break;
212: default:
213: break;
214: }
1.1 deraadt 215: }
216: }
1.36 espie 217:
1.1 deraadt 218: void
1.50 espie 219: Compat_Run(Lst targs) /* List of target nodes to re-create */
1.1 deraadt 220: {
1.60 espie 221: GNode *gn = NULL; /* Current root target */
222: int errors; /* Number of targets not remade due to errors */
1.57 espie 223:
1.63 espie 224: setup_engine();
1.57 espie 225: /* If the user has defined a .BEGIN target, execute the commands
226: * attached to it. */
227: if (!queryFlag) {
1.63 espie 228: if (run_gnode(begin_node, 0) == ERROR) {
1.60 espie 229: printf("\n\nStop.\n");
230: exit(1);
1.57 espie 231: }
232: }
233:
234: /* For each entry in the list of targets to create, call CompatMake on
235: * it to create the thing. CompatMake will leave the 'made' field of gn
236: * in one of several states:
237: * UPTODATE gn was already up-to-date
238: * MADE gn was recreated successfully
1.60 espie 239: * ERROR An error occurred while gn was being
240: * created
1.59 espie 241: * ABORTED gn was not remade because one of its
1.60 espie 242: * inferiors could not be made due to errors.
1.57 espie 243: */
244: errors = 0;
245: while ((gn = (GNode *)Lst_DeQueue(targs)) != NULL) {
246: CompatMake(gn, gn);
247:
248: if (gn->made == UPTODATE)
249: printf("`%s' is up to date.\n", gn->name);
250: else if (gn->made == ABORTED) {
1.59 espie 251: printf("`%s' not remade because of errors.\n",
1.57 espie 252: gn->name);
1.58 espie 253: errors++;
1.57 espie 254: }
255: }
256:
257: /* If the user has defined a .END target, run its commands. */
258: if (errors == 0)
1.63 espie 259: run_gnode(end_node, 0);
1.1 deraadt 260: }