2 * Copyright 1993, 1995 Christopher Seiwald.
4 * This file is part of Jam - see jam.c for Copyright information.
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
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.
19 * make() - make a target, given its name
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
67 //#ifdef OPT_IMPROVED_PROGRESS_EXT
72 # define max(a,b) ((a)>(b)?(a):(b))
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
[] = {
115 #define spaces(x) (" "+16-(x>16?16:x))
119 * Return 'silent make' flag
121 int is_make_silent (void) {
122 LIST
*var
= var_get("JAM_OPTION_MAKE_UPDATES_SILENT");
123 return (var
&& var
->string
&&
124 strcmp(var
->string
, "ona") != 0 &&
125 strcmp(var
->string
, "no") != 0 &&
126 strcmp(var
->string
, "false") != 0 &&
127 strcmp(var
->string
, "0") != 0);
132 * make() - make a target, given its name
134 int make (int n_targets
, const char **targets
, int anyhow
) {
137 int status
= 0; /* 1 if anything fails */
139 //#ifdef OPT_HEADER_CACHE_EXT
142 memset((char *)counts
, 0, sizeof(*counts
));
143 for (i
= 0; i
< n_targets
; ++i
) {
144 TARGET
*t
= bindtarget(targets
[i
]);
145 make0(t
, 0, 0, counts
, anyhow
);
148 if (!is_make_silent()) {
149 if (counts
->targets
) printf("...found %d target%s...\n", counts
->targets
, multiFormSfx(counts
->targets
));
150 if (counts
->temp
) printf("...using %d temp target%s...\n", counts
->temp
, multiFormSfx(counts
->temp
));
151 if (counts
->updating
) printf("...updating %d target%s...\n", counts
->updating
, multiFormSfx(counts
->updating
));
153 if (counts
->cantfind
) printf("...can't find %d target%s...\n", counts
->cantfind
, multiFormSfx(counts
->cantfind
));
154 if (counts
->cantmake
) printf("...can't make %d target%s...\n", counts
->cantmake
, multiFormSfx(counts
->cantmake
));
156 //k8: don't write cache here, 'cause build directory can be created later; write cache in main jam function
157 //#ifdef OPT_HEADER_CACHE_EXT
160 globs
.updating
= counts
->updating
; //k8
162 globs
.progress
= progress_start(counts
->updating
);
164 status
= counts
->cantfind
|| counts
->cantmake
;
165 for (i
= 0; i
< n_targets
; ++i
) status
|= make1(bindtarget(targets
[i
]));
171 * make0() - bind and scan everything to make a TARGET
173 * Make0() recursively binds a target, searches for #included headers,
174 * calls itself on those headers, and calls itself on any dependents.
178 TARGET
*p
, /* parent */
179 int depth
, /* for display purposes */
180 COUNTS
*counts
, /* for reporting */
181 int anyhow
/* forcibly touch all (real) targets */
185 time_t last
, leaf
, hlast
;
187 const char *flag
= "";
190 /* step 1: initialize */
191 if (DEBUG_MAKEPROG
) printf("make\t--\t%s%s\n", spaces(depth
), t
->name
);
192 t
->fate
= T_FATE_MAKING
;
193 /* step 2: under the influence of "on target" variables, bind the target and search for headers */
194 /* step 2a: set "on target" variables */
195 s
= copysettings(t
->settings
);
197 /* step 2b: find and timestamp the target file (if it's a file) */
198 if (t
->binding
== T_BIND_UNBOUND
&& !(t
->flags
& T_FLAG_NOTFILE
)) {
199 t
->boundname
= search(t
->name
, &t
->time
);
200 t
->binding
= t
->time
? T_BIND_EXISTS
: T_BIND_MISSING
;
202 /* INTERNAL, NOTFILE header nodes have the time of their parents */
203 if (p
&& t
->flags
& T_FLAG_INTERNAL
) ptime
= p
;
204 /* if temp file doesn't exist but parent does, use parent */
205 if (p
&& t
->flags
& T_FLAG_TEMP
&& t
->binding
== T_BIND_MISSING
&& p
->binding
!= T_BIND_MISSING
) {
206 t
->binding
= T_BIND_PARENTS
;
209 #ifdef JAM_OPT_SEMAPHORE
211 LIST
*var
= var_get("JAM_SEMAPHORE");
213 TARGET
*semaphore
= bindtarget(var
->string
);
214 semaphore
->progress
= T_MAKE_SEMAPHORE
;
215 t
->semaphore
= semaphore
;
219 /* step 2c: If its a file, search for headers */
220 if (t
->binding
== T_BIND_EXISTS
) headers(t
);
221 /* step 2d: reset "on target" variables */
224 /* pause for a little progress reporting */
225 if (DEBUG_MAKEPROG
) {
226 if (strcmp(t
->name
, t
->boundname
)) {
227 printf("bind\t--\t%s%s: %s\n", spaces(depth
), t
->name
, t
->boundname
);
229 switch (t
->binding
) {
230 case T_BIND_UNBOUND
: case T_BIND_MISSING
: case T_BIND_PARENTS
:
231 printf("time\t--\t%s%s: %s\n", spaces(depth
), t
->name
, target_bind
[ (int)t
->binding
]);
234 printf("time\t--\t%s%s: %s", spaces(depth
), t
->name
, ctime(&t
->time
));
238 /* step 3: recursively make0() dependents & headers */
239 /* step 3a: recursively make0() dependents */
240 for (c
= t
->depends
; c
; c
= c
->next
) {
241 int internal
= t
->flags
& T_FLAG_INTERNAL
;
243 if (DEBUG_DEPENDS
) printf("%s \"%s\" : \"%s\" ;\n", internal
?"Includes":"Depends", t
->name
, c
->target
->name
);
244 /* warn about circular deps, except for includes, which include each other alot */
245 if (c
->target
->fate
== T_FATE_INIT
) make0(c
->target
, ptime
, depth
+1, counts
, anyhow
);
246 else if (c
->target
->fate
== T_FATE_MAKING
&& !internal
) printf("warning: %s depends on itself\n", c
->target
->name
);
248 /* step 3b: recursively make0() internal includes node */
249 if (t
->includes
) make0(t
->includes
, p
, depth
+1, counts
, anyhow
);
250 /* step 3c: add dependents' includes to our direct dependencies */
252 for (c
= t
->depends
; c
; c
= c
->next
) {
253 if (c
->target
->includes
) {
254 incs
= targetentry(incs
, c
->target
->includes
);
255 /* if the includes are newer than we are their original target also needs to be marked newer */
256 /* this is needed so that 'updated' correctly will include the original target in the $(<) variable */
257 if (c
->target
->includes
->time
> t
->time
) c
->target
->fate
= max(T_FATE_NEWER
, c
->target
->fate
);
260 t
->depends
= targetchain(t
->depends
, incs
);
261 /* step 4: compute time & fate */
262 /* step 4a: pick up dependents' time and fate */
265 fate
= T_FATE_STABLE
;
266 for (c
= t
->depends
; c
; c
= c
->next
) {
267 /* if LEAVES has been applied, we only heed the timestamps of the leaf source nodes */
268 leaf
= max(leaf
, c
->target
->leaf
);
269 if (t
->flags
& T_FLAG_LEAVES
) { last
= leaf
; continue; }
270 last
= max(last
, c
->target
->time
);
271 fate
= max(fate
, c
->target
->fate
);
273 /* step 4b: pick up included headers time */
274 /* if a header is newer than a temp source that includes it, the temp source will need building */
275 hlast
= t
->includes
? t
->includes
->time
: 0;
276 /* step 4c: handle NOUPDATE oddity */
277 /* If a NOUPDATE file exists, make dependents eternally old */
278 /* don't inherit our fate from our dependents */
279 /* decide fate based only upon other flags and our binding (done later) */
280 if (t
->flags
& T_FLAG_NOUPDATE
) {
283 fate
= T_FATE_STABLE
;
285 /* step 4d: determine fate: rebuild target or what? */
288 * If can't find or make child, can't make target.
289 * If children changed, make target.
290 * If target missing, make it.
291 * If children newer, make target.
292 * If temp's children newer than parent, make temp.
293 * If temp's headers newer than parent, make temp.
294 * If deliberately touched, make it.
295 * If up-to-date temp file present, use it.
296 * If target newer than non-notfile parent, mark target newer.
299 * Note this block runs from least to most stable:
300 * as we make it further down the list, the target's
301 * fate is getting stabler.
303 if (fate
>= T_FATE_BROKEN
) {
304 fate
= T_FATE_CANTMAKE
;
305 } else if (fate
>= T_FATE_SPOIL
) {
306 fate
= T_FATE_UPDATE
;
307 } else if (t
->binding
== T_BIND_MISSING
) {
308 fate
= T_FATE_MISSING
;
309 } else if (t
->binding
== T_BIND_EXISTS
&& last
> t
->time
) {
310 fate
= T_FATE_OUTDATED
;
311 } else if (t
->binding
== T_BIND_PARENTS
&& last
> p
->time
) {
312 fate
= T_FATE_NEEDTMP
;
313 } else if (t
->binding
== T_BIND_PARENTS
&& hlast
> p
->time
) {
314 fate
= T_FATE_NEEDTMP
;
315 } else if (t
->flags
& T_FLAG_TOUCHED
) {
316 fate
= T_FATE_TOUCHED
;
317 } else if (anyhow
&& !(t
->flags
& T_FLAG_NOUPDATE
)) {
318 fate
= T_FATE_TOUCHED
;
319 } else if (t
->binding
== T_BIND_EXISTS
&& t
->flags
& T_FLAG_TEMP
) {
321 } else if (t
->binding
== T_BIND_EXISTS
&& p
&& p
->binding
!= T_BIND_UNBOUND
&& t
->time
> p
->time
) {
324 fate
= T_FATE_STABLE
;
326 /* step 4e: handle missing files */
327 /* if it's missing and there are no actions to create it, boom */
328 /* if we can't make a target we don't care about, 'sokay */
329 /* we could insist that there are updating actions for all missing
330 * files, but if they have dependents we just pretend it's NOTFILE */
331 if (fate
== T_FATE_MISSING
&& !t
->actions
&& !t
->depends
) {
332 if (t
->flags
& T_FLAG_NOCARE
) {
333 fate
= T_FATE_STABLE
;
335 printf("don't know how to make %s\n", t
->name
);
336 fate
= T_FATE_CANTFIND
;
339 /* step 4f: propagate dependents' time & fate */
340 /* set leaf time to be our time only if this is a leaf */
341 t
->time
= max(t
->time
, last
);
342 t
->leaf
= leaf
?leaf
:t
->time
;
344 /* step 5: sort dependents by their update time */
345 if (globs
.newestfirst
) t
->depends
= make0sort(t
->depends
);
346 /* step 6: a little harmless tabulating for tracing purposes */
347 /* don't count or report interal includes nodes */
348 if (t
->flags
& T_FLAG_INTERNAL
) return;
350 if (counts
->targets
%4096 == 0 && 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
) printf("made%s\t%s\t%s%s\n", flag
, target_fate
[(int)t
->fate
], spaces(depth
), t
->name
);
361 if (DEBUG_CAUSES
&& t
->fate
>= T_FATE_NEWER
&& t
->fate
<= T_FATE_MISSING
) {
362 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
) {
372 /* we walk chain, taking each item and inserting it on the
373 * sorted result, with newest items at the front */
374 /* this involves updating each TARGETS' c->next and c->tail */
375 /* note that we make c->tail a valid prev pointer for every entry */
376 /* normally, it is only valid at the head, where prev == tail */
377 /* note also that while tail is a loop, next ends at the end of the chain */
378 /* walk current target list */
380 TARGETS
*c
= chain
, *s
= result
;
383 /* find point s in result for c */
384 while (s
&& s
->target
->time
> c
->target
->time
) s
= s
->next
;
385 /* insert c in front of s (might be 0) */
386 /* don't even think of deciphering this */
387 c
->next
= s
; /* good even if s = 0 */
388 if (result
== s
) result
= c
; /* new head of chain? */
389 if (!s
) s
= result
; /* wrap to ensure a next */
390 if (result
!= c
) s
->tail
->next
= c
; /* not head? be prev's next */
391 c
->tail
= s
->tail
; /* take on next's prev */
392 s
->tail
= c
; /* make next's prev us */