added pkg-config-has
[k8jam.git] / make.c
blob4017babbe805a151d90b6fca84e54b91bd575d74
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;
161 * Step 1: initialize
163 if (DEBUG_MAKEPROG) printf("make\t--\t%s%s\n", spaces(depth), t->name);
164 t->fate = T_FATE_MAKING;
167 * Step 2: under the influence of "on target" variables,
168 * bind the target and search for headers.
170 /* Step 2a: set "on target" variables. */
171 s = copysettings(t->settings);
172 pushsettings(s);
173 /* Step 2b: find and timestamp the target file (if it's a file). */
174 if (t->binding == T_BIND_UNBOUND && !(t->flags & T_FLAG_NOTFILE)) {
175 t->boundname = search(t->name, &t->time);
176 t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
178 /* INTERNAL, NOTFILE header nodes have the time of their parents */
179 if (p && t->flags & T_FLAG_INTERNAL) ptime = p;
180 /* If temp file doesn't exist but parent does, use parent */
181 if (p && t->flags & T_FLAG_TEMP && t->binding == T_BIND_MISSING && p->binding != T_BIND_MISSING) {
182 t->binding = T_BIND_PARENTS;
183 ptime = p;
185 /* Step 2c: If its a file, search for headers. */
186 if (t->binding == T_BIND_EXISTS) headers(t);
187 /* Step 2d: reset "on target" variables */
188 popsettings(s);
189 freesettings(s);
192 * Pause for a little progress reporting
194 if (DEBUG_MAKEPROG) {
195 if (strcmp(t->name, t->boundname)) {
196 printf("bind\t--\t%s%s: %s\n", spaces(depth), t->name, t->boundname);
198 switch (t->binding) {
199 case T_BIND_UNBOUND: case T_BIND_MISSING: case T_BIND_PARENTS:
200 printf("time\t--\t%s%s: %s\n", spaces(depth), t->name, target_bind[ (int)t->binding ]);
201 break;
202 case T_BIND_EXISTS:
203 printf("time\t--\t%s%s: %s", spaces(depth), t->name, ctime(&t->time));
204 break;
209 * Step 3: recursively make0() dependents & headers
211 /* Step 3a: recursively make0() dependents */
212 for (c = t->depends; c; c = c->next) {
213 int internal = t->flags & T_FLAG_INTERNAL;
215 if (DEBUG_DEPENDS)
216 printf("%s \"%s\" : \"%s\" ;\n",
217 internal ? "Includes" : "Depends",
218 t->name, c->target->name);
220 /* Warn about circular deps, except for includes, */
221 /* which include each other alot. */
222 if (c->target->fate == T_FATE_INIT) make0(c->target, ptime, depth+1, counts, anyhow);
223 else if (c->target->fate == T_FATE_MAKING && !internal) printf("warning: %s depends on itself\n", c->target->name);
225 /* Step 3b: recursively make0() internal includes node */
226 if (t->includes) make0(t->includes, p, depth+1, counts, anyhow);
227 /* Step 3c: add dependents' includes to our direct dependencies */
228 incs = 0;
229 for (c = t->depends; c; c = c->next) {
230 if (c->target->includes) {
231 incs = targetentry(incs, c->target->includes);
232 /* If the includes are newer than we are their original target
233 also needs to be marked newer. This is needed so that 'updated'
234 correctly will include the original target in the $(<) variable. */
235 if (c->target->includes->time > t->time) c->target->fate = max(T_FATE_NEWER, c->target->fate);
239 t->depends = targetchain(t->depends, incs);
242 * Step 4: compute time & fate
244 /* Step 4a: pick up dependents' time and fate */
245 last = 0;
246 leaf = 0;
247 fate = T_FATE_STABLE;
248 for (c = t->depends; c; c = c->next) {
249 /* If LEAVES has been applied, we only heed the timestamps of */
250 /* the leaf source nodes. */
251 leaf = max(leaf, c->target->leaf);
252 if (t->flags & T_FLAG_LEAVES) {
253 last = leaf;
254 continue;
256 last = max(last, c->target->time);
257 fate = max(fate, c->target->fate);
260 /* Step 4b: pick up included headers time */
262 * If a header is newer than a temp source that includes it,
263 * the temp source will need building.
265 hlast = t->includes ? t->includes->time : 0;
266 /* Step 4c: handle NOUPDATE oddity */
268 * If a NOUPDATE file exists, make dependents eternally old.
269 * Don't inherit our fate from our dependents. Decide fate
270 * based only upon other flags and our binding (done later).
272 if (t->flags & T_FLAG_NOUPDATE) {
273 last = 0;
274 t->time = 0;
275 fate = T_FATE_STABLE;
277 /* Step 4d: determine fate: rebuild target or what? */
279 In English:
280 If can't find or make child, can't make target.
281 If children changed, make target.
282 If target missing, make it.
283 If children newer, make target.
284 If temp's children newer than parent, make temp.
285 If temp's headers newer than parent, make temp.
286 If deliberately touched, make it.
287 If up-to-date temp file present, use it.
288 If target newer than non-notfile parent, mark target newer.
289 Otherwise, stable!
291 Note this block runs from least to most stable:
292 as we make it further down the list, the target's
293 fate is getting stabler.
295 if (fate >= T_FATE_BROKEN) {
296 fate = T_FATE_CANTMAKE;
297 } else if (fate >= T_FATE_SPOIL) {
298 fate = T_FATE_UPDATE;
299 } else if (t->binding == T_BIND_MISSING) {
300 fate = T_FATE_MISSING;
301 } else if (t->binding == T_BIND_EXISTS && last > t->time) {
302 fate = T_FATE_OUTDATED;
303 } else if (t->binding == T_BIND_PARENTS && last > p->time) {
304 fate = T_FATE_NEEDTMP;
305 } else if (t->binding == T_BIND_PARENTS && hlast > p->time) {
306 fate = T_FATE_NEEDTMP;
307 } else if (t->flags & T_FLAG_TOUCHED) {
308 fate = T_FATE_TOUCHED;
309 } else if (anyhow && !(t->flags & T_FLAG_NOUPDATE)) {
310 fate = T_FATE_TOUCHED;
311 } else if (t->binding == T_BIND_EXISTS && t->flags & T_FLAG_TEMP) {
312 fate = T_FATE_ISTMP;
313 } else if (t->binding == T_BIND_EXISTS && p && p->binding != T_BIND_UNBOUND && t->time > p->time) {
314 fate = T_FATE_NEWER;
315 } else {
316 fate = T_FATE_STABLE;
318 /* Step 4e: handle missing files */
319 /* If it's missing and there are no actions to create it, boom. */
320 /* If we can't make a target we don't care about, 'sokay */
321 /* We could insist that there are updating actions for all missing */
322 /* files, but if they have dependents we just pretend it's NOTFILE. */
323 if (fate == T_FATE_MISSING && !t->actions && !t->depends) {
324 if (t->flags & T_FLAG_NOCARE) {
325 fate = T_FATE_STABLE;
326 } else {
327 printf("don't know how to make %s\n", t->name);
328 fate = T_FATE_CANTFIND;
331 /* Step 4f: propagate dependents' time & fate. */
332 /* Set leaf time to be our time only if this is a leaf. */
333 t->time = max(t->time, last);
334 t->leaf = leaf ? leaf : t->time ;
335 t->fate = fate;
338 * Step 5: sort dependents by their update time.
340 if (globs.newestfirst) t->depends = make0sort(t->depends);
343 * Step 6: a little harmless tabulating for tracing purposes
345 /* Don't count or report interal includes nodes. */
346 if (t->flags & T_FLAG_INTERNAL) return;
347 if (!(++counts->targets % 1000) && DEBUG_MAKE) printf("...patience...\n");
349 if (fate == T_FATE_ISTMP) counts->temp++;
350 else if (fate == T_FATE_CANTFIND) counts->cantfind++;
351 else if (fate == T_FATE_CANTMAKE && t->actions) counts->cantmake++;
352 else if (fate >= T_FATE_BUILD && fate < T_FATE_BROKEN && t->actions) counts->updating++;
354 if (!(t->flags & T_FLAG_NOTFILE) && fate >= T_FATE_SPOIL) flag = "+";
355 else if (t->binding == T_BIND_EXISTS && p && t->time > p->time) flag = "*";
357 if (DEBUG_MAKEPROG)
358 printf("made%s\t%s\t%s%s\n",
359 flag, target_fate[(int)t->fate],
360 spaces(depth), t->name);
362 if (DEBUG_CAUSES && t->fate >= T_FATE_NEWER && t->fate <= T_FATE_MISSING)
363 printf("%s %s\n", target_fate[ (int)t->fate ], t->name);
368 * make0sort() - reorder TARGETS chain by their time (newest to oldest)
370 static TARGETS *make0sort (TARGETS *chain) {
371 TARGETS *result = 0;
372 /* We walk chain, taking each item and inserting it on the */
373 /* sorted result, with newest items at the front. This involves */
374 /* updating each TARGETS' c->next and c->tail. Note that we */
375 /* make c->tail a valid prev pointer for every entry. Normally, */
376 /* it is only valid at the head, where prev == tail. Note also */
377 /* that while tail is a loop, next ends at the end of the chain. */
379 /* Walk current target list */
380 while (chain) {
381 TARGETS *c = chain;
382 TARGETS *s = result;
384 chain = chain->next;
385 /* Find point s in result for c */
386 while (s && s->target->time > c->target->time) s = s->next;
387 /* Insert c in front of s (might be 0). */
388 /* Don't even think of deciphering this. */
389 c->next = s; /* good even if s = 0 */
390 if (result == s) result = c; /* new head of chain? */
391 if (!s) s = result; /* wrap to ensure a next */
392 if (result != c) s->tail->next = c; /* not head? be prev's next */
393 c->tail = s->tail; /* take on next's prev */
394 s->tail = c; /* make next's prev us */
397 return result;