Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/tools/build/jam_src/make.c @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

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