⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 make1.c

📁 jam源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    }	    /* Tell parents dependent has been built */	    t->progress = T_MAKE_DONE;	    for( c = t->parents; c; c = c->next )		make1b( c->target );	}}/* * make1d() - handle command execution completion and call back make1c() */static voidmake1d( 	void	*closure,	int	status ){	TARGET	*t = (TARGET *)closure;	CMD	*cmd = (CMD *)t->cmds;	/* Execcmd() has completed.  All we need to do is fiddle with the */	/* status and signal our completion so make1c() can run the next */	/* command.  On interrupts, we bail heavily. */	if( status == EXEC_CMD_FAIL && ( cmd->rule->flags & RULE_IGNORE ) )	    status = EXEC_CMD_OK;	/* On interrupt, set intr so _everything_ fails */	if( status == EXEC_CMD_INTR )	    ++intr;	if( status == EXEC_CMD_FAIL && DEBUG_MAKE )	{	    /* Print command text on failure */	    if( !DEBUG_EXEC )		printf( "%s\n", cmd->buf );	    printf( "...failed %s ", cmd->rule->name );	    list_print( lol_get( &cmd->args, 0 ) );	    printf( "...\n" );	    if( globs.quitquick ) ++intr;	}	/* If the command was interrupted or failed and the target */	/* is not "precious", remove the targets. */	/* Precious == 'actions updated' -- the target maintains state. */	if( status != EXEC_CMD_OK && !( cmd->rule->flags & RULE_UPDATED ) )	{	    LIST *targets = lol_get( &cmd->args, 0 );	    for( ; targets; targets = list_next( targets ) )		if( !unlink( targets->string ) )		    printf( "...removing %s\n", targets->string );	}	/* Free this command and call make1c() to move onto next command. */	t->status = status;	t->cmds = (char *)cmd_next( cmd );	cmd_free( cmd );	make1c( t );}/* * make1cmds() - turn ACTIONS into CMDs, grouping, splitting, etc * * Essentially copies a chain of ACTIONs to a chain of CMDs,  * grouping RULE_TOGETHER actions, splitting RULE_PIECEMEAL actions, * and handling RULE_UPDATED actions.  The result is a chain of * CMDs which can be expanded by var_string() and executed with * execcmd(). */static CMD *make1cmds( ACTIONS *a0 ){	CMD *cmds = 0;	LIST *shell = var_get( "JAMSHELL" );	/* shell is per-target */	/* Step through actions */	/* Actions may be shared with other targets or grouped with */	/* RULE_TOGETHER, so actions already seen are skipped. */	for( ; a0; a0 = a0->next )	{	    RULE    *rule = a0->action->rule;	    SETTINGS *boundvars;	    LIST    *nt, *ns;	    ACTIONS *a1;	    CMD	    *cmd;	    int	    start, chunk, length, maxline;	    /* Only do rules with commands to execute. */	    /* If this action has already been executed, use saved status */	    if( !rule->actions || a0->action->running )		continue;	    a0->action->running = 1;	    	    /* Make LISTS of targets and sources */	    /* If `execute together` has been specified for this rule, tack */	    /* on sources from each instance of this rule for this target. */	    nt = make1list( L0, a0->action->targets, 0 );	    ns = make1list( L0, a0->action->sources, rule->flags );	    if( rule->flags & RULE_TOGETHER )		for( a1 = a0->next; a1; a1 = a1->next )		    if( a1->action->rule == rule && !a1->action->running )	    {		ns = make1list( ns, a1->action->sources, rule->flags );		a1->action->running = 1;	    }	    /* If doing only updated (or existing) sources, but none have */	    /* been updated (or exist), skip this action. */	    if( !ns && ( rule->flags & ( RULE_UPDATED | RULE_EXISTING ) ) )	    {		list_free( nt );		continue;	    }	    /* If we had 'actions xxx bind vars' we bind the vars now */	    boundvars = make1settings( rule->bindlist );	    pushsettings( boundvars );	    /*	     * Build command, starting with all source args. 	     *	     * If cmd_new returns 0, it's because the resulting command	     * length is > MAXLINE.  In this case, we'll slowly reduce	     * the number of source arguments presented until it does	     * fit.  This only applies to actions that allow PIECEMEAL 	     * commands.	     *	     * While reducing slowly takes a bit of compute time to get	     * things just right, it's worth it to get as close to MAXLINE	     * as possible, because launching the commands we're executing 	     * is likely to be much more compute intensive!	     *	     * Note we loop through at least once, for sourceless actions.	     *	     * Max line length is the action specific maxline or, if not 	     * given or bigger than MAXLINE, MAXLINE.	     */	    start = 0;	    chunk = length = list_length( ns );	    maxline = rule->flags / RULE_MAXLINE;	    maxline = maxline && maxline < MAXLINE ? maxline : MAXLINE;	    do	    {		/* Build cmd: cmd_new consumes its lists. */		CMD *cmd = cmd_new( rule, 			list_copy( L0, nt ), 			list_sublist( ns, start, chunk ),			list_copy( L0, shell ),			maxline );		if( cmd )		{		    /* It fit: chain it up. */		    if( !cmds ) cmds = cmd;		    else cmds->tail->next = cmd;		    cmds->tail = cmd;		    start += chunk;		}		else if( ( rule->flags & RULE_PIECEMEAL ) && chunk > 1 )		{		    /* Reduce chunk size slowly. */		    chunk = chunk * 9 / 10;		}		else		{		    /* Too long and not splittable. */		    printf( "%s actions too long (max %d)!\n", 			rule->name, maxline );		    exit( EXITBAD );		}	    }	    while( start < length );	    /* These were always copied when used. */	    list_free( nt );	    list_free( ns );	    /* Free the variables whose values were bound by */	    /* 'actions xxx bind vars' */	    popsettings( boundvars );	    freesettings( boundvars );	}	return cmds;}/* * make1list() - turn a list of targets into a LIST, for $(<) and $(>) */static LIST *make1list( 	LIST	*l,	TARGETS	*targets,	int	flags ){    for( ; targets; targets = targets->next )    {	TARGET *t = targets->target;	/* Sources to 'actions existing' are never in the dependency */	/* graph (if they were, they'd get built and 'existing' would */	/* be superfluous, so throttle warning message about independent */	/* targets. */	if( t->binding == T_BIND_UNBOUND )	    make1bind( t, !( flags & RULE_EXISTING ) );	if( ( flags & RULE_EXISTING ) && t->binding != T_BIND_EXISTS )	    continue;	if( ( flags & RULE_UPDATED ) && t->fate <= T_FATE_STABLE )	    continue;	/* Prohibit duplicates for RULE_TOGETHER */	if( flags & RULE_TOGETHER )	{	    LIST *m;	    for( m = l; m; m = m->next )		if( !strcmp( m->string, t->boundname ) )		    break;	    if( m )		continue;	}	/* Build new list */	l = list_new( l, t->boundname, 1 );    }    return l;}/* * make1settings() - for vars that get bound values, build up replacement lists */static SETTINGS *make1settings( LIST *vars ){	SETTINGS *settings = 0;	for( ; vars; vars = list_next( vars ) )	{	    LIST *l = var_get( vars->string );	    LIST *nl = 0;	    for( ; l; l = list_next( l ) ) 	    {		TARGET *t = bindtarget( l->string );		/* Make sure the target is bound, warning if it is not in the */		/* dependency graph. */		if( t->binding == T_BIND_UNBOUND )		    make1bind( t, 1 );		/* Build new list */		nl = list_new( nl, t->boundname, 1 );	    }	    /* Add to settings chain */	    settings = addsettings( settings, 0, vars->string, nl );	}	return settings;}/* * make1bind() - bind targets that weren't bound in dependency analysis * * Spot the kludge!  If a target is not in the dependency tree, it didn't  * get bound by make0(), so we have to do it here.  Ugly. */static voidmake1bind( 	TARGET	*t,	int	warn ){	if( t->flags & T_FLAG_NOTFILE )	    return;	/* Sources to 'actions existing' are never in the dependency */	/* graph (if they were, they'd get built and 'existing' would */	/* be superfluous, so throttle warning message about independent */	/* targets. */	if( warn )	    printf( "warning: using independent target %s\n", t->name );	pushsettings( t->settings );	t->boundname = search( t->name, &t->time );	t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;	popsettings( t->settings );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -