cosmetix
[k8jam.git] / src / make.c
blob36141f70969187c851449a384c87651fd044f609
1 /*
2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
5 */
7 /*
8 * make.c - bring a target up to date, once rules are in place
10 * This modules controls the execution of rules to bring a target and
11 * its dependencies up to date. It is invoked after the targets, rules,
12 * et. al. described in rules.h are created by the interpreting of the
13 * jam files.
15 * This file contains the main make() entry point and the first pass
16 * make0(). The second pass, make1(), which actually does the command
17 * execution, is in make1.c.
19 * External routines:
20 * make() - make a target, given its name
22 * Internal routines:
23 * make0() - bind and scan everything to make a TARGET
24 * make0sort() - reorder TARGETS chain by their time (newest to oldest)
26 * 12/26/93 (seiwald) - allow NOTIME targets to be expanded via $(<), $(>)
27 * 01/04/94 (seiwald) - print all targets, bounded, when tracing commands
28 * 04/08/94 (seiwald) - progress report now reflects only targets with actions
29 * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET.
30 * 12/20/94 (seiwald) - NOTIME renamed NOTFILE.
31 * 12/20/94 (seiwald) - make0() headers after determining fate of target, so
32 * that headers aren't seen as dependents on themselves.
33 * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets.
34 * 02/02/95 (seiwald) - propagate leaf source time for new LEAVES rule.
35 * 02/14/95 (seiwald) - NOUPDATE rule means don't update existing target.
36 * 08/22/95 (seiwald) - NOUPDATE targets immune to anyhow (-a) flag.
37 * 09/06/00 (seiwald) - NOCARE affects targets with sources/actions.
38 * 03/02/01 (seiwald) - reverse NOCARE change.
39 * 03/14/02 (seiwald) - TEMPORARY targets no longer take on parents age
40 * 03/16/02 (seiwald) - support for -g (reorder builds by source time)
41 * 07/17/02 (seiwald) - TEMPORARY sources for headers now get built
42 * 09/19/02 (seiwald) - new -d displays
43 * 09/23/02 (seiwald) - suppress "...using temp..." in default output
44 * 09/28/02 (seiwald) - make0() takes parent pointer; new -dc display
45 * 11/04/02 (seiwald) - const-ing for string literals
46 * 12/03/02 (seiwald) - fix odd includes support by grafting them onto depends
47 * 12/17/02 (seiwald) - new copysettings() to protect target-specific vars
48 * 01/03/03 (seiwald) - T_FATE_NEWER once again gets set with missing parent
49 * 01/14/03 (seiwald) - fix includes fix with new internal includes TARGET
50 * 04/04/03 (seiwald) - fix INTERNAL node binding to avoid T_BIND_PARENTS
51 * 04/14/06 (kaib) - fix targets to show in 'updated' when their includes
52 * are newer
55 # include "jam.h"
57 # include "lists.h"
58 # include "parse.h"
59 # include "variable.h"
60 # include "rules.h"
62 # include "search.h"
63 # include "newstr.h"
64 # include "make.h"
65 # include "headers.h"
66 # include "command.h"
68 # ifndef max
69 # define max(a,b) ((a)>(b)?(a):(b))
70 # endif
72 typedef struct {
73 int temp;
74 int updating;
75 int cantfind;
76 int cantmake;
77 int targets;
78 int made;
79 } COUNTS;
82 static void make0 (TARGET *t, TARGET *p, int depth, COUNTS *counts, int anyhow);
85 static TARGETS *make0sort (TARGETS *c);
88 static const char *target_fate[] = {
89 "init", /* T_FATE_INIT */
90 "making", /* T_FATE_MAKING */
91 "stable", /* T_FATE_STABLE */
92 "newer", /* T_FATE_NEWER */
93 "temp", /* T_FATE_ISTMP */
94 "touched", /* T_FATE_TOUCHED */
95 "missing", /* T_FATE_MISSING */
96 "needtmp", /* T_FATE_NEEDTMP */
97 "old", /* T_FATE_OUTDATED */
98 "update", /* T_FATE_UPDATE */
99 "nofind", /* T_FATE_CANTFIND */
100 "nomake" /* T_FATE_CANTMAKE */
104 static const char *target_bind[] = {
105 "unbound",
106 "missing",
107 "parents",
108 "exists",
111 # define spaces(x) (" " + 16 - (x > 16 ? 16 : x))
115 * make() - make a target, given its name
117 int make (int n_targets, const char **targets, int anyhow) {
118 int i;
119 COUNTS counts[1];
120 int status = 0; /* 1 if anything fails */
122 memset((char *)counts, 0, sizeof(*counts));
123 for (i = 0; i < n_targets; i++) {
124 TARGET *t = bindtarget(targets[i]);
125 make0(t, 0, 0, counts, anyhow);
127 if (DEBUG_MAKE) {
128 if (counts->targets) printf("...found %d target%s...\n", counts->targets, multiFormSfx(counts->targets));
129 if (counts->temp) printf("...using %d temp target%s...\n", counts->temp, multiFormSfx(counts->temp));
130 if (counts->updating) printf("...updating %d target%s...\n", counts->updating, multiFormSfx(counts->updating));
131 if (counts->cantfind) printf("...can't find %d target%s...\n", counts->cantfind, multiFormSfx(counts->cantfind));
132 if (counts->cantmake) printf("...can't make %d target%s...\n", counts->cantmake, multiFormSfx(counts->cantmake));
134 status = counts->cantfind || counts->cantmake;
135 for (i = 0; i < n_targets; i++) status |= make1(bindtarget(targets[i]));
136 return status;
141 * make0() - bind and scan everything to make a TARGET
143 * Make0() recursively binds a target, searches for #included headers,
144 * calls itself on those headers, and calls itself on any dependents.
146 static void make0 (
147 TARGET *t,
148 TARGET *p, /* parent */
149 int depth, /* for display purposes */
150 COUNTS *counts, /* for reporting */
151 int anyhow /* forcibly touch all (real) targets */
153 TARGETS *c, *incs;
154 TARGET *ptime = t;
155 time_t last, leaf, hlast;
156 int fate;
157 const char *flag = "";
158 SETTINGS *s;
159 /* step 1: initialize */
160 if (DEBUG_MAKEPROG) printf("make\t--\t%s%s\n", spaces(depth), t->name);
161 t->fate = T_FATE_MAKING;
163 * Step 2: under the influence of "on target" variables,
164 * bind the target and search for headers.
166 /* Step 2a: set "on target" variables. */
167 s = copysettings(t->settings);
168 pushsettings(s);
169 /* Step 2b: find and timestamp the target file (if it's a file). */
170 if (t->binding == T_BIND_UNBOUND && !(t->flags & T_FLAG_NOTFILE)) {
171 t->boundname = search(t->name, &t->time);
172 t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
174 /* INTERNAL, NOTFILE header nodes have the time of their parents */
175 if (p && t->flags & T_FLAG_INTERNAL) ptime = p;
176 /* If temp file doesn't exist but parent does, use parent */
177 if (p && t->flags & T_FLAG_TEMP && t->binding == T_BIND_MISSING && p->binding != T_BIND_MISSING) {
178 t->binding = T_BIND_PARENTS;
179 ptime = p;
181 #ifdef JAM_OPT_SEMAPHORE
183 LIST *var = var_get("JAM_SEMAPHORE");
184 if (var) {
185 TARGET *semaphore = bindtarget(var->string);
186 semaphore->progress = T_MAKE_SEMAPHORE;
187 t->semaphore = semaphore;
190 #endif
191 /* Step 2c: If its a file, search for headers. */
192 if (t->binding == T_BIND_EXISTS) headers(t);
193 /* Step 2d: reset "on target" variables */
194 popsettings(s);
195 freesettings(s);
196 /* Pause for a little progress reporting */
197 if (DEBUG_MAKEPROG) {
198 if (strcmp(t->name, t->boundname)) {
199 printf("bind\t--\t%s%s: %s\n", spaces(depth), t->name, t->boundname);
201 switch (t->binding) {
202 case T_BIND_UNBOUND: case T_BIND_MISSING: case T_BIND_PARENTS:
203 printf("time\t--\t%s%s: %s\n", spaces(depth), t->name, target_bind[ (int)t->binding ]);
204 break;
205 case T_BIND_EXISTS:
206 printf("time\t--\t%s%s: %s", spaces(depth), t->name, ctime(&t->time));
207 break;
212 * Step 3: recursively make0() dependents & headers
214 /* Step 3a: recursively make0() dependents */
215 for (c = t->depends; c; c = c->next) {
216 int internal = t->flags & T_FLAG_INTERNAL;
218 if (DEBUG_DEPENDS)
219 printf("%s \"%s\" : \"%s\" ;\n",
220 internal ? "Includes" : "Depends",
221 t->name, c->target->name);
223 /* Warn about circular deps, except for includes, */
224 /* which include each other alot. */
225 if (c->target->fate == T_FATE_INIT) make0(c->target, ptime, depth+1, counts, anyhow);
226 else if (c->target->fate == T_FATE_MAKING && !internal) printf("warning: %s depends on itself\n", c->target->name);
228 /* Step 3b: recursively make0() internal includes node */
229 if (t->includes) make0(t->includes, p, depth+1, counts, anyhow);
230 /* Step 3c: add dependents' includes to our direct dependencies */
231 incs = 0;
232 for (c = t->depends; c; c = c->next) {
233 if (c->target->includes) {
234 incs = targetentry(incs, c->target->includes);
235 /* If the includes are newer than we are their original target
236 also needs to be marked newer. This is needed so that 'updated'
237 correctly will include the original target in the $(<) variable. */
238 if (c->target->includes->time > t->time) c->target->fate = max(T_FATE_NEWER, c->target->fate);
242 t->depends = targetchain(t->depends, incs);
245 * Step 4: compute time & fate
247 /* Step 4a: pick up dependents' time and fate */
248 last = 0;
249 leaf = 0;
250 fate = T_FATE_STABLE;
251 for (c = t->depends; c; c = c->next) {
252 /* If LEAVES has been applied, we only heed the timestamps of */
253 /* the leaf source nodes. */
254 leaf = max(leaf, c->target->leaf);
255 if (t->flags & T_FLAG_LEAVES) {
256 last = leaf;
257 continue;
259 last = max(last, c->target->time);
260 fate = max(fate, c->target->fate);
263 /* Step 4b: pick up included headers time */
265 * If a header is newer than a temp source that includes it,
266 * the temp source will need building.
268 hlast = t->includes ? t->includes->time : 0;
269 /* Step 4c: handle NOUPDATE oddity */
271 * If a NOUPDATE file exists, make dependents eternally old.
272 * Don't inherit our fate from our dependents. Decide fate
273 * based only upon other flags and our binding (done later).
275 if (t->flags & T_FLAG_NOUPDATE) {
276 last = 0;
277 t->time = 0;
278 fate = T_FATE_STABLE;
280 /* Step 4d: determine fate: rebuild target or what? */
282 In English:
283 If can't find or make child, can't make target.
284 If children changed, make target.
285 If target missing, make it.
286 If children newer, make target.
287 If temp's children newer than parent, make temp.
288 If temp's headers newer than parent, make temp.
289 If deliberately touched, make it.
290 If up-to-date temp file present, use it.
291 If target newer than non-notfile parent, mark target newer.
292 Otherwise, stable!
294 Note this block runs from least to most stable:
295 as we make it further down the list, the target's
296 fate is getting stabler.
298 if (fate >= T_FATE_BROKEN) {
299 fate = T_FATE_CANTMAKE;
300 } else if (fate >= T_FATE_SPOIL) {
301 fate = T_FATE_UPDATE;
302 } else if (t->binding == T_BIND_MISSING) {
303 fate = T_FATE_MISSING;
304 } else if (t->binding == T_BIND_EXISTS && last > t->time) {
305 fate = T_FATE_OUTDATED;
306 } else if (t->binding == T_BIND_PARENTS && last > p->time) {
307 fate = T_FATE_NEEDTMP;
308 } else if (t->binding == T_BIND_PARENTS && hlast > p->time) {
309 fate = T_FATE_NEEDTMP;
310 } else if (t->flags & T_FLAG_TOUCHED) {
311 fate = T_FATE_TOUCHED;
312 } else if (anyhow && !(t->flags & T_FLAG_NOUPDATE)) {
313 fate = T_FATE_TOUCHED;
314 } else if (t->binding == T_BIND_EXISTS && t->flags & T_FLAG_TEMP) {
315 fate = T_FATE_ISTMP;
316 } else if (t->binding == T_BIND_EXISTS && p && p->binding != T_BIND_UNBOUND && t->time > p->time) {
317 fate = T_FATE_NEWER;
318 } else {
319 fate = T_FATE_STABLE;
321 /* Step 4e: handle missing files */
322 /* If it's missing and there are no actions to create it, boom. */
323 /* If we can't make a target we don't care about, 'sokay */
324 /* We could insist that there are updating actions for all missing */
325 /* files, but if they have dependents we just pretend it's NOTFILE. */
326 if (fate == T_FATE_MISSING && !t->actions && !t->depends) {
327 if (t->flags & T_FLAG_NOCARE) {
328 fate = T_FATE_STABLE;
329 } else {
330 printf("don't know how to make %s\n", t->name);
331 fate = T_FATE_CANTFIND;
334 /* Step 4f: propagate dependents' time & fate. */
335 /* Set leaf time to be our time only if this is a leaf. */
336 t->time = max(t->time, last);
337 t->leaf = leaf ? leaf : t->time ;
338 t->fate = fate;
341 * Step 5: sort dependents by their update time.
343 if (globs.newestfirst) t->depends = make0sort(t->depends);
346 * Step 6: a little harmless tabulating for tracing purposes
348 /* Don't count or report interal includes nodes. */
349 if (t->flags & T_FLAG_INTERNAL) return;
350 if (!(++counts->targets % 1000) && DEBUG_MAKE) printf("...patience...\n");
352 if (fate == T_FATE_ISTMP) counts->temp++;
353 else if (fate == T_FATE_CANTFIND) counts->cantfind++;
354 else if (fate == T_FATE_CANTMAKE && t->actions) counts->cantmake++;
355 else if (fate >= T_FATE_BUILD && fate < T_FATE_BROKEN && t->actions) counts->updating++;
357 if (!(t->flags & T_FLAG_NOTFILE) && fate >= T_FATE_SPOIL) flag = "+";
358 else if (t->binding == T_BIND_EXISTS && p && t->time > p->time) flag = "*";
360 if (DEBUG_MAKEPROG)
361 printf("made%s\t%s\t%s%s\n",
362 flag, target_fate[(int)t->fate],
363 spaces(depth), t->name);
365 if (DEBUG_CAUSES && t->fate >= T_FATE_NEWER && t->fate <= T_FATE_MISSING)
366 printf("%s %s\n", target_fate[ (int)t->fate ], t->name);
371 * make0sort() - reorder TARGETS chain by their time (newest to oldest)
373 static TARGETS *make0sort (TARGETS *chain) {
374 TARGETS *result = 0;
375 /* We walk chain, taking each item and inserting it on the */
376 /* sorted result, with newest items at the front. This involves */
377 /* updating each TARGETS' c->next and c->tail. Note that we */
378 /* make c->tail a valid prev pointer for every entry. Normally, */
379 /* it is only valid at the head, where prev == tail. Note also */
380 /* that while tail is a loop, next ends at the end of the chain. */
382 /* Walk current target list */
383 while (chain) {
384 TARGETS *c = chain;
385 TARGETS *s = result;
387 chain = chain->next;
388 /* Find point s in result for c */
389 while (s && s->target->time > c->target->time) s = s->next;
390 /* Insert c in front of s (might be 0). */
391 /* Don't even think of deciphering this. */
392 c->next = s; /* good even if s = 0 */
393 if (result == s) result = c; /* new head of chain? */
394 if (!s) s = result; /* wrap to ensure a next */
395 if (result != c) s->tail->next = c; /* not head? be prev's next */
396 c->tail = s->tail; /* take on next's prev */
397 s->tail = c; /* make next's prev us */
400 return result;