• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 #include "jam.h"
33 #include "make.h"
34 
35 #include "command.h"
36 #ifdef OPT_HEADER_CACHE_EXT
37 # include "hcache.h"
38 #endif
39 #include "headers.h"
40 #include "lists.h"
41 #include "object.h"
42 #include "parse.h"
43 #include "rules.h"
44 #include "search.h"
45 #include "timestamp.h"
46 #include "variable.h"
47 #include "execcmd.h"
48 #include "output.h"
49 
50 #include <assert.h>
51 
52 #ifndef max
53 # define max(a,b) ((a)>(b)?(a):(b))
54 #endif
55 
56 static TARGETS * make0sort( TARGETS * c );
57 
58 #ifdef OPT_GRAPH_DEBUG_EXT
59     static void dependGraphOutput( TARGET * t, int depth );
60 #endif
61 
62 static char const * target_fate[] =
63 {
64     "init",     /* T_FATE_INIT     */
65     "making",   /* T_FATE_MAKING   */
66     "stable",   /* T_FATE_STABLE   */
67     "newer",    /* T_FATE_NEWER    */
68     "temp",     /* T_FATE_ISTMP    */
69     "touched",  /* T_FATE_TOUCHED  */
70     "rebuild",  /* T_FATE_REBUILD  */
71     "missing",  /* T_FATE_MISSING  */
72     "needtmp",  /* T_FATE_NEEDTMP  */
73     "old",      /* T_FATE_OUTDATED */
74     "update",   /* T_FATE_UPDATE   */
75     "nofind",   /* T_FATE_CANTFIND */
76     "nomake"    /* T_FATE_CANTMAKE */
77 };
78 
79 static char const * target_bind[] =
80 {
81     "unbound",
82     "missing",
83     "parents",
84     "exists",
85 };
86 
87 #define spaces(x) ( ((const char *)"                    ") + ( x > 20 ? 0 : 20-x ) )
88 
89 
90 /*
91  * make() - make a target, given its name.
92  */
93 
make(LIST * targets,int anyhow)94 int make( LIST * targets, int anyhow )
95 {
96     COUNTS counts[ 1 ];
97     int status = 0;  /* 1 if anything fails */
98 
99 #ifdef OPT_HEADER_CACHE_EXT
100     hcache_init();
101 #endif
102 
103     memset( (char *)counts, 0, sizeof( *counts ) );
104 
105     /* Make sure that the tables are set up correctly.
106      */
107     exec_init();
108 
109     /* First bind all targets with LOCATE_TARGET setting. This is needed to
110      * correctly handle dependencies to generated headers.
111      */
112     bind_explicitly_located_targets();
113 
114     {
115         LISTITER iter, end;
116         PROFILE_ENTER( MAKE_MAKE0 );
117         for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) )
118         {
119             TARGET * t = bindtarget( list_item( iter ) );
120             if ( t->fate == T_FATE_INIT )
121                 make0( t, 0, 0, counts, anyhow, 0 );
122         }
123         PROFILE_EXIT( MAKE_MAKE0 );
124     }
125 
126 #ifdef OPT_GRAPH_DEBUG_EXT
127     if ( DEBUG_GRAPH )
128     {
129         LISTITER iter, end;
130         for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) )
131            dependGraphOutput( bindtarget( list_item( iter ) ), 0 );
132     }
133 #endif
134 
135     if ( DEBUG_MAKE )
136     {
137         if ( counts->targets )
138             out_printf( "...found %d target%s...\n", counts->targets,
139                 counts->targets > 1 ? "s" : "" );
140         if ( counts->temp )
141             out_printf( "...using %d temp target%s...\n", counts->temp,
142                 counts->temp > 1 ? "s" : "" );
143         if ( counts->updating )
144             out_printf( "...updating %d target%s...\n", counts->updating,
145                 counts->updating > 1 ? "s" : "" );
146         if ( counts->cantfind )
147             out_printf( "...can't find %d target%s...\n", counts->cantfind,
148                 counts->cantfind > 1 ? "s" : "" );
149         if ( counts->cantmake )
150             out_printf( "...can't make %d target%s...\n", counts->cantmake,
151                 counts->cantmake > 1 ? "s" : "" );
152     }
153 
154     status = counts->cantfind || counts->cantmake;
155 
156     {
157         PROFILE_ENTER( MAKE_MAKE1 );
158         status |= make1( targets );
159         PROFILE_EXIT( MAKE_MAKE1 );
160     }
161 
162     return status;
163 }
164 
165 
166 /* Force any dependants of t that have already at least begun being visited by
167  * make0() to be updated.
168  */
169 
170 static void force_rebuilds( TARGET * t );
171 
update_dependants(TARGET * t)172 static void update_dependants( TARGET * t )
173 {
174     TARGETS * q;
175 
176     for ( q = t->dependants; q; q = q->next )
177     {
178         TARGET * p = q->target;
179         char fate0 = p->fate;
180 
181         /* If we have already at least begun visiting it and we are not already
182          * rebuilding it for other reasons.
183          */
184         if ( ( fate0 != T_FATE_INIT ) && ( fate0 < T_FATE_BUILD ) )
185         {
186             p->fate = T_FATE_UPDATE;
187 
188             if ( DEBUG_FATE )
189             {
190                 out_printf( "fate change  %s from %s to %s (as dependent of %s)\n",
191                         object_str( p->name ), target_fate[ (int) fate0 ], target_fate[ (int) p->fate ], object_str( t->name ) );
192             }
193 
194             /* If we are done visiting it, go back and make sure its dependants
195              * get rebuilt.
196              */
197             if ( fate0 > T_FATE_MAKING )
198                 update_dependants( p );
199         }
200     }
201     /* Make sure that rebuilds can be chained. */
202     force_rebuilds( t );
203 }
204 
205 
206 /*
207  * Make sure that all of t's rebuilds get rebuilt.
208  */
209 
force_rebuilds(TARGET * t)210 static void force_rebuilds( TARGET * t )
211 {
212     TARGETS * d;
213     for ( d = t->rebuilds; d; d = d->next )
214     {
215         TARGET * r = d->target;
216 
217         /* If it is not already being rebuilt for other reasons. */
218         if ( r->fate < T_FATE_BUILD )
219         {
220             if ( DEBUG_FATE )
221                 out_printf( "fate change  %s from %s to %s (by rebuild)\n",
222                         object_str( r->name ), target_fate[ (int) r->fate ], target_fate[ T_FATE_REBUILD ] );
223 
224             /* Force rebuild it. */
225             r->fate = T_FATE_REBUILD;
226 
227             /* And make sure its dependants are updated too. */
228             update_dependants( r );
229         }
230     }
231 }
232 
233 
make0rescan(TARGET * t,TARGET * rescanning)234 int make0rescan( TARGET * t, TARGET * rescanning )
235 {
236     int result = 0;
237     TARGETS * c;
238 
239     /* Check whether we have already found a cycle. */
240     if ( target_scc( t ) == rescanning )
241         return 1;
242 
243     /* If we have already visited this node, ignore it. */
244     if ( t->rescanning == rescanning )
245         return 0;
246 
247     /* If t is already updated, ignore it. */
248     if ( t->scc_root == NULL && t->progress > T_MAKE_ACTIVE )
249         return 0;
250 
251     t->rescanning = rescanning;
252     for ( c = t->depends; c; c = c->next )
253     {
254         TARGET * dependency = c->target;
255         /* Always start at the root of each new strongly connected component. */
256         if ( target_scc( dependency ) != target_scc( t ) )
257             dependency = target_scc( dependency );
258         result |= make0rescan( dependency, rescanning );
259 
260         /* Make sure that we pick up the new include node. */
261         if ( c->target->includes == rescanning )
262             result = 1;
263     }
264     if ( result && t->scc_root == NULL )
265     {
266         t->scc_root = rescanning;
267         rescanning->depends = targetentry( rescanning->depends, t );
268     }
269     return result;
270 }
271 
272 
273 /*
274  * make0() - bind and scan everything to make a TARGET.
275  *
276  * Recursively binds a target, searches for #included headers, calls itself on
277  * those headers and any dependencies.
278  */
279 
make0(TARGET * t,TARGET * p,int depth,COUNTS * counts,int anyhow,TARGET * rescanning)280 void make0
281 (
282     TARGET * t,
283     TARGET * p,       /* parent */
284     int      depth,   /* for display purposes */
285     COUNTS * counts,  /* for reporting */
286     int      anyhow,
287     TARGET * rescanning
288 )  /* forcibly touch all (real) targets */
289 {
290     TARGETS    * c;
291     TARGET     * ptime = t;
292     TARGET     * located_target = 0;
293     timestamp    last;
294     timestamp    leaf;
295     timestamp    hlast;
296     int          fate;
297     char const * flag = "";
298     SETTINGS   * s;
299 
300 #ifdef OPT_GRAPH_DEBUG_EXT
301     int savedFate;
302     int oldTimeStamp;
303 #endif
304 
305     if ( DEBUG_MAKEPROG )
306         out_printf( "make\t--\t%s%s\n", spaces( depth ), object_str( t->name ) );
307 
308     /*
309      * Step 1: Initialize.
310      */
311 
312     if ( DEBUG_MAKEPROG )
313         out_printf( "make\t--\t%s%s\n", spaces( depth ), object_str( t->name ) );
314 
315     t->fate = T_FATE_MAKING;
316     t->depth = depth;
317 
318     /*
319      * Step 2: Under the influence of "on target" variables, bind the target and
320      * search for headers.
321      */
322 
323     /* Step 2a: Set "on target" variables. */
324     s = copysettings( t->settings );
325     pushsettings( root_module(), s );
326 
327     /* Step 2b: Find and timestamp the target file (if it is a file). */
328     if ( ( t->binding == T_BIND_UNBOUND ) && !( t->flags & T_FLAG_NOTFILE ) )
329     {
330         OBJECT * another_target;
331         object_free( t->boundname );
332         t->boundname = search( t->name, &t->time, &another_target,
333             t->flags & T_FLAG_ISFILE );
334         /* If it was detected that this target refers to an already existing and
335          * bound target, we add a dependency so that every target depending on
336          * us will depend on that other target as well.
337          */
338         if ( another_target )
339             located_target = bindtarget( another_target );
340 
341         t->binding = timestamp_empty( &t->time )
342             ? T_BIND_MISSING
343             : T_BIND_EXISTS;
344     }
345 
346     /* INTERNAL, NOTFILE header nodes have the time of their parents. */
347     if ( p && ( t->flags & T_FLAG_INTERNAL ) )
348         ptime = p;
349 
350     /* If temp file does not exist but parent does, use parent. */
351     if ( p && ( t->flags & T_FLAG_TEMP ) &&
352         ( t->binding == T_BIND_MISSING ) &&
353         ( p->binding != T_BIND_MISSING ) )
354     {
355         t->binding = T_BIND_PARENTS;
356         ptime = p;
357     }
358 
359 #ifdef OPT_SEMAPHORE
360     {
361         LIST * var = var_get( root_module(), constant_JAM_SEMAPHORE );
362         if ( !list_empty( var ) )
363         {
364             TARGET * const semaphore = bindtarget( list_front( var ) );
365             semaphore->progress = T_MAKE_SEMAPHORE;
366             t->semaphore = semaphore;
367         }
368     }
369 #endif
370 
371     /* Step 2c: If its a file, search for headers. */
372     if ( t->binding == T_BIND_EXISTS )
373         headers( t );
374 
375     /* Step 2d: reset "on target" variables. */
376     popsettings( root_module(), s );
377     freesettings( s );
378 
379     /*
380      * Pause for a little progress reporting.
381      */
382 
383     if ( DEBUG_BIND )
384     {
385         if ( !object_equal( t->name, t->boundname ) )
386             out_printf( "bind\t--\t%s%s: %s\n", spaces( depth ),
387                 object_str( t->name ), object_str( t->boundname ) );
388 
389         switch ( t->binding )
390         {
391         case T_BIND_UNBOUND:
392         case T_BIND_MISSING:
393         case T_BIND_PARENTS:
394             out_printf( "time\t--\t%s%s: %s\n", spaces( depth ),
395                 object_str( t->name ), target_bind[ (int)t->binding ] );
396             break;
397 
398         case T_BIND_EXISTS:
399             out_printf( "time\t--\t%s%s: %s\n", spaces( depth ),
400                 object_str( t->name ), timestamp_str( &t->time ) );
401             break;
402         }
403     }
404 
405     /*
406      * Step 3: Recursively make0() dependencies & headers.
407      */
408 
409     /* Step 3a: Recursively make0() dependencies. */
410     for ( c = t->depends; c; c = c->next )
411     {
412         int const internal = t->flags & T_FLAG_INTERNAL;
413 
414         /* Warn about circular deps, except for includes, which include each
415          * other alot.
416          */
417         if ( c->target->fate == T_FATE_INIT )
418             make0( c->target, ptime, depth + 1, counts, anyhow, rescanning );
419         else if ( c->target->fate == T_FATE_MAKING && !internal )
420             out_printf( "warning: %s depends on itself\n", object_str(
421                 c->target->name ) );
422         else if ( c->target->fate != T_FATE_MAKING && rescanning )
423             make0rescan( c->target, rescanning );
424         if ( rescanning && c->target->includes && c->target->includes->fate !=
425             T_FATE_MAKING )
426             make0rescan( target_scc( c->target->includes ), rescanning );
427     }
428 
429     if ( located_target )
430     {
431         if ( located_target->fate == T_FATE_INIT )
432             make0( located_target, ptime, depth + 1, counts, anyhow, rescanning
433                 );
434         else if ( located_target->fate != T_FATE_MAKING && rescanning )
435             make0rescan( located_target, rescanning );
436     }
437 
438     /* Step 3b: Recursively make0() internal includes node. */
439     if ( t->includes )
440         make0( t->includes, p, depth + 1, counts, anyhow, rescanning );
441 
442     /* Step 3c: Add dependencies' includes to our direct dependencies. */
443     {
444         TARGETS * incs = 0;
445         for ( c = t->depends; c; c = c->next )
446             if ( c->target->includes )
447                 incs = targetentry( incs, c->target->includes );
448         t->depends = targetchain( t->depends, incs );
449     }
450 
451     if ( located_target )
452         t->depends = targetentry( t->depends, located_target );
453 
454     /* Step 3d: Detect cycles. */
455     {
456         int cycle_depth = depth;
457         for ( c = t->depends; c; c = c->next )
458         {
459             TARGET * scc_root = target_scc( c->target );
460             if ( scc_root->fate == T_FATE_MAKING &&
461                 ( !scc_root->includes ||
462                   scc_root->includes->fate != T_FATE_MAKING ) )
463             {
464                 if ( scc_root->depth < cycle_depth )
465                 {
466                     cycle_depth = scc_root->depth;
467                     t->scc_root = scc_root;
468                 }
469             }
470         }
471     }
472 
473     /*
474      * Step 4: Compute time & fate.
475      */
476 
477     /* Step 4a: Pick up dependencies' time and fate. */
478     timestamp_clear( &last );
479     timestamp_clear( &leaf );
480     fate = T_FATE_STABLE;
481     for ( c = t->depends; c; c = c->next )
482     {
483         /* If we are in a different strongly connected component, pull
484          * timestamps from the root.
485          */
486         if ( c->target->scc_root )
487         {
488             TARGET * const scc_root = target_scc( c->target );
489             if ( scc_root != t->scc_root )
490             {
491                 timestamp_max( &c->target->leaf, &c->target->leaf,
492                     &scc_root->leaf );
493                 timestamp_max( &c->target->time, &c->target->time,
494                     &scc_root->time );
495                 c->target->fate = max( c->target->fate, scc_root->fate );
496             }
497         }
498 
499         /* If LEAVES has been applied, we only heed the timestamps of the leaf
500          * source nodes.
501          */
502         timestamp_max( &leaf, &leaf, &c->target->leaf );
503         if ( t->flags & T_FLAG_LEAVES )
504         {
505             timestamp_copy( &last, &leaf );
506             continue;
507         }
508         timestamp_max( &last, &last, &c->target->time );
509         fate = max( fate, c->target->fate );
510 
511 #ifdef OPT_GRAPH_DEBUG_EXT
512         if ( DEBUG_FATE )
513             if ( fate < c->target->fate )
514                 out_printf( "fate change %s from %s to %s by dependency %s\n",
515                     object_str( t->name ), target_fate[ (int)fate ],
516                     target_fate[ (int)c->target->fate ], object_str(
517                     c->target->name ) );
518 #endif
519     }
520 
521     /* Step 4b: Pick up included headers time. */
522 
523     /*
524      * If a header is newer than a temp source that includes it, the temp source
525      * will need building.
526      */
527     if ( t->includes )
528         timestamp_copy( &hlast, &t->includes->time );
529     else
530         timestamp_clear( &hlast );
531 
532     /* Step 4c: handle NOUPDATE oddity.
533      *
534      * If a NOUPDATE file exists, mark it as having eternally old dependencies.
535      * Do not inherit our fate from our dependencies. Decide fate based only on
536      * other flags and our binding (done later).
537      */
538     if ( t->flags & T_FLAG_NOUPDATE )
539     {
540 #ifdef OPT_GRAPH_DEBUG_EXT
541         if ( DEBUG_FATE )
542             if ( fate != T_FATE_STABLE )
543                 out_printf( "fate change  %s back to stable, NOUPDATE.\n",
544                     object_str( t->name ) );
545 #endif
546 
547         timestamp_clear( &last );
548         timestamp_clear( &t->time );
549 
550         /* Do not inherit our fate from our dependencies. Decide fate based only
551          * upon other flags and our binding (done later).
552          */
553         fate = T_FATE_STABLE;
554     }
555 
556     /* Step 4d: Determine fate: rebuild target or what? */
557 
558     /*
559         In English:
560         If can not find or make child, can not make target.
561         If children changed, make target.
562         If target missing, make it.
563         If children newer, make target.
564         If temp's children newer than parent, make temp.
565         If temp's headers newer than parent, make temp.
566         If deliberately touched, make it.
567         If up-to-date temp file present, use it.
568         If target newer than non-notfile parent, mark target newer.
569         Otherwise, stable!
570 
571         Note this block runs from least to most stable: as we make it further
572         down the list, the target's fate gets more stable.
573     */
574 
575 #ifdef OPT_GRAPH_DEBUG_EXT
576     savedFate = fate;
577     oldTimeStamp = 0;
578 #endif
579 
580     if ( fate >= T_FATE_BROKEN )
581     {
582         fate = T_FATE_CANTMAKE;
583     }
584     else if ( fate >= T_FATE_SPOIL )
585     {
586         fate = T_FATE_UPDATE;
587     }
588     else if ( t->binding == T_BIND_MISSING )
589     {
590         fate = T_FATE_MISSING;
591     }
592     else if ( t->binding == T_BIND_EXISTS && timestamp_cmp( &last, &t->time ) >
593         0 )
594     {
595 #ifdef OPT_GRAPH_DEBUG_EXT
596         oldTimeStamp = 1;
597 #endif
598         fate = T_FATE_OUTDATED;
599     }
600     else if ( t->binding == T_BIND_PARENTS && timestamp_cmp( &last, &p->time ) >
601         0 )
602     {
603 #ifdef OPT_GRAPH_DEBUG_EXT
604         oldTimeStamp = 1;
605 #endif
606         fate = T_FATE_NEEDTMP;
607     }
608     else if ( t->binding == T_BIND_PARENTS && timestamp_cmp( &hlast, &p->time )
609         > 0 )
610     {
611         fate = T_FATE_NEEDTMP;
612     }
613     else if ( t->flags & T_FLAG_TOUCHED )
614     {
615         fate = T_FATE_TOUCHED;
616     }
617     else if ( anyhow && !( t->flags & T_FLAG_NOUPDATE ) )
618     {
619         fate = T_FATE_TOUCHED;
620     }
621     else if ( t->binding == T_BIND_EXISTS && ( t->flags & T_FLAG_TEMP ) )
622     {
623         fate = T_FATE_ISTMP;
624     }
625     else if ( t->binding == T_BIND_EXISTS && p && p->binding != T_BIND_UNBOUND
626         && timestamp_cmp( &t->time, &p->time ) > 0 )
627     {
628 #ifdef OPT_GRAPH_DEBUG_EXT
629         oldTimeStamp = 1;
630 #endif
631         fate = T_FATE_NEWER;
632     }
633     else
634     {
635         fate = T_FATE_STABLE;
636     }
637 #ifdef OPT_GRAPH_DEBUG_EXT
638     if ( DEBUG_FATE && ( fate != savedFate ) )
639 	{
640         if ( savedFate == T_FATE_STABLE )
641             out_printf( "fate change  %s set to %s%s\n", object_str( t->name ),
642                 target_fate[ fate ], oldTimeStamp ? " (by timestamp)" : "" );
643         else
644             out_printf( "fate change  %s from %s to %s%s\n", object_str( t->name ),
645                 target_fate[ savedFate ], target_fate[ fate ], oldTimeStamp ?
646                 " (by timestamp)" : "" );
647 	}
648 #endif
649 
650     /* Step 4e: Handle missing files. */
651     /* If it is missing and there are no actions to create it, boom. */
652     /* If we can not make a target we do not care about it, okay. */
653     /* We could insist that there are updating actions for all missing */
654     /* files, but if they have dependencies we just pretend it is a NOTFILE. */
655 
656     if ( ( fate == T_FATE_MISSING ) && !t->actions && !t->depends )
657     {
658         if ( t->flags & T_FLAG_NOCARE )
659         {
660 #ifdef OPT_GRAPH_DEBUG_EXT
661             if ( DEBUG_FATE )
662                 out_printf( "fate change %s to STABLE from %s, "
663                     "no actions, no dependencies and do not care\n",
664                     object_str( t->name ), target_fate[ fate ] );
665 #endif
666             fate = T_FATE_STABLE;
667         }
668         else
669         {
670             out_printf( "don't know how to make %s\n", object_str( t->name ) );
671             fate = T_FATE_CANTFIND;
672         }
673     }
674 
675     /* Step 4f: Propagate dependencies' time & fate. */
676     /* Set leaf time to be our time only if this is a leaf. */
677 
678     timestamp_max( &t->time, &t->time, &last );
679     timestamp_copy( &t->leaf, timestamp_empty( &leaf ) ? &t->time : &leaf );
680     /* This target's fate may have been updated by virtue of following some
681      * target's rebuilds list, so only allow it to be increased to the fate we
682      * have calculated. Otherwise, grab its new fate.
683      */
684     if ( fate > t->fate )
685         t->fate = fate;
686     else
687         fate = t->fate;
688 
689     /*
690      * Step 4g: If this target needs to be built, make0 all targets
691      * that are updated by the same actions used to update this target.
692      * These have already been marked as REBUILDS, and make1 has
693      * special handling for them.  We just need to make sure that
694      * they get make0ed.
695      */
696     if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )
697     {
698         ACTIONS * a;
699         TARGETS * c;
700         for ( a = t->actions; a; a = a->next )
701         {
702             for ( c = a->action->targets; c; c = c->next )
703             {
704                 if ( c->target->fate == T_FATE_INIT )
705                 {
706                     make0( c->target, ptime, depth + 1, counts, anyhow, rescanning );
707                 }
708             }
709         }
710     }
711 
712     /* Step 4h: If this target needs to be built, force rebuild everything in
713      * its rebuilds list.
714      */
715     if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) )
716         force_rebuilds( t );
717 
718     /*
719      * Step 5: Sort dependencies by their update time.
720      */
721 
722     if ( globs.newestfirst )
723         t->depends = make0sort( t->depends );
724 
725     /*
726      * Step 6: A little harmless tabulating for tracing purposes.
727      */
728 
729     /* Do not count or report internal includes nodes. */
730     if ( t->flags & T_FLAG_INTERNAL )
731         return;
732 
733     if ( counts )
734     {
735 #ifdef OPT_IMPROVED_PATIENCE_EXT
736         ++counts->targets;
737 #else
738         if ( !( ++counts->targets % 1000 ) && DEBUG_MAKE )
739         {
740             out_printf( "...patience...\n" );
741             out_flush();
742         }
743 #endif
744 
745         if ( fate == T_FATE_ISTMP )
746             ++counts->temp;
747         else if ( fate == T_FATE_CANTFIND )
748             ++counts->cantfind;
749         else if ( ( fate == T_FATE_CANTMAKE ) && t->actions )
750             ++counts->cantmake;
751         else if ( ( fate >= T_FATE_BUILD ) && ( fate < T_FATE_BROKEN ) &&
752             t->actions )
753             ++counts->updating;
754     }
755 
756     if ( !( t->flags & T_FLAG_NOTFILE ) && ( fate >= T_FATE_SPOIL ) )
757         flag = "+";
758     else if ( t->binding == T_BIND_EXISTS && p && timestamp_cmp( &t->time,
759         &p->time ) > 0 )
760         flag = "*";
761 
762     if ( DEBUG_MAKEPROG )
763         out_printf( "made%s\t%s\t%s%s\n", flag, target_fate[ (int)t->fate ],
764             spaces( depth ), object_str( t->name ) );
765 }
766 
767 
768 #ifdef OPT_GRAPH_DEBUG_EXT
769 
target_name(TARGET * t)770 static char const * target_name( TARGET * t )
771 {
772     static char buf[ 1000 ];
773     if ( t->flags & T_FLAG_INTERNAL )
774     {
775         sprintf( buf, "%s (internal node)", object_str( t->name ) );
776         return buf;
777     }
778     return object_str( t->name );
779 }
780 
781 
782 /*
783  * dependGraphOutput() - output the DG after make0 has run.
784  */
785 
dependGraphOutput(TARGET * t,int depth)786 static void dependGraphOutput( TARGET * t, int depth )
787 {
788     TARGETS * c;
789 
790     if ( ( t->flags & T_FLAG_VISITED ) || !t->name || !t->boundname )
791         return;
792 
793     t->flags |= T_FLAG_VISITED;
794 
795     switch ( t->fate )
796     {
797         case T_FATE_TOUCHED:
798         case T_FATE_MISSING:
799         case T_FATE_OUTDATED:
800         case T_FATE_UPDATE:
801             out_printf( "->%s%2d Name: %s\n", spaces( depth ), depth, target_name( t
802                 ) );
803             break;
804         default:
805             out_printf( "  %s%2d Name: %s\n", spaces( depth ), depth, target_name( t
806                 ) );
807             break;
808     }
809 
810     if ( !object_equal( t->name, t->boundname ) )
811         out_printf( "  %s    Loc: %s\n", spaces( depth ), object_str( t->boundname )
812             );
813 
814     switch ( t->fate )
815     {
816     case T_FATE_STABLE:
817         out_printf( "  %s       : Stable\n", spaces( depth ) );
818         break;
819     case T_FATE_NEWER:
820         out_printf( "  %s       : Newer\n", spaces( depth ) );
821         break;
822     case T_FATE_ISTMP:
823         out_printf( "  %s       : Up to date temp file\n", spaces( depth ) );
824         break;
825     case T_FATE_NEEDTMP:
826         out_printf( "  %s       : Temporary file, to be updated\n", spaces( depth )
827             );
828         break;
829     case T_FATE_TOUCHED:
830         out_printf( "  %s       : Been touched, updating it\n", spaces( depth ) );
831         break;
832     case T_FATE_MISSING:
833         out_printf( "  %s       : Missing, creating it\n", spaces( depth ) );
834         break;
835     case T_FATE_OUTDATED:
836         out_printf( "  %s       : Outdated, updating it\n", spaces( depth ) );
837         break;
838     case T_FATE_REBUILD:
839         out_printf( "  %s       : Rebuild, updating it\n", spaces( depth ) );
840         break;
841     case T_FATE_UPDATE:
842         out_printf( "  %s       : Updating it\n", spaces( depth ) );
843         break;
844     case T_FATE_CANTFIND:
845         out_printf( "  %s       : Can not find it\n", spaces( depth ) );
846         break;
847     case T_FATE_CANTMAKE:
848         out_printf( "  %s       : Can make it\n", spaces( depth ) );
849         break;
850     }
851 
852     if ( t->flags & ~T_FLAG_VISITED )
853     {
854         out_printf( "  %s       : ", spaces( depth ) );
855         if ( t->flags & T_FLAG_TEMP     ) out_printf( "TEMPORARY " );
856         if ( t->flags & T_FLAG_NOCARE   ) out_printf( "NOCARE "    );
857         if ( t->flags & T_FLAG_NOTFILE  ) out_printf( "NOTFILE "   );
858         if ( t->flags & T_FLAG_TOUCHED  ) out_printf( "TOUCHED "   );
859         if ( t->flags & T_FLAG_LEAVES   ) out_printf( "LEAVES "    );
860         if ( t->flags & T_FLAG_NOUPDATE ) out_printf( "NOUPDATE "  );
861         out_printf( "\n" );
862     }
863 
864     for ( c = t->depends; c; c = c->next )
865     {
866         out_printf( "  %s       : Depends on %s (%s)", spaces( depth ),
867            target_name( c->target ), target_fate[ (int)c->target->fate ] );
868         if ( !timestamp_cmp( &c->target->time, &t->time ) )
869             out_printf( " (max time)");
870         out_printf( "\n" );
871     }
872 
873     for ( c = t->depends; c; c = c->next )
874         dependGraphOutput( c->target, depth + 1 );
875 }
876 #endif
877 
878 
879 /*
880  * make0sort() - reorder TARGETS chain by their time (newest to oldest).
881  *
882  * We walk chain, taking each item and inserting it on the sorted result, with
883  * newest items at the front. This involves updating each of the TARGETS'
884  * c->next and c->tail. Note that we make c->tail a valid prev pointer for every
885  * entry. Normally, it is only valid at the head, where prev == tail. Note also
886  * that while tail is a loop, next ends at the end of the chain.
887  */
888 
make0sort(TARGETS * chain)889 static TARGETS * make0sort( TARGETS * chain )
890 {
891     PROFILE_ENTER( MAKE_MAKE0SORT );
892 
893     TARGETS * result = 0;
894 
895     /* Walk the current target list. */
896     while ( chain )
897     {
898         TARGETS * c = chain;
899         TARGETS * s = result;
900 
901         chain = chain->next;
902 
903         /* Find point s in result for c. */
904         while ( s && timestamp_cmp( &s->target->time, &c->target->time ) > 0 )
905             s = s->next;
906 
907         /* Insert c in front of s (might be 0). */
908         c->next = s;                           /* good even if s = 0       */
909         if ( result == s ) result = c;         /* new head of chain?       */
910         if ( !s ) s = result;                  /* wrap to ensure a next    */
911         if ( result != c ) s->tail->next = c;  /* not head? be prev's next */
912         c->tail = s->tail;                     /* take on next's prev      */
913         s->tail = c;                           /* make next's prev us      */
914     }
915 
916     PROFILE_EXIT( MAKE_MAKE0SORT );
917     return result;
918 }
919 
920 
921 static LIST * targets_to_update_ = L0;
922 
923 
mark_target_for_updating(OBJECT * target)924 void mark_target_for_updating( OBJECT * target )
925 {
926     targets_to_update_ = list_push_back( targets_to_update_, object_copy(
927         target ) );
928 }
929 
930 
targets_to_update()931 LIST * targets_to_update()
932 {
933     return targets_to_update_;
934 }
935 
936 
clear_targets_to_update()937 void clear_targets_to_update()
938 {
939     list_free( targets_to_update_ );
940     targets_to_update_ = L0;
941 }
942