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