Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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 );
}
Esempio n. 4
0
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 );
	}
}
Esempio n. 5
0
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;
}