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 * make() - make a target, given its name
121 int make (int n_targets
, const char **targets
, int anyhow
) {
124 int status
= 0; /* 1 if anything fails */
126 //#ifdef OPT_HEADER_CACHE_EXT
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
);
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
144 //#ifdef OPT_IMPROVED_PROGRESS_EXT
145 globs
.updating
= counts
->updating
;
146 globs
.progress
= progress_start(counts
->updating
);
148 status
= counts
->cantfind
|| counts
->cantmake
;
149 for (i
= 0; i
< n_targets
; ++i
) status
|= make1(bindtarget(targets
[i
]));
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.
162 TARGET
*p
, /* parent */
163 int depth
, /* for display purposes */
164 COUNTS
*counts
, /* for reporting */
165 int anyhow
/* forcibly touch all (real) targets */
169 time_t last
, leaf
, hlast
;
171 const char *flag
= "";
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
);
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
;
193 #ifdef JAM_OPT_SEMAPHORE
195 LIST
*var
= var_get("JAM_SEMAPHORE");
197 TARGET
*semaphore
= bindtarget(var
->string
);
198 semaphore
->progress
= T_MAKE_SEMAPHORE
;
199 t
->semaphore
= semaphore
;
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 */
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
]);
218 printf("time\t--\t%s%s: %s", spaces(depth
), t
->name
, ctime(&t
->time
));
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 */
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 */
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
) {
267 fate
= T_FATE_STABLE
;
269 /* step 4d: determine fate: rebuild target or what? */
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.
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
) {
305 } else if (t
->binding
== T_BIND_EXISTS
&& p
&& p
->binding
!= T_BIND_UNBOUND
&& t
->time
> p
->time
) {
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
;
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
;
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;
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
) {
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 */
364 TARGETS
*c
= chain
, *s
= result
;
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 */