]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/build/src/engine/make.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / tools / build / src / engine / make.cpp
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
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
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
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
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
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
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
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
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
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
931 LIST * targets_to_update()
932 {
933 return targets_to_update_;
934 }
935
936
937 void clear_targets_to_update()
938 {
939 list_free( targets_to_update_ );
940 targets_to_update_ = L0;
941 }