int make1( TARGET *t ) { state *pState; memset( (char *)counts, 0, sizeof( *counts ) ); /* Recursively make the target and its dependents */ push_state(&state_stack, t, NULL, T_STATE_MAKE1A); do { while((pState = current_state(&state_stack)) != NULL) { if (intr) pop_state(&state_stack); switch(pState->curstate) { case T_STATE_MAKE1A: make1a(pState); break; case T_STATE_MAKE1ATAIL: make1atail(pState); break; case T_STATE_MAKE1B: make1b(pState); break; case T_STATE_MAKE1C: make1c(pState); break; case T_STATE_MAKE1D: make1d(pState); break; default: break; } } /* Wait for any outstanding commands to finish running. */ } while( execwait() ); clear_state_freelist(); /* Talk about it */ if( counts->failed ) printf( "...failed updating %d target%s...\n", counts->failed, counts->failed > 1 ? "s" : "" ); if( DEBUG_MAKE && counts->skipped ) printf( "...skipped %d target%s...\n", counts->skipped, counts->skipped > 1 ? "s" : "" ); if( DEBUG_MAKE && counts->made ) printf( "...updated %d target%s...\n", counts->made, counts->made > 1 ? "s" : "" ); return counts->total != counts->made; }
int make1( TARGET * const t ) { state * pState; memset( (char *)counts, 0, sizeof( *counts ) ); /* Recursively make the target and its dependencies. */ push_state( &state_stack, t, NULL, T_STATE_MAKE1A ); while ( 1 ) { while ( ( pState = current_state( &state_stack ) ) ) { if ( intr ) pop_state( &state_stack ); switch ( pState->curstate ) { case T_STATE_MAKE1A: make1a( pState ); break; case T_STATE_MAKE1B: make1b( pState ); break; case T_STATE_MAKE1C: make1c( pState ); break; default: assert( !"make1(): Invalid state detected." ); } } if ( !cmdsrunning ) break; /* Wait for outstanding commands to finish running. */ exec_wait(); } clear_state_freelist(); /* Talk about it. */ if ( counts->failed ) printf( "...failed updating %d target%s...\n", counts->failed, counts->failed > 1 ? "s" : "" ); if ( DEBUG_MAKE && counts->skipped ) printf( "...skipped %d target%s...\n", counts->skipped, counts->skipped > 1 ? "s" : "" ); if ( DEBUG_MAKE && counts->made ) printf( "...updated %d target%s...\n", counts->made, counts->made > 1 ? "s" : "" ); return counts->total != counts->made; }
static void make1a( TARGET *t, TARGET *parent ) { TARGETS *c; #ifdef OPT_DEBUG_MAKE1_LOG_EXT if (DEBUG_MAKE1) { printf("make1\t--\t%s (parent %s)\n", t->name, parent ? parent->name : "<nil>"); } #endif /* If the parent is the first to try to build this target */ /* or this target is in the make1c() quagmire, arrange for the */ /* parent to be notified when this target is built. */ if( parent ) switch( t->progress ) { case T_MAKE_INIT: case T_MAKE_ACTIVE: case T_MAKE_RUNNING: #ifdef OPT_BUILTIN_NEEDS_EXT t->parents = targetentry( t->parents, parent, 0 ); #else t->parents = targetentry( t->parents, parent ); #endif parent->asynccnt++; } if( t->progress != T_MAKE_INIT ) return; /* Asynccnt counts the dependents preventing this target from */ /* proceeding to make1b() for actual building. We start off with */ /* a count of 1 to prevent anything from happening until we can */ /* call all dependents. This 1 is accounted for when we call */ /* make1b() ourselves, below. */ t->asynccnt = 1; /* Recurse on our dependents, manipulating progress to guard */ /* against circular dependency. */ t->progress = T_MAKE_ONSTACK; /* Recurse on "real" dependents. */ for( c = t->depends; c && !intr; c = c->next ) make1a( c->target, t ); #ifdef OPT_UPDATED_CHILD_FIX { ACTIONS *actions; for( actions = t->actions; actions; actions = actions->next ) { TARGETS *targets; #ifdef OPT_MULTIPASS_EXT if ( actions->action->pass != actionpass ) continue; #endif for( targets = actions->action->targets; targets; targets = targets->next ) { if (targets->target != t)// && targets->target->progress<T_MAKE_ONSTACK) { // make1a( targets->target, t ); for( c = targets->target->depends; c && !intr; c = c->next ) make1a( c->target, t ); } } } } #endif t->progress = T_MAKE_ACTIVE; /* Now that all dependents have bumped asynccnt, we now allow */ /* decrement our reference to asynccnt. */ make1b( t ); }
static void make1c( TARGET *t ) { CMD *cmd = (CMD *)t->cmds; #ifdef OPT_DEBUG_MAKE1_LOG_EXT if (DEBUG_MAKE1) { printf( "make1c\t--\t%s (status %d)\n" , t->name, t->status ); } #endif /* If there are (more) commands to run to build this target */ /* (and we haven't hit an error running earlier comands) we */ /* launch the command with execcmd(). */ /* If there are no more commands to run, we collect the status */ /* from all the actions then report our completion to all the */ /* parents. */ if( cmd && t->status == EXEC_CMD_OK ) { #ifdef OPT_DEBUG_MAKE1_LOG_EXT if (DEBUG_MAKE1) { printf( "make1c\t--\t%s (more to do)\n" , t->name ); } #endif #ifndef OPT_SERIAL_OUTPUT_EXT if( DEBUG_MAKE ) if( DEBUG_MAKEQ || ! ( cmd->rule->flags & RULE_QUIETLY ) ) { #ifdef OPT_PERCENT_DONE_EXT /* CWM - added '@' and %done to front of output */ int done = counts->skipped + counts->failed + counts->made; float percent = (done * 99.0f) / globs.updating; printf( "@ %2.0f%% %s ", percent, cmd->rule->name ); #else /* CWM - added '@' to front of output */ printf( "@ %s ", cmd->rule->name ); #endif #ifdef OPT_DEBUG_MAKE_PRINT_TARGET_NAME if (globs.printtarget) { printf("%s ", t->name); } else { list_print( lol_get( &cmd->args, 0 ) ); } #else list_print( lol_get( &cmd->args, 0 ) ); #endif printf( "\n" ); } if( DEBUG_EXEC ) printf( "%s\n", buffer_ptr( &cmd->commandbuff ) ); #endif /* !OPT_SERIAL_OUTPUT_EXT */ #ifdef OPT_RESPONSE_FILES if (DEBUG_EXEC) { printResponseFiles(cmd); } #endif if( globs.cmdout ) fprintf( globs.cmdout, "%s", buffer_ptr(&cmd->commandbuff) ); #ifdef OPT_BUILTIN_LUA_SUPPORT_EXT if ( cmd->rule->flags & RULE_LUA ) { execlua( cmd->luastring, make1d, t ); } else #endif #ifdef OPT_ACTIONS_DUMP_TEXT_EXT if (cmd->rule->flags & RULE_WRITEFILE) { #ifdef OPT_SERIAL_OUTPUT_EXT make1d( 0, t, EXEC_CMD_OK ); #else make1d( t, EXEC_CMD_OK ); #endif } else #endif if( globs.noexec ) { #ifdef OPT_SERIAL_OUTPUT_EXT make1d( 0, t, EXEC_CMD_OK ); #else make1d( t, EXEC_CMD_OK ); #endif } else { fflush( stdout ); execcmd( buffer_ptr(&cmd->commandbuff), make1d, t, cmd->shell, (cmd->rule->flags & RULE_SCREENOUTPUT) == 0 ); } } else { TARGETS *c; ACTIONS *actions; #ifdef OPT_DEBUG_MAKE1_LOG_EXT if (DEBUG_MAKE1) { printf( "make1c\t--\t%s (no more to do)\n" , t->name ); } #endif /* Collect status from actions, and distribute it as well */ #ifdef OPT_MULTIPASS_EXT { int previousPassStatus = -1; int currentPassStatus = -1; for( actions = t->actions; actions; actions = actions->next ) if( actions->action->pass < actionpass && actions->action->status > previousPassStatus ) previousPassStatus = actions->action->status; for( actions = t->actions; actions; actions = actions->next ) if( actions->action->pass == actionpass && actions->action->status > currentPassStatus ) currentPassStatus = actions->action->status; if (currentPassStatus == -1 && previousPassStatus != -1) t->status = previousPassStatus; else if (currentPassStatus != -1 && currentPassStatus > t->status) t->status = currentPassStatus; for( actions = t->actions; actions; actions = actions->next ) if( actions->action->pass == actionpass && t->status > actions->action->status ) actions->action->status = t->status; } #else for( actions = t->actions; actions; actions = actions->next ) if( actions->action->status > t->status ) t->status = actions->action->status; for( actions = t->actions; actions; actions = actions->next ) if( t->status > actions->action->status ) actions->action->status = t->status; #endif #ifdef OPT_MULTIPASS_EXT if ( t->fate == T_FATE_MISSING && !( t->flags & T_FLAG_NOCARE ) && !t->actions && queuedjamfiles ) { t->status = EXEC_CMD_NEXTPASS; } #endif /* Tally success/failure for those we tried to update. */ if( t->progress == T_MAKE_RUNNING ) switch( t->status ) { case EXEC_CMD_OK: ++counts->made; break; case EXEC_CMD_FAIL: ++counts->failed; break; } /* Tell parents dependent has been built */ t->progress = T_MAKE_DONE; #ifdef OPT_BUILTIN_MD5CACHE_EXT /* Update the file cache. */ if ( t->flags & T_FLAG_USECOMMANDLINE ) hcache_finalizerulemd5sum( t ); #endif #ifdef OPT_SEMAPHORE /* If there is a semaphore, its now free */ if( t->semaphore ) { --(t->semaphore->asynccnt); if( DEBUG_EXECCMD ) printf( "SEM: %s is now free\n", t->semaphore->name); /* If anything is waiting, notify the next target */ if( t->semaphore->parents ) { TARGETS *first = t->semaphore->parents; if( first->next ) first->next->tail = first->tail; t->semaphore->parents = first->next; if( DEBUG_EXECCMD ) printf( "SEM: now launching %s\n", first->target->name); make1b( first->target ); #ifndef OPT_IMPROVED_MEMUSE_EXT free( first ); #endif } } #endif for( c = t->parents; c; c = c->next ) make1b( c->target ); } }
int make1( LIST * targets ) { state * pState; int status = 0; memset( (char *)counts, 0, sizeof( *counts ) ); { LISTITER iter, end; stack temp_stack = { NULL }; for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) ) push_state( &temp_stack, bindtarget( list_item( iter ) ), NULL, T_STATE_MAKE1A ); push_stack_on_stack( &state_stack, &temp_stack ); } /* Clear any state left over from the past */ quit = 0; /* Recursively make the target and its dependencies. */ while ( 1 ) { while ( ( pState = current_state( &state_stack ) ) ) { if ( quit ) pop_state( &state_stack ); switch ( pState->curstate ) { case T_STATE_MAKE1A: make1a( pState ); break; case T_STATE_MAKE1B: make1b( pState ); break; case T_STATE_MAKE1C: make1c( pState ); break; default: assert( !"make1(): Invalid state detected." ); } } if ( !cmdsrunning ) break; /* Wait for outstanding commands to finish running. */ exec_wait(); } clear_state_freelist(); /* Talk about it. */ if ( counts->failed ) printf( "...failed updating %d target%s...\n", counts->failed, counts->failed > 1 ? "s" : "" ); if ( DEBUG_MAKE && counts->skipped ) printf( "...skipped %d target%s...\n", counts->skipped, counts->skipped > 1 ? "s" : "" ); if ( DEBUG_MAKE && counts->made ) printf( "...updated %d target%s...\n", counts->made, counts->made > 1 ? "s" : "" ); /* If we were interrupted, exit now that all child processes have finished. */ if ( intr ) exit( 1 ); { LISTITER iter, end; for ( iter = list_begin( targets ), end = list_end( targets ); iter != end; iter = list_next( iter ) ) { /* Check that the target was updated and that the update succeeded. */ TARGET * t = bindtarget( list_item( iter ) ); if (t->progress == T_MAKE_DONE) { if (t->status != EXEC_CMD_OK) status = 1; } else if ( ! ( t->progress == T_MAKE_NOEXEC_DONE && globs.noexec ) ) { status = 1; } } } return status; }