Imported Upstream version 1.51.0
[platform/upstream/boost.git] / tools / build / v2 / engine / make.c
1 /*
2  * Copyright 1993, 1995 Christopher Seiwald.
3  *
4  * This file is part of Jam - see jam.c for Copyright information.
5  */
6
7 /*  This file is ALSO:
8  *  Copyright 2001-2004 David Abrahams.
9  *  Distributed under the Boost Software License, Version 1.0.
10  *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11  */
12
13 /*
14  * make.c - bring a target up to date, once rules are in place.
15  *
16  * This modules controls the execution of rules to bring a target and its
17  * dependencies up to date. It is invoked after the targets, rules, et. al.
18  * described in rules.h are created by the interpreting jam files.
19  *
20  * This file contains the main make() entry point and the first pass make0().
21  * The second pass, make1(), which actually does the command execution, is in
22  * make1.c.
23  *
24  * External routines:
25  *  make() - make a target, given its name
26  *
27  * Internal routines:
28  *  make0() - bind and scan everything to make a TARGET
29  *  make0sort() - reorder TARGETS chain by their time (newest to oldest)
30  *
31  * 12/26/93 (seiwald) - allow NOTIME targets to be expanded via $(<), $(>).
32  * 01/04/94 (seiwald) - print all targets, bounded, when tracing commands.
33  * 04/08/94 (seiwald) - progress report now reflects only targets with actions.
34  * 04/11/94 (seiwald) - Combined deps & headers into deps[2] in TARGET.
35  * 12/20/94 (seiwald) - NOTIME renamed NOTFILE.
36  * 12/20/94 (seiwald) - make0() headers after determining fate of target, so
37  *                      that headers are not seen as being dependent on
38  *                      themselves.
39  * 01/19/95 (seiwald) - distinguish between CANTFIND/CANTMAKE targets.
40  * 02/02/95 (seiwald) - propagate leaf source time for new LEAVES rule.
41  * 02/14/95 (seiwald) - NOUPDATE rule means don't update existing target.
42  * 08/22/95 (seiwald) - NOUPDATE targets immune to anyhow (-a) flag.
43  * 09/06/00 (seiwald) - NOCARE affects targets with sources/actions.
44  * 03/02/01 (seiwald) - reverse NOCARE change.
45  * 03/14/02 (seiwald) - TEMPORARY targets no longer take on parents age.
46  * 03/16/02 (seiwald) - support for -g (reorder builds by source time).
47  */
48
49 #include "jam.h"
50
51 #include "lists.h"
52 #include "parse.h"
53 #include "variable.h"
54 #include "rules.h"
55
56 #ifdef OPT_HEADER_CACHE_EXT
57     #include "hcache.h"
58 #endif
59
60 #include "search.h"
61 #include "object.h"
62 #include "make.h"
63 #include "headers.h"
64 #include "command.h"
65 #include <assert.h>
66
67 #ifndef max
68     #define max( a,b ) ((a)>(b)?(a):(b))
69 #endif
70
71 static TARGETS * make0sort( TARGETS * c );
72
73 #ifdef OPT_GRAPH_DEBUG_EXT
74     static void dependGraphOutput( TARGET * t, int depth );
75 #endif
76
77 static const char * target_fate[] =
78 {
79     "init",     /* T_FATE_INIT     */
80     "making",   /* T_FATE_MAKING   */
81     "stable",   /* T_FATE_STABLE   */
82     "newer",    /* T_FATE_NEWER    */
83     "temp",     /* T_FATE_ISTMP    */
84     "touched",  /* T_FATE_TOUCHED  */
85     "rebuild",  /* T_FATE_REBUILD  */
86     "missing",  /* T_FATE_MISSING  */
87     "needtmp",  /* T_FATE_NEEDTMP  */
88     "old",      /* T_FATE_OUTDATED */
89     "update",   /* T_FATE_UPDATE   */
90     "nofind",   /* T_FATE_CANTFIND */
91     "nomake"    /* T_FATE_CANTMAKE */
92 };
93
94 static const char * target_bind[] =
95 {
96     "unbound",
97     "missing",
98     "parents",
99     "exists",
100 };
101
102 # define spaces(x) ( "                    " + ( x > 20 ? 0 : 20-x ) )
103
104
105 /*
106  * make() - make a target, given its name.
107  */
108
109 int make( LIST * targets, int anyhow )
110 {
111     COUNTS counts[ 1 ];
112     int    status = 0;     /* 1 if anything fails */
113
114 #ifdef OPT_HEADER_CACHE_EXT
115     hcache_init();
116 #endif
117
118     memset( (char *)counts, 0, sizeof( *counts ) );
119
120     /* First bind all targets with LOCATE_TARGET setting. This is needed to
121      * correctly handle dependencies to generated headers.
122      */
123     bind_explicitly_located_targets();
124
125     {
126         LISTITER iter, end;
127         PROFILE_ENTER( MAKE_MAKE0 );
128         for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) )
129         {
130             TARGET * t = bindtarget( list_item( iter ) );
131             if ( t->fate == T_FATE_INIT )
132                 make0( t, 0, 0, counts, anyhow );
133         }
134         PROFILE_EXIT( MAKE_MAKE0 );
135     }
136
137 #ifdef OPT_GRAPH_DEBUG_EXT
138     if ( DEBUG_GRAPH )
139     {
140         LISTITER iter, end;
141         for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) )
142            dependGraphOutput( bindtarget( list_item( iter ) ), 0 );
143     }
144 #endif
145
146     if ( DEBUG_MAKE )
147     {
148         if ( counts->targets )
149             printf( "...found %d target%s...\n", counts->targets,
150                 counts->targets > 1 ? "s" : "" );
151         if ( counts->temp )
152             printf( "...using %d temp target%s...\n", counts->temp,
153                 counts->temp > 1 ? "s" : "" );
154         if ( counts->updating )
155             printf( "...updating %d target%s...\n", counts->updating,
156                 counts->updating > 1 ? "s" : "" );
157         if ( counts->cantfind )
158             printf( "...can't find %d target%s...\n", counts->cantfind,
159                 counts->cantfind > 1 ? "s" : "" );
160         if ( counts->cantmake )
161             printf( "...can't make %d target%s...\n", counts->cantmake,
162                 counts->cantmake > 1 ? "s" : "" );
163     }
164
165     status = counts->cantfind || counts->cantmake;
166
167     {
168         LISTITER iter, end;
169         PROFILE_ENTER( MAKE_MAKE1 );
170         for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) )
171             status |= make1( bindtarget( list_item( iter ) ) );
172         PROFILE_EXIT( MAKE_MAKE1 );
173     }
174
175     return status;
176 }
177
178
179 /* Force any dependants of t that have already at least begun being visited by
180  * make0() to be updated.
181  */
182
183 static void update_dependants( TARGET * t )
184 {
185     TARGETS * q;
186
187     for ( q = t->dependants; q; q = q->next )
188     {
189         TARGET * p = q->target;
190         char fate0 = p->fate;
191
192         /* If we have already at least begun visiting it and we are not already
193          * rebuilding it for other reasons.
194          */
195         if ( ( fate0 != T_FATE_INIT ) && ( fate0 < T_FATE_BUILD ) )
196         {
197             p->fate = T_FATE_UPDATE;
198
199             if ( DEBUG_FATE )
200             {
201                 printf( "fate change  %s from %s to %s (as dependant of %s)\n",
202                         object_str( p->name ), target_fate[ (int) fate0 ], target_fate[ (int) p->fate ], object_str( t->name ) );
203             }
204
205             /* If we are done visiting it, go back and make sure its dependants
206              * get rebuilt.
207              */
208             if ( fate0 > T_FATE_MAKING )
209                 update_dependants( p );
210         }
211     }
212 }
213
214
215 /*
216  * Make sure that all of t's rebuilds get rebuilt.
217  */
218
219 static void force_rebuilds( TARGET * t )
220 {
221     TARGETS * d;
222     for ( d = t->rebuilds; d; d = d->next )
223     {
224         TARGET * r = d->target;
225
226         /* If it is not already being rebuilt for other reasons. */
227         if ( r->fate < T_FATE_BUILD )
228         {
229             if ( DEBUG_FATE )
230                 printf( "fate change  %s from %s to %s (by rebuild)\n",
231                         object_str( r->name ), target_fate[ (int) r->fate ], target_fate[ T_FATE_REBUILD ] );
232
233             /* Force rebuild it. */
234             r->fate = T_FATE_REBUILD;
235
236             /* And make sure its dependants are updated too. */
237             update_dependants( r );
238         }
239     }
240 }
241
242
243 /*
244  * make0() - bind and scan everything to make a TARGET.
245  *
246  * Recursively binds a target, searches for #included headers, calls itself on
247  * those headers and any dependencies.
248  */
249
250 void make0
251 (
252     TARGET * t,
253     TARGET * p,       /* parent */
254     int      depth,   /* for display purposes */
255     COUNTS * counts,  /* for reporting */
256     int      anyhow
257 )  /* forcibly touch all (real) targets */
258 {
259     TARGETS    * c;
260     TARGET     * ptime = t;
261     time_t       last;
262     time_t       leaf;
263     time_t       hlast;
264     int          fate;
265     char const * flag = "";
266     SETTINGS   * s;
267
268 #ifdef OPT_GRAPH_DEBUG_EXT
269     int savedFate, oldTimeStamp;
270 #endif
271
272     if ( DEBUG_MAKEPROG )
273         printf( "make\t--\t%s%s\n", spaces( depth ), object_str( t->name ) );
274
275     /*
276      * Step 1: initialize
277      */
278
279     if ( DEBUG_MAKEPROG )
280         printf( "make\t--\t%s%s\n", spaces( depth ), object_str( t->name ) );
281
282     t->fate = T_FATE_MAKING;
283
284     /*
285      * Step 2: under the influence of "on target" variables,
286      * bind the target and search for headers.
287      */
288
289     /* Step 2a: set "on target" variables. */
290     s = copysettings( t->settings );
291     pushsettings( root_module(), s );
292
293     /* Step 2b: find and timestamp the target file (if it is a file). */
294     if ( ( t->binding == T_BIND_UNBOUND ) && !( t->flags & T_FLAG_NOTFILE ) )
295     {
296         OBJECT * another_target;
297         object_free( t->boundname );
298         t->boundname = search( t->name, &t->time, &another_target,
299                                t->flags & T_FLAG_ISFILE );
300         /* If it was detected that this target refers to an already existing and
301          * bound one, we add an include dependency, so that every target
302          * depending on us will depend on that other target as well.
303          */
304         if ( another_target )
305             target_include( t, bindtarget( another_target ) );
306
307         t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
308     }
309
310     /* INTERNAL, NOTFILE header nodes have the time of their parents. */
311     if ( p && ( t->flags & T_FLAG_INTERNAL ) )
312         ptime = p;
313
314     /* If temp file does not exist but parent does, use parent. */
315     if ( p && ( t->flags & T_FLAG_TEMP ) &&
316         ( t->binding == T_BIND_MISSING ) &&
317         ( p->binding != T_BIND_MISSING ) )
318     {
319         t->binding = T_BIND_PARENTS;
320         ptime = p;
321     }
322
323 #ifdef OPT_SEMAPHORE
324     {
325         LIST * var = var_get( root_module(), constant_JAM_SEMAPHORE );
326         if ( !list_empty( var ) )
327         {
328             TARGET * semaphore = bindtarget( list_front( var ) );
329             semaphore->progress = T_MAKE_SEMAPHORE;
330             t->semaphore = semaphore;
331         }
332     }
333 #endif
334
335     /* Step 2c: If its a file, search for headers. */
336     if ( t->binding == T_BIND_EXISTS )
337         headers( t );
338
339     /* Step 2d: reset "on target" variables. */
340     popsettings( root_module(), s );
341     freesettings( s );
342
343     /*
344      * Pause for a little progress reporting .
345      */
346
347     if ( DEBUG_BIND )
348     {
349         if ( ! object_equal( t->name, t->boundname ) )
350             printf( "bind\t--\t%s%s: %s\n",
351                 spaces( depth ), object_str( t->name ), object_str( t->boundname ) );
352
353         switch ( t->binding )
354         {
355         case T_BIND_UNBOUND:
356         case T_BIND_MISSING:
357         case T_BIND_PARENTS:
358             printf( "time\t--\t%s%s: %s\n",
359                 spaces( depth ), object_str( t->name ), target_bind[ (int) t->binding ] );
360             break;
361
362         case T_BIND_EXISTS:
363             printf( "time\t--\t%s%s: %s",
364                 spaces( depth ), object_str( t->name ), ctime( &t->time ) );
365             break;
366         }
367     }
368
369     /*
370      * Step 3: recursively make0() dependencies & headers.
371      */
372
373     /* Step 3a: recursively make0() dependencies. */
374     for ( c = t->depends; c; c = c->next )
375     {
376         int internal = t->flags & T_FLAG_INTERNAL;
377
378         /* Warn about circular deps, except for includes, which include each
379          * other alot.
380          */
381         if ( c->target->fate == T_FATE_INIT )
382             make0( c->target, ptime, depth + 1, counts, anyhow );
383         else if ( c->target->fate == T_FATE_MAKING && !internal )
384             printf( "warning: %s depends on itself\n", object_str( c->target->name ) );
385     }
386
387     /* Step 3b: recursively make0() internal includes node. */
388     if ( t->includes )
389         make0( t->includes, p, depth + 1, counts, anyhow );
390
391     /* Step 3c: add dependencies' includes to our direct dependencies. */
392     {
393         TARGETS * incs = 0;
394         for ( c = t->depends; c; c = c->next )
395             if ( c->target->includes )
396                 incs = targetentry( incs, c->target->includes );
397         t->depends = targetchain( t->depends, incs );
398     }
399
400     /*
401      * Step 4: compute time & fate
402      */
403
404     /* Step 4a: pick up dependencies' time and fate */
405     last = 0;
406     leaf = 0;
407     fate = T_FATE_STABLE;
408     for ( c = t->depends; c; c = c->next )
409     {
410         /* If LEAVES has been applied, we only heed the timestamps of the leaf
411          * source nodes.
412          */
413         leaf = max( leaf, c->target->leaf );
414
415         if ( t->flags & T_FLAG_LEAVES )
416         {
417             last = leaf;
418             continue;
419         }
420
421         last = max( last, c->target->time );
422         fate = max( fate, c->target->fate );
423
424 #ifdef OPT_GRAPH_DEBUG_EXT
425         if ( DEBUG_FATE )
426             if ( fate < c->target->fate )
427                 printf( "fate change %s from %s to %s by dependency %s\n",
428                     object_str( t->name ), target_fate[(int) fate], target_fate[(int) c->target->fate],
429                     object_str( c->target->name ) );
430 #endif
431     }
432
433     /* Step 4b: pick up included headers time */
434
435     /*
436      * If a header is newer than a temp source that includes it,
437      * the temp source will need building.
438      */
439
440     hlast = t->includes ? t->includes->time : 0;
441
442     /* Step 4c: handle NOUPDATE oddity.
443      *
444      * If a NOUPDATE file exists, mark it as having eternally old dependencies.
445      * Do not inherit our fate from our dependencies. Decide fate based only on
446      * other flags and our binding (done later).
447      */
448     if ( t->flags & T_FLAG_NOUPDATE )
449     {
450 #ifdef OPT_GRAPH_DEBUG_EXT
451         if ( DEBUG_FATE )
452             if ( fate != T_FATE_STABLE )
453                 printf( "fate change  %s back to stable, NOUPDATE.\n",
454                     object_str( t->name ) );
455 #endif
456
457         last = 0;
458         t->time = 0;
459
460         /* Do not inherit our fate from our dependencies. Decide fate based only
461          * upon other flags and our binding (done later).
462          */
463         fate = T_FATE_STABLE;
464     }
465
466     /* Step 4d: determine fate: rebuild target or what? */
467
468     /*
469         In English:
470         If can not find or make child, can not make target.
471         If children changed, make target.
472         If target missing, make it.
473         If children newer, make target.
474         If temp's children newer than parent, make temp.
475         If temp's headers newer than parent, make temp.
476         If deliberately touched, make it.
477         If up-to-date temp file present, use it.
478         If target newer than non-notfile parent, mark target newer.
479         Otherwise, stable!
480
481         Note this block runs from least to most stable:
482         as we make it further down the list, the target's
483         fate is getting stabler.
484     */
485
486 #ifdef OPT_GRAPH_DEBUG_EXT
487     savedFate = fate;
488     oldTimeStamp = 0;
489 #endif
490
491     if ( fate >= T_FATE_BROKEN )
492     {
493         fate = T_FATE_CANTMAKE;
494     }
495     else if ( fate >= T_FATE_SPOIL )
496     {
497         fate = T_FATE_UPDATE;
498     }
499     else if ( t->binding == T_BIND_MISSING )
500     {
501         fate = T_FATE_MISSING;
502     }
503     else if ( ( t->binding == T_BIND_EXISTS ) && ( last > t->time ) )
504     {
505 #ifdef OPT_GRAPH_DEBUG_EXT
506         oldTimeStamp = 1;
507 #endif
508         fate = T_FATE_OUTDATED;
509     }
510     else if ( ( t->binding == T_BIND_PARENTS ) && ( last > p->time ) )
511     {
512 #ifdef OPT_GRAPH_DEBUG_EXT
513         oldTimeStamp = 1;
514 #endif
515         fate = T_FATE_NEEDTMP;
516     }
517     else if ( ( t->binding == T_BIND_PARENTS ) && ( hlast > p->time ) )
518     {
519         fate = T_FATE_NEEDTMP;
520     }
521     else if ( t->flags & T_FLAG_TOUCHED )
522     {
523         fate = T_FATE_TOUCHED;
524     }
525     else if ( anyhow && !( t->flags & T_FLAG_NOUPDATE ) )
526     {
527         fate = T_FATE_TOUCHED;
528     }
529     else if ( ( t->binding == T_BIND_EXISTS ) && ( t->flags & T_FLAG_TEMP ) )
530     {
531         fate = T_FATE_ISTMP;
532     }
533     else if ( ( t->binding == T_BIND_EXISTS ) && p &&
534          ( p->binding != T_BIND_UNBOUND ) && ( t->time > p->time ) )
535     {
536 #ifdef OPT_GRAPH_DEBUG_EXT
537         oldTimeStamp = 1;
538 #endif
539         fate = T_FATE_NEWER;
540     }
541     else
542     {
543         fate = T_FATE_STABLE;
544     }
545 #ifdef OPT_GRAPH_DEBUG_EXT
546     if ( DEBUG_FATE && ( fate != savedFate ) )
547         {
548         if ( savedFate == T_FATE_STABLE )
549             printf( "fate change  %s set to %s%s\n", object_str( t->name ),
550                 target_fate[ fate ], oldTimeStamp ? " (by timestamp)" : "" );
551         else
552             printf( "fate change  %s from %s to %s%s\n", object_str( t->name ),
553                 target_fate[ savedFate ], target_fate[ fate ],
554                 oldTimeStamp ? " (by timestamp)" : "" );
555         }
556 #endif
557
558     /* Step 4e: handle missing files */
559     /* If it is missing and there are no actions to create it, boom. */
560     /* If we can not make a target we do not care about it, okay. */
561     /* We could insist that there are updating actions for all missing */
562     /* files, but if they have dependencies we just pretend it is a NOTFILE. */
563
564     if ( ( fate == T_FATE_MISSING ) && !t->actions && !t->depends )
565     {
566         if ( t->flags & T_FLAG_NOCARE )
567         {
568 #ifdef OPT_GRAPH_DEBUG_EXT
569             if ( DEBUG_FATE )
570                 printf( "fate change %s to STABLE from %s, "
571                     "no actions, no dependencies and do not care\n",
572                     object_str( t->name ), target_fate[ fate ] );
573 #endif
574             fate = T_FATE_STABLE;
575         }
576         else
577         {
578             printf( "don't know how to make %s\n", object_str( t->name ) );
579             fate = T_FATE_CANTFIND;
580         }
581     }
582
583     /* Step 4f: propagate dependencies' time & fate. */
584     /* Set leaf time to be our time only if this is a leaf. */
585
586     t->time = max( t->time, last );
587     t->leaf = leaf ? leaf : t->time ;
588     /* This target's fate may have been updated by virtue of following some
589      * target's rebuilds list, so only allow it to be increased to the fate we
590      * have calculated. Otherwise, grab its new fate.
591      */
592     if ( fate > t->fate )
593         t->fate = fate;
594     else
595         fate = t->fate;
596
597     /* Step 4g: if this target needs to be built, force rebuild everything in
598      * this target's rebuilds list.
599      */
600     if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )
601         force_rebuilds( t );
602
603     /*
604      * Step 5: sort dependencies by their update time.
605      */
606
607     if ( globs.newestfirst )
608         t->depends = make0sort( t->depends );
609
610     /*
611      * Step 6: a little harmless tabulating for tracing purposes
612      */
613
614     /* Do not count or report interal includes nodes. */
615     if ( t->flags & T_FLAG_INTERNAL )
616         return;
617
618     if ( counts )
619     {
620 #ifdef OPT_IMPROVED_PATIENCE_EXT
621         ++counts->targets;
622 #else
623         if ( !( ++counts->targets % 1000 ) && DEBUG_MAKE )
624             printf( "...patience...\n" );
625 #endif
626
627         if ( fate == T_FATE_ISTMP )
628             ++counts->temp;
629         else if ( fate == T_FATE_CANTFIND )
630             ++counts->cantfind;
631         else if ( ( fate == T_FATE_CANTMAKE ) && t->actions )
632             ++counts->cantmake;
633         else if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) &&
634             t->actions )
635             ++counts->updating;
636     }
637
638     if ( !( t->flags & T_FLAG_NOTFILE ) && ( fate >= T_FATE_SPOIL ) )
639         flag = "+";
640     else if ( ( t->binding == T_BIND_EXISTS ) && p && ( t->time > p->time ) )
641         flag = "*";
642
643     if ( DEBUG_MAKEPROG )
644         printf( "made%s\t%s\t%s%s\n", flag, target_fate[ (int) t->fate ],
645             spaces( depth ), object_str( t->name ) );
646 }
647
648
649 #ifdef OPT_GRAPH_DEBUG_EXT
650
651 static const char * target_name( TARGET * t )
652 {
653     static char buf[ 1000 ];
654     if ( t->flags & T_FLAG_INTERNAL )
655     {
656         sprintf( buf, "%s (internal node)", object_str( t->name ) );
657         return buf;
658     }
659     return object_str( t->name );
660 }
661
662
663 /*
664  * dependGraphOutput() - output the DG after make0 has run.
665  */
666
667 static void dependGraphOutput( TARGET * t, int depth )
668 {
669     TARGETS * c;
670
671     if ( ( t->flags & T_FLAG_VISITED ) || !t->name || !t->boundname )
672         return;
673
674     t->flags |= T_FLAG_VISITED;
675
676     switch ( t->fate )
677     {
678     case T_FATE_TOUCHED:
679     case T_FATE_MISSING:
680     case T_FATE_OUTDATED:
681     case T_FATE_UPDATE:
682         printf( "->%s%2d Name: %s\n", spaces( depth ), depth, target_name( t ) );
683         break;
684     default:
685         printf( "  %s%2d Name: %s\n", spaces( depth ), depth, target_name( t ) );
686         break;
687     }
688
689     if ( ! object_equal( t->name, t->boundname ) )
690         printf( "  %s    Loc: %s\n", spaces( depth ), object_str( t->boundname ) );
691
692     switch ( t->fate )
693     {
694     case T_FATE_STABLE:
695         printf( "  %s       : Stable\n", spaces( depth ) );
696         break;
697     case T_FATE_NEWER:
698         printf( "  %s       : Newer\n", spaces( depth ) );
699         break;
700     case T_FATE_ISTMP:
701         printf( "  %s       : Up to date temp file\n", spaces( depth ) );
702         break;
703     case T_FATE_NEEDTMP:
704         printf( "  %s       : Temporary file, to be updated\n", spaces( depth ) );
705         break;
706     case T_FATE_TOUCHED:
707         printf( "  %s       : Been touched, updating it\n", spaces( depth ) );
708         break;
709     case T_FATE_MISSING:
710         printf( "  %s       : Missing, creating it\n", spaces( depth ) );
711         break;
712     case T_FATE_OUTDATED:
713         printf( "  %s       : Outdated, updating it\n", spaces( depth ) );
714         break;
715     case T_FATE_REBUILD:
716         printf( "  %s       : Rebuild, updating it\n", spaces( depth ) );
717         break;
718     case T_FATE_UPDATE:
719         printf( "  %s       : Updating it\n", spaces( depth ) );
720         break;
721     case T_FATE_CANTFIND:
722         printf( "  %s       : Can not find it\n", spaces( depth ) );
723         break;
724     case T_FATE_CANTMAKE:
725         printf( "  %s       : Can make it\n", spaces( depth ) );
726         break;
727     }
728
729     if ( t->flags & ~T_FLAG_VISITED )
730     {
731         printf( "  %s       : ", spaces( depth ) );
732         if ( t->flags & T_FLAG_TEMP     ) printf( "TEMPORARY " );
733         if ( t->flags & T_FLAG_NOCARE   ) printf( "NOCARE "    );
734         if ( t->flags & T_FLAG_NOTFILE  ) printf( "NOTFILE "   );
735         if ( t->flags & T_FLAG_TOUCHED  ) printf( "TOUCHED "   );
736         if ( t->flags & T_FLAG_LEAVES   ) printf( "LEAVES "    );
737         if ( t->flags & T_FLAG_NOUPDATE ) printf( "NOUPDATE "  );
738         printf( "\n" );
739     }
740
741     for ( c = t->depends; c; c = c->next )
742     {
743         printf( "  %s       : Depends on %s (%s)", spaces( depth ),
744                target_name( c->target ), target_fate[ (int) c->target->fate ] );
745         if ( c->target->time == t->time )
746             printf( " (max time)");
747         printf( "\n" );
748     }
749
750     for ( c = t->depends; c; c = c->next )
751         dependGraphOutput( c->target, depth + 1 );
752 }
753 #endif
754
755
756 /*
757  * make0sort() - reorder TARGETS chain by their time (newest to oldest).
758  *
759  * We walk chain, taking each item and inserting it on the sorted result, with
760  * newest items at the front. This involves updating each of the TARGETS'
761  * c->next and c->tail. Note that we make c->tail a valid prev pointer for every
762  * entry. Normally, it is only valid at the head, where prev == tail. Note also
763  * that while tail is a loop, next ends at the end of the chain.
764  */
765
766 static TARGETS * make0sort( TARGETS * chain )
767 {
768     PROFILE_ENTER( MAKE_MAKE0SORT );
769
770     TARGETS * result = 0;
771
772     /* Walk the current target list. */
773     while ( chain )
774     {
775         TARGETS * c = chain;
776         TARGETS * s = result;
777
778         chain = chain->next;
779
780         /* Find point s in result for c. */
781         while ( s && ( s->target->time > c->target->time ) )
782             s = s->next;
783
784         /* Insert c in front of s (might be 0). Do not even think of deciphering
785          * this.
786          */
787         c->next = s;                           /* good even if s = 0       */
788         if ( result == s ) result = c;         /* new head of chain?       */
789         if ( !s ) s = result;                  /* wrap to ensure a next    */
790         if ( result != c ) s->tail->next = c;  /* not head? be prev's next */
791         c->tail = s->tail;                     /* take on next's prev      */
792         s->tail = c;                           /* make next's prev us      */
793     }
794
795     PROFILE_EXIT( MAKE_MAKE0SORT );
796     return result;
797 }
798
799
800 static LIST * targets_to_update_ = L0;
801
802
803 void mark_target_for_updating( OBJECT * target )
804 {
805     targets_to_update_ = list_push_back( targets_to_update_, object_copy( target ) );
806 }
807
808
809 LIST * targets_to_update()
810 {
811     return targets_to_update_;
812 }
813
814
815 void clear_targets_to_update()
816 {
817     list_free( targets_to_update_ );
818     targets_to_update_ = L0;
819 }