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