]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc. | |
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 | * make1.c - execute commands to bring targets up to date | |
15 | * | |
16 | * This module contains make1(), the entry point called by make() to recursively | |
17 | * descend the dependency graph executing update actions as marked by make0(). | |
18 | * | |
19 | * External routines: | |
20 | * make1() - execute commands to update a TARGET and all of its dependencies | |
21 | * | |
22 | * Internal routines, the recursive/asynchronous command executors: | |
23 | * make1a() - recursively schedules dependency builds and then goes to | |
24 | * MAKE1B | |
25 | * make1b() - if nothing is blocking this target's build, proceed to | |
26 | * MAKE1C | |
27 | * make1c() - launch target's next command, or go to parents' MAKE1B | |
28 | * if none | |
29 | * make1c_closure() - handle command execution completion and go to MAKE1C | |
30 | * | |
31 | * Internal support routines: | |
32 | * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc. | |
33 | * make1list() - turn a list of targets into a LIST, for $(<) and $(>) | |
34 | * make1settings() - for vars with bound values, build up replacement lists | |
35 | * make1bind() - bind targets that weren't bound in dependency analysis | |
36 | */ | |
37 | ||
38 | #include "jam.h" | |
39 | #include "make.h" | |
40 | ||
41 | #include "command.h" | |
42 | #include "compile.h" | |
43 | #include "execcmd.h" | |
44 | #include "headers.h" | |
45 | #include "lists.h" | |
46 | #include "object.h" | |
47 | #include "output.h" | |
48 | #include "parse.h" | |
49 | #include "rules.h" | |
50 | #include "search.h" | |
51 | #include "variable.h" | |
52 | #include "output.h" | |
53 | ||
54 | #include <assert.h> | |
55 | #include <stdlib.h> | |
56 | ||
57 | #if !defined( NT ) || defined( __GNUC__ ) | |
58 | #include <unistd.h> /* for unlink */ | |
59 | #endif | |
60 | ||
61 | static CMD * make1cmds ( TARGET * ); | |
62 | static LIST * make1list ( LIST *, TARGETS *, int flags ); | |
63 | static SETTINGS * make1settings ( struct module_t *, LIST * vars ); | |
64 | static void make1bind ( TARGET * ); | |
7c673cae FG |
65 | static void push_cmds( CMDLIST * cmds, int status ); |
66 | static int cmd_sem_lock( TARGET * t ); | |
67 | static void cmd_sem_unlock( TARGET * t ); | |
68 | ||
69 | static int targets_contains( TARGETS * l, TARGET * t ); | |
70 | static int targets_equal( TARGETS * l1, TARGETS * l2 ); | |
71 | ||
72 | /* Ugly static - it is too hard to carry it through the callbacks. */ | |
73 | ||
74 | static struct | |
75 | { | |
76 | int failed; | |
77 | int skipped; | |
78 | int total; | |
79 | int made; | |
80 | } counts[ 1 ]; | |
81 | ||
82 | /* Target state. */ | |
83 | #define T_STATE_MAKE1A 0 /* make1a() should be called */ | |
84 | #define T_STATE_MAKE1B 1 /* make1b() should be called */ | |
85 | #define T_STATE_MAKE1C 2 /* make1c() should be called */ | |
86 | ||
87 | typedef struct _state state; | |
88 | struct _state | |
89 | { | |
90 | state * prev; /* previous state on stack */ | |
91 | TARGET * t; /* current target */ | |
92 | TARGET * parent; /* parent argument necessary for MAKE1A */ | |
93 | int curstate; /* current state */ | |
94 | }; | |
95 | ||
96 | static void make1a( state * const ); | |
97 | static void make1b( state * const ); | |
98 | static void make1c( state const * const ); | |
99 | ||
100 | static void make1c_closure( void * const closure, int status, | |
101 | timing_info const * const, char const * const cmd_stdout, | |
102 | char const * const cmd_stderr, int const cmd_exit_reason ); | |
103 | ||
104 | typedef struct _stack | |
105 | { | |
106 | state * stack; | |
107 | } stack; | |
108 | ||
109 | static stack state_stack = { NULL }; | |
110 | ||
111 | static state * state_freelist = NULL; | |
112 | ||
113 | /* Currently running command counter. */ | |
114 | static int cmdsrunning; | |
115 | ||
116 | ||
117 | static state * alloc_state() | |
118 | { | |
119 | if ( state_freelist ) | |
120 | { | |
121 | state * const pState = state_freelist; | |
122 | state_freelist = pState->prev; | |
123 | memset( pState, 0, sizeof( state ) ); | |
124 | return pState; | |
125 | } | |
126 | return (state *)BJAM_MALLOC( sizeof( state ) ); | |
127 | } | |
128 | ||
129 | ||
130 | static void free_state( state * const pState ) | |
131 | { | |
132 | pState->prev = state_freelist; | |
133 | state_freelist = pState; | |
134 | } | |
135 | ||
136 | ||
137 | static void clear_state_freelist() | |
138 | { | |
139 | while ( state_freelist ) | |
140 | { | |
141 | state * const pState = state_freelist; | |
142 | state_freelist = state_freelist->prev; | |
143 | BJAM_FREE( pState ); | |
144 | } | |
145 | } | |
146 | ||
147 | ||
148 | static state * current_state( stack * const pStack ) | |
149 | { | |
150 | return pStack->stack; | |
151 | } | |
152 | ||
153 | ||
154 | static void pop_state( stack * const pStack ) | |
155 | { | |
156 | if ( pStack->stack ) | |
157 | { | |
158 | state * const pState = pStack->stack->prev; | |
159 | free_state( pStack->stack ); | |
160 | pStack->stack = pState; | |
161 | } | |
162 | } | |
163 | ||
164 | ||
165 | static state * push_state( stack * const pStack, TARGET * const t, | |
166 | TARGET * const parent, int const curstate ) | |
167 | { | |
168 | state * const pState = alloc_state(); | |
169 | pState->t = t; | |
170 | pState->parent = parent; | |
171 | pState->prev = pStack->stack; | |
172 | pState->curstate = curstate; | |
173 | return pStack->stack = pState; | |
174 | } | |
175 | ||
176 | ||
177 | /* | |
178 | * Pushes a stack onto another stack, effectively reversing the order. | |
179 | */ | |
180 | ||
181 | static void push_stack_on_stack( stack * const pDest, stack * const pSrc ) | |
182 | { | |
183 | while ( pSrc->stack ) | |
184 | { | |
185 | state * const pState = pSrc->stack; | |
186 | pSrc->stack = pState->prev; | |
187 | pState->prev = pDest->stack; | |
188 | pDest->stack = pState; | |
189 | } | |
190 | } | |
191 | ||
192 | ||
193 | /* | |
194 | * make1() - execute commands to update a list of targets and all of their dependencies | |
195 | */ | |
196 | ||
197 | static int intr = 0; | |
198 | static int quit = 0; | |
199 | ||
200 | int make1( LIST * targets ) | |
201 | { | |
202 | state * pState; | |
203 | int status = 0; | |
204 | ||
205 | memset( (char *)counts, 0, sizeof( *counts ) ); | |
f67539c2 | 206 | |
7c673cae FG |
207 | { |
208 | LISTITER iter, end; | |
209 | stack temp_stack = { NULL }; | |
210 | for ( iter = list_begin( targets ), end = list_end( targets ); | |
211 | iter != end; iter = list_next( iter ) ) | |
212 | push_state( &temp_stack, bindtarget( list_item( iter ) ), NULL, T_STATE_MAKE1A ); | |
213 | push_stack_on_stack( &state_stack, &temp_stack ); | |
214 | } | |
215 | ||
216 | /* Clear any state left over from the past */ | |
217 | quit = 0; | |
218 | ||
219 | /* Recursively make the target and its dependencies. */ | |
220 | ||
221 | while ( 1 ) | |
222 | { | |
223 | while ( ( pState = current_state( &state_stack ) ) ) | |
224 | { | |
225 | if ( quit ) | |
226 | pop_state( &state_stack ); | |
227 | ||
228 | switch ( pState->curstate ) | |
229 | { | |
230 | case T_STATE_MAKE1A: make1a( pState ); break; | |
231 | case T_STATE_MAKE1B: make1b( pState ); break; | |
232 | case T_STATE_MAKE1C: make1c( pState ); break; | |
233 | default: | |
234 | assert( !"make1(): Invalid state detected." ); | |
235 | } | |
236 | } | |
237 | if ( !cmdsrunning ) | |
238 | break; | |
239 | /* Wait for outstanding commands to finish running. */ | |
240 | exec_wait(); | |
241 | } | |
242 | ||
243 | clear_state_freelist(); | |
244 | ||
245 | /* Talk about it. */ | |
246 | if ( counts->failed ) | |
247 | out_printf( "...failed updating %d target%s...\n", counts->failed, | |
248 | counts->failed > 1 ? "s" : "" ); | |
249 | if ( DEBUG_MAKE && counts->skipped ) | |
250 | out_printf( "...skipped %d target%s...\n", counts->skipped, | |
251 | counts->skipped > 1 ? "s" : "" ); | |
252 | if ( DEBUG_MAKE && counts->made ) | |
253 | out_printf( "...updated %d target%s...\n", counts->made, | |
254 | counts->made > 1 ? "s" : "" ); | |
255 | ||
256 | /* If we were interrupted, exit now that all child processes | |
257 | have finished. */ | |
258 | if ( intr ) | |
259 | exit( EXITBAD ); | |
260 | ||
261 | { | |
262 | LISTITER iter, end; | |
263 | for ( iter = list_begin( targets ), end = list_end( targets ); | |
264 | iter != end; iter = list_next( iter ) ) | |
265 | { | |
266 | /* Check that the target was updated and that the | |
267 | update succeeded. */ | |
268 | TARGET * t = bindtarget( list_item( iter ) ); | |
269 | if (t->progress == T_MAKE_DONE) | |
270 | { | |
271 | if (t->status != EXEC_CMD_OK) | |
272 | status = 1; | |
273 | } | |
274 | else if ( ! ( t->progress == T_MAKE_NOEXEC_DONE && globs.noexec ) ) | |
275 | { | |
276 | status = 1; | |
277 | } | |
278 | } | |
279 | } | |
280 | return status; | |
281 | } | |
282 | ||
283 | ||
284 | /* | |
285 | * make1a() - recursively schedules dependency builds and then goes to MAKE1B | |
286 | * | |
287 | * Called to start processing a specified target. Does nothing if the target is | |
288 | * already being processed or otherwise starts processing all of its | |
289 | * dependencies. | |
290 | */ | |
291 | ||
292 | static void make1a( state * const pState ) | |
293 | { | |
294 | TARGET * t = pState->t; | |
295 | TARGET * const scc_root = target_scc( t ); | |
296 | ||
297 | if ( !pState->parent || target_scc( pState->parent ) != scc_root ) | |
298 | pState->t = t = scc_root; | |
299 | ||
300 | /* If the parent is the first to try to build this target or this target is | |
301 | * in the MAKE1C quagmire, arrange for the parent to be notified when this | |
302 | * target has been built. | |
303 | */ | |
304 | if ( pState->parent && t->progress <= T_MAKE_RUNNING ) | |
305 | { | |
306 | TARGET * const parent_scc = target_scc( pState->parent ); | |
307 | if ( t != parent_scc ) | |
308 | { | |
309 | t->parents = targetentry( t->parents, parent_scc ); | |
310 | ++parent_scc->asynccnt; | |
311 | } | |
312 | } | |
313 | ||
314 | /* If the target has been previously updated with -n in effect, and we are | |
315 | * now ignoring -n, update it for real. E.g. if the UPDATE_NOW rule was | |
316 | * called for it twice - first with the -n option and then without. | |
317 | */ | |
318 | if ( !globs.noexec && t->progress == T_MAKE_NOEXEC_DONE ) | |
319 | t->progress = T_MAKE_INIT; | |
320 | ||
321 | /* If this target is already being processed then do nothing. There is no | |
322 | * need to start processing the same target all over again. | |
323 | */ | |
324 | if ( t->progress != T_MAKE_INIT ) | |
325 | { | |
326 | pop_state( &state_stack ); | |
327 | return; | |
328 | } | |
329 | ||
330 | /* Guard against circular dependencies. */ | |
331 | t->progress = T_MAKE_ONSTACK; | |
332 | ||
333 | /* 'asynccnt' counts the dependencies preventing this target from proceeding | |
334 | * to MAKE1C for actual building. We start off with a count of 1 to prevent | |
335 | * anything from happening until we can notify all dependencies that they | |
336 | * are needed. This 1 is then accounted for when we enter MAKE1B ourselves, | |
337 | * below. Without this if a dependency gets built before we finish | |
92f5a8d4 | 338 | * processing all of our other dependencies our build might be triggered |
7c673cae FG |
339 | * prematurely. |
340 | */ | |
341 | t->asynccnt = 1; | |
342 | ||
343 | /* Push dependency build requests (to be executed in the natural order). */ | |
344 | { | |
345 | stack temp_stack = { NULL }; | |
346 | TARGETS * c; | |
347 | for ( c = t->depends; c && !quit; c = c->next ) | |
348 | push_state( &temp_stack, c->target, t, T_STATE_MAKE1A ); | |
349 | push_stack_on_stack( &state_stack, &temp_stack ); | |
350 | } | |
351 | ||
352 | t->progress = T_MAKE_ACTIVE; | |
353 | ||
354 | /* Once all of our dependencies have started getting processed we can move | |
355 | * onto MAKE1B. | |
356 | */ | |
357 | /* Implementation note: | |
358 | * In theory this would be done by popping this state before pushing | |
359 | * dependency target build requests but as a slight optimization we simply | |
360 | * modify our current state and leave it on the stack instead. | |
361 | */ | |
362 | pState->curstate = T_STATE_MAKE1B; | |
363 | } | |
364 | ||
365 | ||
366 | /* | |
367 | * make1b() - if nothing is blocking this target's build, proceed to MAKE1C | |
368 | * | |
369 | * Called after something stops blocking this target's build, e.g. that all of | |
370 | * its dependencies have started being processed, one of its dependencies has | |
371 | * been built or a semaphore this target has been waiting for is free again. | |
372 | */ | |
373 | ||
374 | static void make1b( state * const pState ) | |
375 | { | |
376 | TARGET * const t = pState->t; | |
377 | TARGET * failed = 0; | |
378 | char const * failed_name = "dependencies"; | |
379 | ||
380 | pop_state( &state_stack ); | |
381 | ||
382 | /* If any dependencies are still outstanding, wait until they signal their | |
383 | * completion by pushing this same state for their parent targets. | |
384 | */ | |
385 | if ( --t->asynccnt ) | |
386 | { | |
387 | return; | |
388 | } | |
389 | ||
390 | /* Now ready to build target 't', if dependencies built OK. */ | |
391 | ||
392 | /* Collect status from dependencies. If -n was passed then act as though all | |
393 | * dependencies built correctly (the only way they can fail is if UPDATE_NOW | |
394 | * was called). If the dependencies can not be found or we got an interrupt, | |
395 | * we can not get here. | |
396 | */ | |
397 | if ( !globs.noexec ) | |
398 | { | |
399 | TARGETS * c; | |
400 | for ( c = t->depends; c; c = c->next ) | |
401 | if ( c->target->status > t->status && !( c->target->flags & | |
402 | T_FLAG_NOCARE ) ) | |
403 | { | |
404 | failed = c->target; | |
405 | t->status = c->target->status; | |
406 | } | |
407 | } | |
408 | ||
409 | /* If an internal header node failed to build, we want to output the target | |
410 | * that it failed on. | |
411 | */ | |
412 | if ( failed ) | |
413 | failed_name = failed->flags & T_FLAG_INTERNAL | |
414 | ? failed->failed | |
415 | : object_str( failed->name ); | |
416 | t->failed = failed_name; | |
417 | ||
418 | /* If actions for building any of the dependencies have failed, bail. | |
419 | * Otherwise, execute all actions to make the current target. | |
420 | */ | |
421 | if ( ( t->status == EXEC_CMD_FAIL ) && t->actions ) | |
422 | { | |
423 | ++counts->skipped; | |
424 | if ( ( t->flags & ( T_FLAG_RMOLD | T_FLAG_NOTFILE ) ) == T_FLAG_RMOLD ) | |
425 | { | |
426 | if ( !unlink( object_str( t->boundname ) ) ) | |
427 | out_printf( "...removing outdated %s\n", object_str( t->boundname ) | |
428 | ); | |
429 | } | |
430 | else | |
431 | out_printf( "...skipped %s for lack of %s...\n", object_str( t->name ), | |
432 | failed_name ); | |
433 | } | |
434 | ||
435 | if ( t->status == EXEC_CMD_OK ) | |
436 | switch ( t->fate ) | |
437 | { | |
438 | case T_FATE_STABLE: | |
439 | case T_FATE_NEWER: | |
440 | break; | |
441 | ||
442 | case T_FATE_CANTFIND: | |
443 | case T_FATE_CANTMAKE: | |
444 | t->status = EXEC_CMD_FAIL; | |
445 | break; | |
446 | ||
447 | case T_FATE_ISTMP: | |
448 | if ( DEBUG_MAKE ) | |
449 | out_printf( "...using %s...\n", object_str( t->name ) ); | |
450 | break; | |
451 | ||
452 | case T_FATE_TOUCHED: | |
453 | case T_FATE_MISSING: | |
454 | case T_FATE_NEEDTMP: | |
455 | case T_FATE_OUTDATED: | |
456 | case T_FATE_UPDATE: | |
457 | case T_FATE_REBUILD: | |
458 | /* Prepare commands for executing actions scheduled for this target. | |
459 | * Commands have their embedded variables automatically expanded, | |
460 | * including making use of any "on target" variables. | |
461 | */ | |
462 | if ( t->actions ) | |
463 | { | |
464 | ++counts->total; | |
465 | if ( DEBUG_MAKE && !( counts->total % 100 ) ) | |
466 | out_printf( "...on %dth target...\n", counts->total ); | |
467 | ||
468 | t->cmds = (char *)make1cmds( t ); | |
469 | /* Update the target's "progress" so MAKE1C processing counts it | |
470 | * among its successes/failures. | |
471 | */ | |
472 | t->progress = T_MAKE_RUNNING; | |
473 | } | |
474 | break; | |
475 | ||
476 | /* All valid fates should have been accounted for by now. */ | |
477 | default: | |
478 | err_printf( "ERROR: %s has bad fate %d", object_str( t->name ), | |
479 | t->fate ); | |
480 | abort(); | |
481 | } | |
482 | ||
483 | /* Proceed to MAKE1C to begin executing the chain of commands prepared for | |
484 | * building the target. If we are not going to build the target (e.g. due to | |
485 | * dependency failures or no commands needing to be run) the chain will be | |
486 | * empty and MAKE1C processing will directly signal the target's completion. | |
487 | */ | |
488 | ||
489 | if ( t->cmds == NULL || --( ( CMD * )t->cmds )->asynccnt == 0 ) | |
490 | push_state( &state_stack, t, NULL, T_STATE_MAKE1C ); | |
491 | else if ( DEBUG_EXECCMD ) | |
492 | { | |
493 | CMD * cmd = ( CMD * )t->cmds; | |
494 | out_printf( "Delaying %s %s: %d targets not ready\n", object_str( cmd->rule->name ), object_str( t->boundname ), cmd->asynccnt ); | |
495 | } | |
496 | } | |
497 | ||
498 | ||
499 | /* | |
500 | * make1c() - launch target's next command, or go to parents' MAKE1B if none | |
501 | * | |
502 | * If there are (more) commands to run to build this target (and we have not hit | |
503 | * an error running earlier comands) we launch the command using exec_cmd(). | |
504 | * Command execution signals its completion in exec_wait() by calling our | |
505 | * make1c_closure() callback. | |
506 | * | |
507 | * If there are no more commands to run, we collect the status from all the | |
508 | * actions and report our completion to all the parents. | |
509 | */ | |
510 | ||
511 | static void make1c( state const * const pState ) | |
512 | { | |
513 | TARGET * const t = pState->t; | |
514 | CMD * const cmd = (CMD *)t->cmds; | |
11fdf7f2 | 515 | int exec_flags = 0; |
7c673cae FG |
516 | |
517 | if ( cmd ) | |
518 | { | |
519 | /* Pop state first in case something below (e.g. exec_cmd(), exec_wait() | |
520 | * or make1c_closure()) pushes a new state. Note that we must not access | |
521 | * the popped state data after this as the same stack node might have | |
522 | * been reused internally for some newly pushed state. | |
523 | */ | |
524 | pop_state( &state_stack ); | |
525 | ||
526 | if ( cmd->status != EXEC_CMD_OK ) | |
527 | { | |
528 | t->cmds = NULL; | |
529 | push_cmds( cmd->next, cmd->status ); | |
530 | cmd_free( cmd ); | |
531 | return; | |
532 | } | |
533 | ||
534 | #ifdef OPT_SEMAPHORE | |
535 | if ( ! cmd_sem_lock( t ) ) | |
536 | { | |
537 | return; | |
538 | } | |
539 | #endif | |
540 | ||
541 | /* Increment the jobs running counter. */ | |
542 | ++cmdsrunning; | |
543 | ||
11fdf7f2 TL |
544 | if ( ( globs.jobs == 1 ) && ( DEBUG_MAKEQ || |
545 | ( DEBUG_MAKE && !( cmd->rule->actions->flags & RULE_QUIETLY ) ) ) ) | |
546 | { | |
547 | OBJECT * action = cmd->rule->name; | |
548 | OBJECT * target = list_front( lol_get( (LOL *)&cmd->args, 0 ) ); | |
549 | ||
550 | out_printf( "%s %s\n", object_str( action ), object_str( target ) ); | |
551 | ||
552 | /* Print out the command executed if given -d+2. */ | |
553 | if ( DEBUG_EXEC ) | |
554 | { | |
555 | out_puts( cmd->buf->value ); | |
556 | out_putc( '\n' ); | |
557 | } | |
558 | ||
559 | /* We only need to flush the streams if there's likely to | |
560 | * be a wait before it finishes. | |
561 | */ | |
562 | if ( ! globs.noexec && ! cmd->noop ) | |
563 | { | |
564 | out_flush(); | |
565 | err_flush(); | |
566 | } | |
567 | } | |
568 | else | |
569 | { | |
570 | exec_flags |= EXEC_CMD_QUIET; | |
571 | } | |
572 | ||
7c673cae FG |
573 | /* Execute the actual build command or fake it if no-op. */ |
574 | if ( globs.noexec || cmd->noop ) | |
575 | { | |
576 | timing_info time_info = { 0 }; | |
577 | timestamp_current( &time_info.start ); | |
578 | timestamp_copy( &time_info.end, &time_info.start ); | |
579 | make1c_closure( t, EXEC_CMD_OK, &time_info, "", "", EXIT_OK ); | |
580 | } | |
581 | else | |
582 | { | |
11fdf7f2 | 583 | exec_cmd( cmd->buf, exec_flags, make1c_closure, t, cmd->shell ); |
7c673cae FG |
584 | |
585 | /* Wait until under the concurrent command count limit. */ | |
586 | /* FIXME: This wait could be skipped here and moved to just before | |
587 | * trying to execute a command that would cross the command count | |
588 | * limit. Note though that this might affect the order in which | |
589 | * unrelated targets get built and would thus require that all | |
590 | * affected Boost Build tests be updated. | |
591 | */ | |
592 | assert( 0 < globs.jobs ); | |
7c673cae FG |
593 | while ( cmdsrunning >= globs.jobs ) |
594 | exec_wait(); | |
595 | } | |
596 | } | |
597 | else | |
598 | { | |
7c673cae FG |
599 | /* Tally success/failure for those we tried to update. */ |
600 | if ( t->progress == T_MAKE_RUNNING ) | |
11fdf7f2 TL |
601 | { |
602 | /* Invert OK/FAIL target status when FAIL_EXPECTED has been applied. */ | |
603 | if ( t->flags & T_FLAG_FAIL_EXPECTED && !globs.noexec ) | |
604 | { | |
605 | switch ( t->status ) | |
606 | { | |
607 | case EXEC_CMD_FAIL: t->status = EXEC_CMD_OK; break; | |
608 | case EXEC_CMD_OK: t->status = EXEC_CMD_FAIL; break; | |
609 | } | |
610 | ||
611 | /* Printing failure has to be delayed until the last | |
612 | * action is completed for FAIL_EXPECTED targets. | |
613 | * Do it here. | |
614 | */ | |
615 | if ( t->status == EXEC_CMD_FAIL ) | |
616 | { | |
617 | out_printf( "...failed %s ", object_str( t->actions->action->rule->name ) ); | |
618 | out_printf( "%s", object_str( t->boundname ) ); | |
619 | out_printf( "...\n" ); | |
620 | } | |
621 | ||
622 | /* Handle -q */ | |
623 | if ( t->status == EXEC_CMD_FAIL && globs.quitquick ) | |
624 | ++quit; | |
625 | ||
626 | /* Delete the target on failure. */ | |
627 | if ( !( t->flags & ( T_FLAG_PRECIOUS | T_FLAG_NOTFILE ) ) && | |
628 | !unlink( object_str( t->boundname ) ) ) | |
629 | out_printf( "...removing %s\n", object_str( t->boundname ) ); | |
630 | } | |
7c673cae FG |
631 | switch ( t->status ) |
632 | { | |
633 | case EXEC_CMD_OK: ++counts->made; break; | |
634 | case EXEC_CMD_FAIL: ++counts->failed; break; | |
635 | } | |
11fdf7f2 | 636 | } |
7c673cae FG |
637 | |
638 | /* Tell parents their dependency has been built. */ | |
639 | { | |
640 | TARGETS * c; | |
641 | stack temp_stack = { NULL }; | |
642 | TARGET * additional_includes = NULL; | |
643 | ||
644 | t->progress = globs.noexec ? T_MAKE_NOEXEC_DONE : T_MAKE_DONE; | |
645 | ||
646 | /* Target has been updated so rescan it for dependencies. */ | |
647 | if ( t->fate >= T_FATE_MISSING && t->status == EXEC_CMD_OK && | |
648 | !( t->flags & T_FLAG_INTERNAL ) ) | |
649 | { | |
650 | TARGET * saved_includes; | |
651 | SETTINGS * s; | |
652 | ||
653 | /* Clean current includes. */ | |
654 | saved_includes = t->includes; | |
655 | t->includes = 0; | |
656 | ||
657 | s = copysettings( t->settings ); | |
658 | pushsettings( root_module(), s ); | |
659 | headers( t ); | |
660 | popsettings( root_module(), s ); | |
661 | freesettings( s ); | |
662 | ||
663 | if ( t->includes ) | |
664 | { | |
665 | /* Tricky. The parents have already been processed, but they | |
666 | * have not seen the internal node, because it was just | |
667 | * created. We need to: | |
668 | * - push MAKE1A states that would have been pushed by the | |
669 | * parents here | |
670 | * - make sure all unprocessed parents will pick up the | |
671 | * new includes | |
672 | * - make sure processing the additional MAKE1A states is | |
673 | * done before processing the MAKE1B state for our | |
674 | * current target (which would mean this target has | |
675 | * already been built), otherwise the parent would be | |
676 | * considered built before the additional MAKE1A state | |
677 | * processing even got a chance to start. | |
678 | */ | |
679 | make0( t->includes, t->parents->target, 0, 0, 0, t->includes | |
680 | ); | |
681 | /* Link the old includes on to make sure that it gets | |
682 | * cleaned up correctly. | |
683 | */ | |
684 | t->includes->includes = saved_includes; | |
685 | for ( c = t->dependants; c; c = c->next ) | |
686 | c->target->depends = targetentry( c->target->depends, | |
687 | t->includes ); | |
688 | /* Will be processed below. */ | |
689 | additional_includes = t->includes; | |
690 | } | |
691 | else | |
692 | { | |
693 | t->includes = saved_includes; | |
694 | } | |
695 | } | |
696 | ||
697 | if ( additional_includes ) | |
698 | for ( c = t->parents; c; c = c->next ) | |
699 | push_state( &temp_stack, additional_includes, c->target, | |
700 | T_STATE_MAKE1A ); | |
701 | ||
702 | if ( t->scc_root ) | |
703 | { | |
704 | TARGET * const scc_root = target_scc( t ); | |
705 | assert( scc_root->progress < T_MAKE_DONE ); | |
706 | for ( c = t->parents; c; c = c->next ) | |
707 | { | |
708 | if ( target_scc( c->target ) == scc_root ) | |
709 | push_state( &temp_stack, c->target, NULL, T_STATE_MAKE1B | |
710 | ); | |
711 | else | |
712 | scc_root->parents = targetentry( scc_root->parents, | |
713 | c->target ); | |
714 | } | |
715 | } | |
716 | else | |
717 | { | |
718 | for ( c = t->parents; c; c = c->next ) | |
719 | push_state( &temp_stack, c->target, NULL, T_STATE_MAKE1B ); | |
720 | } | |
721 | ||
722 | /* Must pop state before pushing any more. */ | |
723 | pop_state( &state_stack ); | |
724 | ||
725 | /* Using stacks reverses the order of execution. Reverse it back. */ | |
726 | push_stack_on_stack( &state_stack, &temp_stack ); | |
727 | } | |
728 | } | |
729 | } | |
730 | ||
731 | ||
732 | /* | |
733 | * call_timing_rule() - Look up the __TIMING_RULE__ variable on the given | |
734 | * target, and if non-empty, invoke the rule it names, passing the given | |
735 | * timing_info. | |
736 | */ | |
737 | ||
738 | static void call_timing_rule( TARGET * target, timing_info const * const time ) | |
739 | { | |
740 | LIST * timing_rule; | |
741 | ||
742 | pushsettings( root_module(), target->settings ); | |
743 | timing_rule = var_get( root_module(), constant_TIMING_RULE ); | |
744 | popsettings( root_module(), target->settings ); | |
745 | ||
746 | if ( !list_empty( timing_rule ) ) | |
747 | { | |
748 | /* rule timing-rule ( args * : target : start end user system clock ) */ | |
749 | ||
750 | /* Prepare the argument list. */ | |
751 | FRAME frame[ 1 ]; | |
752 | OBJECT * rulename = list_front( timing_rule ); | |
753 | frame_init( frame ); | |
754 | ||
755 | /* args * :: $(__TIMING_RULE__[2-]) */ | |
756 | lol_add( frame->args, list_copy_range( timing_rule, list_next( | |
757 | list_begin( timing_rule ) ), list_end( timing_rule ) ) ); | |
758 | ||
759 | /* target :: the name of the target */ | |
760 | lol_add( frame->args, list_new( object_copy( target->name ) ) ); | |
761 | ||
762 | /* start end user system clock :: info about the action command */ | |
763 | lol_add( frame->args, list_push_back( list_push_back( list_push_back( list_push_back( list_new( | |
764 | outf_time( &time->start ) ), | |
765 | outf_time( &time->end ) ), | |
766 | outf_double( time->user ) ), | |
767 | outf_double( time->system ) ), | |
768 | outf_double( timestamp_delta_seconds(&time->start, &time->end) ) ) | |
769 | ); | |
770 | ||
771 | /* Call the rule. */ | |
772 | evaluate_rule( bindrule( rulename , root_module() ), rulename, frame ); | |
773 | ||
774 | /* Clean up. */ | |
775 | frame_free( frame ); | |
776 | } | |
777 | } | |
778 | ||
779 | ||
780 | /* | |
781 | * call_action_rule() - Look up the __ACTION_RULE__ variable on the given | |
782 | * target, and if non-empty, invoke the rule it names, passing the given info, | |
783 | * timing_info, executed command and command output. | |
784 | */ | |
785 | ||
786 | static void call_action_rule | |
787 | ( | |
788 | TARGET * target, | |
789 | int status, | |
790 | timing_info const * time, | |
791 | char const * executed_command, | |
792 | char const * command_output | |
793 | ) | |
794 | { | |
795 | LIST * action_rule; | |
796 | ||
797 | pushsettings( root_module(), target->settings ); | |
798 | action_rule = var_get( root_module(), constant_ACTION_RULE ); | |
799 | popsettings( root_module(), target->settings ); | |
800 | ||
801 | if ( !list_empty( action_rule ) ) | |
802 | { | |
803 | /* rule action-rule ( | |
804 | args * : | |
805 | target : | |
806 | command status start end user system : | |
807 | output ? ) */ | |
808 | ||
809 | /* Prepare the argument list. */ | |
810 | FRAME frame[ 1 ]; | |
811 | OBJECT * rulename = list_front( action_rule ); | |
812 | frame_init( frame ); | |
813 | ||
814 | /* args * :: $(__ACTION_RULE__[2-]) */ | |
815 | lol_add( frame->args, list_copy_range( action_rule, list_next( | |
816 | list_begin( action_rule ) ), list_end( action_rule ) ) ); | |
817 | ||
818 | /* target :: the name of the target */ | |
819 | lol_add( frame->args, list_new( object_copy( target->name ) ) ); | |
820 | ||
821 | /* command status start end user system :: info about the action command | |
822 | */ | |
823 | lol_add( frame->args, | |
824 | list_push_back( list_push_back( list_push_back( list_push_back( list_push_back( list_new( | |
825 | object_new( executed_command ) ), | |
826 | outf_int( status ) ), | |
827 | outf_time( &time->start ) ), | |
828 | outf_time( &time->end ) ), | |
829 | outf_double( time->user ) ), | |
830 | outf_double( time->system ) ) ); | |
831 | ||
832 | /* output ? :: the output of the action command */ | |
833 | if ( command_output ) | |
b32b8144 FG |
834 | { |
835 | OBJECT * command_output_obj = object_new( command_output ); | |
836 | char * output_i = (char*)object_str(command_output_obj); | |
837 | /* Clean the output of control characters. */ | |
838 | for (; *output_i; ++output_i) | |
839 | { | |
840 | if (iscntrl(*output_i) && !isspace(*output_i)) *output_i = '?'; | |
841 | } | |
842 | lol_add( frame->args, list_new( command_output_obj ) ); | |
843 | } | |
7c673cae FG |
844 | else |
845 | lol_add( frame->args, L0 ); | |
846 | ||
847 | /* Call the rule. */ | |
848 | evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ); | |
849 | ||
850 | /* Clean up. */ | |
851 | frame_free( frame ); | |
852 | } | |
853 | } | |
854 | ||
855 | ||
856 | /* | |
857 | * make1c_closure() - handle command execution completion and go to MAKE1C. | |
858 | * | |
859 | * Internal function passed as a notification callback for when a command | |
860 | * finishes getting executed by the OS or called directly when faking that a | |
861 | * command had been executed by the OS. | |
862 | * | |
863 | * Now all we need to do is fiddle with the command exit status and push a new | |
864 | * MAKE1C state to execute the next command scheduled for building this target | |
865 | * or close up the target's build process in case there are no more commands | |
866 | * scheduled for it. On interrupts, we bail heavily. | |
867 | */ | |
868 | ||
869 | static void make1c_closure | |
870 | ( | |
871 | void * const closure, | |
872 | int status_orig, | |
873 | timing_info const * const time, | |
874 | char const * const cmd_stdout, | |
875 | char const * const cmd_stderr, | |
876 | int const cmd_exit_reason | |
877 | ) | |
878 | { | |
879 | TARGET * const t = (TARGET *)closure; | |
880 | CMD * const cmd = (CMD *)t->cmds; | |
881 | char const * rule_name = 0; | |
882 | char const * target_name = 0; | |
883 | ||
884 | assert( cmd ); | |
885 | ||
886 | --cmdsrunning; | |
887 | ||
888 | /* Calculate the target's status from the cmd execution result. */ | |
889 | { | |
890 | /* Store the target's status. */ | |
891 | t->status = status_orig; | |
892 | ||
7c673cae FG |
893 | /* Ignore failures for actions marked as 'ignore'. */ |
894 | if ( t->status == EXEC_CMD_FAIL && cmd->rule->actions->flags & | |
895 | RULE_IGNORE ) | |
896 | t->status = EXEC_CMD_OK; | |
897 | } | |
898 | ||
899 | if ( DEBUG_MAKEQ || | |
900 | ( DEBUG_MAKE && !( cmd->rule->actions->flags & RULE_QUIETLY ) ) ) | |
901 | { | |
902 | rule_name = object_str( cmd->rule->name ); | |
903 | target_name = object_str( list_front( lol_get( (LOL *)&cmd->args, 0 ) ) | |
904 | ); | |
905 | } | |
906 | ||
11fdf7f2 TL |
907 | if ( rule_name == NULL || globs.jobs > 1 ) |
908 | out_action( rule_name, target_name, cmd->buf->value, cmd_stdout, | |
909 | cmd_stderr, cmd_exit_reason ); | |
910 | ||
911 | /* If the process expired, make user aware with an explicit message, but do | |
912 | * this only for non-quiet actions. | |
913 | */ | |
914 | if ( cmd_exit_reason == EXIT_TIMEOUT && target_name ) | |
915 | out_printf( "%ld second time limit exceeded\n", globs.timeout ); | |
916 | ||
917 | out_flush(); | |
918 | err_flush(); | |
7c673cae FG |
919 | |
920 | if ( !globs.noexec ) | |
921 | { | |
922 | call_timing_rule( t, time ); | |
923 | if ( DEBUG_EXECCMD ) | |
924 | out_printf( "%f sec system; %f sec user; %f sec clock\n", | |
925 | time->system, time->user, | |
926 | timestamp_delta_seconds(&time->start, &time->end) ); | |
927 | ||
928 | /* Assume -p0 is in effect, i.e. cmd_stdout contains merged output. */ | |
929 | call_action_rule( t, status_orig, time, cmd->buf->value, cmd_stdout ); | |
930 | } | |
931 | ||
932 | /* Print command text on failure. */ | |
11fdf7f2 TL |
933 | if ( t->status == EXEC_CMD_FAIL && DEBUG_MAKE && |
934 | ! ( t->flags & T_FLAG_FAIL_EXPECTED ) ) | |
7c673cae FG |
935 | { |
936 | if ( !DEBUG_EXEC ) | |
937 | out_printf( "%s\n", cmd->buf->value ); | |
938 | ||
939 | out_printf( "...failed %s ", object_str( cmd->rule->name ) ); | |
940 | list_print( lol_get( (LOL *)&cmd->args, 0 ) ); | |
941 | out_printf( "...\n" ); | |
942 | } | |
943 | ||
944 | /* On interrupt, set quit so _everything_ fails. Do the same for failed | |
945 | * commands if we were asked to stop the build in case of any errors. | |
946 | */ | |
947 | if ( t->status == EXEC_CMD_INTR ) | |
948 | { | |
949 | ++intr; | |
950 | ++quit; | |
951 | } | |
11fdf7f2 TL |
952 | if ( t->status == EXEC_CMD_FAIL && globs.quitquick && |
953 | ! ( t->flags & T_FLAG_FAIL_EXPECTED ) ) | |
7c673cae FG |
954 | ++quit; |
955 | ||
956 | /* If the command was not successful remove all of its targets not marked as | |
957 | * "precious". | |
958 | */ | |
959 | if ( t->status != EXEC_CMD_OK ) | |
960 | { | |
961 | LIST * const targets = lol_get( (LOL *)&cmd->args, 0 ); | |
962 | LISTITER iter = list_begin( targets ); | |
963 | LISTITER const end = list_end( targets ); | |
964 | for ( ; iter != end; iter = list_next( iter ) ) | |
965 | { | |
966 | char const * const filename = object_str( list_item( iter ) ); | |
967 | TARGET const * const t = bindtarget( list_item( iter ) ); | |
968 | if ( !( t->flags & T_FLAG_PRECIOUS ) && !unlink( filename ) ) | |
969 | out_printf( "...removing %s\n", filename ); | |
970 | } | |
971 | } | |
972 | ||
973 | #ifdef OPT_SEMAPHORE | |
974 | /* Release any semaphores used by this action. */ | |
975 | cmd_sem_unlock( t ); | |
976 | #endif | |
977 | ||
978 | /* Free this command and push the MAKE1C state to execute the next one | |
979 | * scheduled for building this same target. | |
980 | */ | |
981 | t->cmds = NULL; | |
982 | push_cmds( cmd->next, t->status ); | |
983 | cmd_free( cmd ); | |
984 | } | |
985 | ||
986 | /* push the next MAKE1C state after a command is run. */ | |
987 | static void push_cmds( CMDLIST * cmds, int status ) | |
988 | { | |
989 | CMDLIST * cmd_iter; | |
990 | for( cmd_iter = cmds; cmd_iter; cmd_iter = cmd_iter->next ) | |
991 | { | |
992 | if ( cmd_iter->iscmd ) | |
993 | { | |
994 | CMD * next_cmd = cmd_iter->impl.cmd; | |
995 | /* Propagate the command status. */ | |
996 | if ( next_cmd->status < status ) | |
997 | next_cmd->status = status; | |
998 | if ( --next_cmd->asynccnt == 0 ) | |
999 | { | |
1000 | /* Select the first target associated with the action. | |
1001 | * This is safe because sibling CMDs cannot have targets | |
1002 | * in common. | |
1003 | */ | |
1004 | TARGET * first_target = bindtarget( list_front( lol_get( &next_cmd->args, 0 ) ) ); | |
1005 | first_target->cmds = (char *)next_cmd; | |
1006 | push_state( &state_stack, first_target, NULL, T_STATE_MAKE1C ); | |
1007 | } | |
1008 | else if ( DEBUG_EXECCMD ) | |
1009 | { | |
1010 | TARGET * first_target = bindtarget( list_front( lol_get( &next_cmd->args, 0 ) ) ); | |
1011 | out_printf( "Delaying %s %s: %d targets not ready\n", object_str( next_cmd->rule->name ), object_str( first_target->boundname ), next_cmd->asynccnt ); | |
1012 | } | |
1013 | } | |
1014 | else | |
1015 | { | |
1016 | /* This is a target that we're finished updating */ | |
1017 | TARGET * updated_target = cmd_iter->impl.t; | |
1018 | if ( updated_target->status < status ) | |
1019 | updated_target->status = status; | |
1020 | updated_target->cmds = NULL; | |
1021 | push_state( &state_stack, updated_target, NULL, T_STATE_MAKE1C ); | |
1022 | } | |
1023 | } | |
1024 | } | |
1025 | ||
1026 | ||
1027 | /* | |
1028 | * swap_settings() - replace the settings from the current module and target | |
1029 | * with those from the new module and target | |
1030 | */ | |
1031 | ||
1032 | static void swap_settings | |
1033 | ( | |
1034 | module_t * * current_module, | |
1035 | TARGET * * current_target, | |
1036 | module_t * new_module, | |
1037 | TARGET * new_target | |
1038 | ) | |
1039 | { | |
1040 | if ( ( new_target == *current_target ) && | |
1041 | ( new_module == *current_module ) ) | |
1042 | return; | |
1043 | ||
1044 | if ( *current_target ) | |
1045 | popsettings( *current_module, (*current_target)->settings ); | |
1046 | ||
1047 | if ( new_target ) | |
1048 | pushsettings( new_module, new_target->settings ); | |
1049 | ||
1050 | *current_module = new_module; | |
1051 | *current_target = new_target; | |
1052 | } | |
1053 | ||
1054 | ||
1055 | /* | |
1056 | * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc. | |
1057 | * | |
1058 | * Essentially copies a chain of ACTIONs to a chain of CMDs, grouping | |
1059 | * RULE_TOGETHER actions, splitting RULE_PIECEMEAL actions, and handling | |
1060 | * RULE_NEWSRCS actions. The result is a chain of CMDs which has already had all | |
1061 | * of its embedded variable references expanded and can now be executed using | |
1062 | * exec_cmd(). | |
1063 | */ | |
1064 | ||
1065 | static CMD * make1cmds( TARGET * t ) | |
1066 | { | |
1067 | CMD * cmds = 0; | |
1068 | CMD * last_cmd; | |
1069 | LIST * shell = L0; | |
1070 | module_t * settings_module = 0; | |
1071 | TARGET * settings_target = 0; | |
1072 | ACTIONS * a0; | |
1073 | int const running_flag = globs.noexec ? A_RUNNING_NOEXEC : A_RUNNING; | |
1074 | ||
1075 | /* Step through actions. | |
1076 | */ | |
1077 | for ( a0 = t->actions; a0; a0 = a0->next ) | |
1078 | { | |
1079 | RULE * rule = a0->action->rule; | |
1080 | rule_actions * actions = rule->actions; | |
1081 | SETTINGS * boundvars; | |
1082 | LIST * nt; | |
1083 | LIST * ns; | |
1084 | ACTIONS * a1; | |
1085 | ||
1086 | /* Only do rules with commands to execute. | |
1087 | */ | |
1088 | if ( !actions ) | |
1089 | continue; | |
1090 | ||
1091 | if ( a0->action->running >= running_flag ) | |
1092 | { | |
1093 | CMD * first; | |
1094 | /* If this action was skipped either because it was | |
1095 | * combined with another action by RULE_TOGETHER, or | |
1096 | * because all of its sources were filtered out, | |
1097 | * then we don't have anything to do here. | |
1098 | */ | |
1099 | if ( a0->action->first_cmd == NULL ) | |
1100 | continue; | |
1101 | /* This action has already been processed for another target. | |
1102 | * Just set up the dependency graph correctly and move on. | |
1103 | */ | |
92f5a8d4 | 1104 | first = (CMD *)a0->action->first_cmd; |
7c673cae FG |
1105 | if( cmds ) |
1106 | { | |
1107 | last_cmd->next = cmdlist_append_cmd( last_cmd->next, first ); | |
1108 | } | |
1109 | else | |
1110 | { | |
1111 | cmds = first; | |
1112 | } | |
92f5a8d4 | 1113 | last_cmd = (CMD *)a0->action->last_cmd; |
7c673cae FG |
1114 | continue; |
1115 | } | |
1116 | ||
1117 | a0->action->running = running_flag; | |
1118 | ||
1119 | /* Make LISTS of targets and sources. If `execute together` has been | |
1120 | * specified for this rule, tack on sources from each instance of this | |
1121 | * rule for this target. | |
1122 | */ | |
1123 | nt = make1list( L0, a0->action->targets, 0 ); | |
1124 | ns = make1list( L0, a0->action->sources, actions->flags ); | |
1125 | if ( actions->flags & RULE_TOGETHER ) | |
1126 | for ( a1 = a0->next; a1; a1 = a1->next ) | |
1127 | if ( a1->action->rule == rule && | |
1128 | a1->action->running < running_flag && | |
1129 | targets_equal( a0->action->targets, a1->action->targets ) ) | |
1130 | { | |
1131 | ns = make1list( ns, a1->action->sources, actions->flags ); | |
1132 | a1->action->running = running_flag; | |
1133 | } | |
1134 | ||
1135 | /* If doing only updated (or existing) sources, but none have been | |
1136 | * updated (or exist), skip this action. | |
1137 | */ | |
1138 | if ( list_empty( ns ) && | |
1139 | ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) ) | |
1140 | { | |
1141 | list_free( nt ); | |
1142 | continue; | |
1143 | } | |
1144 | ||
1145 | swap_settings( &settings_module, &settings_target, rule->module, t ); | |
1146 | if ( list_empty( shell ) ) | |
1147 | { | |
1148 | /* shell is per-target */ | |
1149 | shell = var_get( rule->module, constant_JAMSHELL ); | |
1150 | } | |
1151 | ||
1152 | /* If we had 'actions xxx bind vars' we bind the vars now. */ | |
1153 | boundvars = make1settings( rule->module, actions->bindlist ); | |
1154 | pushsettings( rule->module, boundvars ); | |
1155 | ||
1156 | /* | |
1157 | * Build command, starting with all source args. | |
1158 | * | |
1159 | * For actions that allow PIECEMEAL commands, if the constructed command | |
1160 | * string is too long, we retry constructing it with a reduced number of | |
1161 | * source arguments presented. | |
1162 | * | |
1163 | * While reducing slowly takes a bit of compute time to get things just | |
1164 | * right, it is worth it to get as close to maximum allowed command | |
1165 | * string length as possible, because launching the commands we are | |
1166 | * executing is likely to be much more compute intensive. | |
1167 | * | |
1168 | * Note that we loop through at least once, for sourceless actions. | |
1169 | */ | |
1170 | { | |
1171 | int const length = list_length( ns ); | |
1172 | int start = 0; | |
1173 | int chunk = length; | |
1174 | int cmd_count = 0; | |
7c673cae FG |
1175 | TARGETS * semaphores = NULL; |
1176 | TARGETS * targets_iter; | |
1177 | int unique_targets; | |
1178 | do | |
1179 | { | |
1180 | CMD * cmd; | |
1181 | int cmd_check_result; | |
1182 | int cmd_error_length; | |
1183 | int cmd_error_max_length; | |
1184 | int retry = 0; | |
1185 | int accept_command = 0; | |
1186 | ||
1187 | /* Build cmd: cmd_new() takes ownership of its lists. */ | |
92f5a8d4 TL |
1188 | cmd = cmd_new( rule, list_copy( nt ), list_sublist( ns, start, |
1189 | chunk ), list_copy( shell ) ); | |
7c673cae FG |
1190 | |
1191 | cmd_check_result = exec_check( cmd->buf, &cmd->shell, | |
1192 | &cmd_error_length, &cmd_error_max_length ); | |
1193 | ||
1194 | if ( cmd_check_result == EXEC_CHECK_OK ) | |
1195 | { | |
1196 | accept_command = 1; | |
1197 | } | |
1198 | else if ( cmd_check_result == EXEC_CHECK_NOOP ) | |
1199 | { | |
1200 | accept_command = 1; | |
1201 | cmd->noop = 1; | |
1202 | } | |
1203 | else if ( ( actions->flags & RULE_PIECEMEAL ) && ( chunk > 1 ) ) | |
1204 | { | |
1205 | /* Too long but splittable. Reduce chunk size slowly and | |
1206 | * retry. | |
1207 | */ | |
1208 | assert( cmd_check_result == EXEC_CHECK_TOO_LONG || | |
1209 | cmd_check_result == EXEC_CHECK_LINE_TOO_LONG ); | |
1210 | chunk = chunk * 9 / 10; | |
1211 | retry = 1; | |
1212 | } | |
1213 | else | |
1214 | { | |
1215 | /* Too long and not splittable. */ | |
1216 | char const * const error_message = cmd_check_result == | |
1217 | EXEC_CHECK_TOO_LONG | |
1218 | ? "is too long" | |
1219 | : "contains a line that is too long"; | |
1220 | assert( cmd_check_result == EXEC_CHECK_TOO_LONG || | |
1221 | cmd_check_result == EXEC_CHECK_LINE_TOO_LONG ); | |
1222 | out_printf( "%s action %s (%d, max %d):\n", object_str( | |
1223 | rule->name ), error_message, cmd_error_length, | |
1224 | cmd_error_max_length ); | |
1225 | ||
1226 | /* Tell the user what did not fit. */ | |
1227 | out_puts( cmd->buf->value ); | |
1228 | exit( EXITBAD ); | |
1229 | } | |
1230 | ||
1231 | assert( !retry || !accept_command ); | |
1232 | ||
1233 | if ( accept_command ) | |
1234 | { | |
1235 | /* Chain it up. */ | |
1236 | if ( cmds ) | |
1237 | { | |
1238 | last_cmd->next = cmdlist_append_cmd( last_cmd->next, cmd ); | |
1239 | last_cmd = cmd; | |
1240 | } | |
1241 | else | |
1242 | { | |
1243 | cmds = last_cmd = cmd; | |
1244 | } | |
1245 | ||
1246 | if ( cmd_count++ == 0 ) | |
1247 | { | |
1248 | a0->action->first_cmd = cmd; | |
1249 | } | |
7c673cae FG |
1250 | } |
1251 | else | |
1252 | { | |
7c673cae FG |
1253 | cmd_free( cmd ); |
1254 | } | |
1255 | ||
1256 | if ( !retry ) | |
1257 | start += chunk; | |
1258 | } | |
1259 | while ( start < length ); | |
1260 | ||
1261 | /* Record the end of the actions cmds */ | |
1262 | a0->action->last_cmd = last_cmd; | |
1263 | ||
1264 | unique_targets = 0; | |
1265 | for ( targets_iter = a0->action->targets; targets_iter; targets_iter = targets_iter->next ) | |
1266 | { | |
1267 | if ( targets_contains( targets_iter->next, targets_iter->target ) ) | |
1268 | continue; | |
1269 | /* Add all targets produced by the action to the update list. */ | |
1270 | push_state( &state_stack, targets_iter->target, NULL, T_STATE_MAKE1A ); | |
1271 | ++unique_targets; | |
1272 | } | |
1273 | /* We need to wait until all the targets agree that | |
1274 | * it's okay to run this action. | |
1275 | */ | |
1276 | ( ( CMD * )a0->action->first_cmd )->asynccnt = unique_targets; | |
1277 | ||
1278 | #if OPT_SEMAPHORE | |
1279 | /* Collect semaphores */ | |
1280 | for ( targets_iter = a0->action->targets; targets_iter; targets_iter = targets_iter->next ) | |
1281 | { | |
1282 | TARGET * sem = targets_iter->target->semaphore; | |
1283 | if ( sem ) | |
1284 | { | |
7c673cae FG |
1285 | if ( ! targets_contains( semaphores, sem ) ) |
1286 | semaphores = targetentry( semaphores, sem ); | |
1287 | } | |
1288 | } | |
1289 | ( ( CMD * )a0->action->first_cmd )->lock = semaphores; | |
1290 | ( ( CMD * )a0->action->last_cmd )->unlock = semaphores; | |
1291 | #endif | |
1292 | } | |
1293 | ||
1294 | /* These were always copied when used. */ | |
1295 | list_free( nt ); | |
1296 | list_free( ns ); | |
1297 | ||
1298 | /* Free variables with values bound by 'actions xxx bind vars'. */ | |
1299 | popsettings( rule->module, boundvars ); | |
1300 | freesettings( boundvars ); | |
1301 | } | |
1302 | ||
1303 | if ( cmds ) | |
1304 | { | |
1305 | last_cmd->next = cmdlist_append_target( last_cmd->next, t ); | |
1306 | } | |
1307 | ||
1308 | swap_settings( &settings_module, &settings_target, 0, 0 ); | |
1309 | return cmds; | |
1310 | } | |
1311 | ||
1312 | ||
1313 | /* | |
1314 | * make1list() - turn a list of targets into a LIST, for $(<) and $(>) | |
1315 | */ | |
1316 | ||
1317 | static LIST * make1list( LIST * l, TARGETS * targets, int flags ) | |
1318 | { | |
1319 | for ( ; targets; targets = targets->next ) | |
1320 | { | |
1321 | TARGET * t = targets->target; | |
1322 | ||
1323 | if ( t->binding == T_BIND_UNBOUND ) | |
1324 | make1bind( t ); | |
1325 | ||
1326 | if ( ( flags & RULE_EXISTING ) && ( flags & RULE_NEWSRCS ) ) | |
1327 | { | |
1328 | if ( ( t->binding != T_BIND_EXISTS ) && | |
1329 | ( t->fate <= T_FATE_STABLE ) ) | |
1330 | continue; | |
1331 | } | |
1332 | else if ( flags & RULE_EXISTING ) | |
1333 | { | |
1334 | if ( t->binding != T_BIND_EXISTS ) | |
1335 | continue; | |
1336 | } | |
1337 | else if ( flags & RULE_NEWSRCS ) | |
1338 | { | |
1339 | if ( t->fate <= T_FATE_STABLE ) | |
1340 | continue; | |
1341 | } | |
1342 | ||
1343 | /* Prohibit duplicates for RULE_TOGETHER. */ | |
1344 | if ( flags & RULE_TOGETHER ) | |
1345 | { | |
1346 | LISTITER iter = list_begin( l ); | |
1347 | LISTITER const end = list_end( l ); | |
1348 | for ( ; iter != end; iter = list_next( iter ) ) | |
1349 | if ( object_equal( list_item( iter ), t->boundname ) ) | |
1350 | break; | |
1351 | if ( iter != end ) | |
1352 | continue; | |
1353 | } | |
1354 | ||
1355 | /* Build new list. */ | |
1356 | l = list_push_back( l, object_copy( t->boundname ) ); | |
1357 | } | |
1358 | ||
1359 | return l; | |
1360 | } | |
1361 | ||
1362 | ||
1363 | /* | |
1364 | * make1settings() - for vars with bound values, build up replacement lists | |
1365 | */ | |
1366 | ||
1367 | static SETTINGS * make1settings( struct module_t * module, LIST * vars ) | |
1368 | { | |
1369 | SETTINGS * settings = 0; | |
1370 | ||
1371 | LISTITER vars_iter = list_begin( vars ); | |
1372 | LISTITER const vars_end = list_end( vars ); | |
1373 | for ( ; vars_iter != vars_end; vars_iter = list_next( vars_iter ) ) | |
1374 | { | |
1375 | LIST * const l = var_get( module, list_item( vars_iter ) ); | |
1376 | LIST * nl = L0; | |
1377 | LISTITER iter = list_begin( l ); | |
1378 | LISTITER const end = list_end( l ); | |
1379 | ||
1380 | for ( ; iter != end; iter = list_next( iter ) ) | |
1381 | { | |
1382 | TARGET * const t = bindtarget( list_item( iter ) ); | |
1383 | ||
1384 | /* Make sure the target is bound. */ | |
1385 | if ( t->binding == T_BIND_UNBOUND ) | |
1386 | make1bind( t ); | |
1387 | ||
1388 | /* Build a new list. */ | |
1389 | nl = list_push_back( nl, object_copy( t->boundname ) ); | |
1390 | } | |
1391 | ||
1392 | /* Add to settings chain. */ | |
1393 | settings = addsettings( settings, VAR_SET, list_item( vars_iter ), nl ); | |
1394 | } | |
1395 | ||
1396 | return settings; | |
1397 | } | |
1398 | ||
1399 | ||
1400 | /* | |
1401 | * make1bind() - bind targets that were not bound during dependency analysis | |
1402 | * | |
1403 | * Spot the kludge! If a target is not in the dependency tree, it did not get | |
1404 | * bound by make0(), so we have to do it here. Ugly. | |
1405 | */ | |
1406 | ||
1407 | static void make1bind( TARGET * t ) | |
1408 | { | |
1409 | if ( t->flags & T_FLAG_NOTFILE ) | |
1410 | return; | |
1411 | ||
1412 | pushsettings( root_module(), t->settings ); | |
1413 | object_free( t->boundname ); | |
1414 | t->boundname = search( t->name, &t->time, 0, t->flags & T_FLAG_ISFILE ); | |
1415 | t->binding = timestamp_empty( &t->time ) ? T_BIND_MISSING : T_BIND_EXISTS; | |
1416 | popsettings( root_module(), t->settings ); | |
1417 | } | |
1418 | ||
1419 | ||
1420 | static int targets_contains( TARGETS * l, TARGET * t ) | |
1421 | { | |
1422 | for ( ; l; l = l->next ) | |
1423 | { | |
1424 | if ( t == l->target ) | |
1425 | { | |
1426 | return 1; | |
1427 | } | |
1428 | } | |
1429 | return 0; | |
1430 | } | |
1431 | ||
1432 | static int targets_equal( TARGETS * l1, TARGETS * l2 ) | |
1433 | { | |
1434 | for ( ; l1 && l2; l1 = l1->next, l2 = l2->next ) | |
1435 | { | |
1436 | if ( l1->target != l2->target ) | |
1437 | return 0; | |
1438 | } | |
1439 | return !l1 && !l2; | |
1440 | } | |
1441 | ||
1442 | ||
1443 | #ifdef OPT_SEMAPHORE | |
1444 | ||
1445 | static int cmd_sem_lock( TARGET * t ) | |
1446 | { | |
1447 | CMD * cmd = (CMD *)t->cmds; | |
1448 | TARGETS * iter; | |
1449 | /* Check whether all the semaphores required for updating | |
1450 | * this target are free. | |
1451 | */ | |
1452 | for ( iter = cmd->lock; iter; iter = iter->next ) | |
1453 | { | |
1454 | if ( iter->target->asynccnt > 0 ) | |
1455 | { | |
1456 | if ( DEBUG_EXECCMD ) | |
1457 | out_printf( "SEM: %s is busy, delaying launch of %s\n", | |
1458 | object_str( iter->target->name ), object_str( t->name ) ); | |
1459 | iter->target->parents = targetentry( iter->target->parents, t ); | |
1460 | return 0; | |
1461 | } | |
1462 | } | |
1463 | /* Lock the semaphores. */ | |
1464 | for ( iter = cmd->lock; iter; iter = iter->next ) | |
1465 | { | |
1466 | ++iter->target->asynccnt; | |
1467 | if ( DEBUG_EXECCMD ) | |
1468 | out_printf( "SEM: %s now used by %s\n", object_str( iter->target->name | |
1469 | ), object_str( t->name ) ); | |
1470 | } | |
1471 | /* A cmd only needs to be locked around its execution. | |
1472 | * clearing cmd->lock here makes it safe to call cmd_sem_lock | |
1473 | * twice. | |
1474 | */ | |
1475 | cmd->lock = NULL; | |
1476 | return 1; | |
1477 | } | |
1478 | ||
1479 | static void cmd_sem_unlock( TARGET * t ) | |
1480 | { | |
1481 | CMD * cmd = ( CMD * )t->cmds; | |
1482 | TARGETS * iter; | |
1483 | /* Release the semaphores. */ | |
1484 | for ( iter = cmd->unlock; iter; iter = iter->next ) | |
1485 | { | |
1486 | if ( DEBUG_EXECCMD ) | |
1487 | out_printf( "SEM: %s is now free\n", object_str( | |
1488 | iter->target->name ) ); | |
1489 | --iter->target->asynccnt; | |
1490 | assert( iter->target->asynccnt <= 0 ); | |
1491 | } | |
1492 | for ( iter = cmd->unlock; iter; iter = iter->next ) | |
1493 | { | |
1494 | /* Find a waiting target that's ready */ | |
1495 | while ( iter->target->parents ) | |
1496 | { | |
1497 | TARGETS * first = iter->target->parents; | |
1498 | TARGET * t1 = first->target; | |
1499 | ||
1500 | /* Pop the first waiting CMD */ | |
1501 | if ( first->next ) | |
1502 | first->next->tail = first->tail; | |
1503 | iter->target->parents = first->next; | |
1504 | BJAM_FREE( first ); | |
1505 | ||
1506 | if ( cmd_sem_lock( t1 ) ) | |
1507 | { | |
1508 | push_state( &state_stack, t1, NULL, T_STATE_MAKE1C ); | |
1509 | break; | |
1510 | } | |
1511 | } | |
1512 | } | |
1513 | } | |
1514 | ||
1515 | #endif |