summaryrefslogtreecommitdiff
path: root/tools/build/v2/engine/make1.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/build/v2/engine/make1.c')
-rw-r--r--tools/build/v2/engine/make1.c249
1 files changed, 137 insertions, 112 deletions
diff --git a/tools/build/v2/engine/make1.c b/tools/build/v2/engine/make1.c
index 8001f33390..47132419a8 100644
--- a/tools/build/v2/engine/make1.c
+++ b/tools/build/v2/engine/make1.c
@@ -57,7 +57,7 @@
#include "headers.h"
#include "search.h"
-#include "newstr.h"
+#include "object.h"
#include "make.h"
#include "command.h"
#include "execcmd.h"
@@ -72,7 +72,7 @@
static CMD * make1cmds ( TARGET * );
static LIST * make1list ( LIST *, TARGETS *, int flags );
-static SETTINGS * make1settings( LIST * vars );
+static SETTINGS * make1settings( struct module_t * module, LIST * vars );
static void make1bind ( TARGET * );
/* Ugly static - it is too hard to carry it through the callbacks. */
@@ -107,7 +107,7 @@ static void make1atail ( state * );
static void make1b ( state * );
static void make1c ( state * );
static void make1d ( state * );
-static void make_closure( void * closure, int status, timing_info *, char *, char * );
+static void make_closure( void * closure, int status, timing_info *, const char *, const char * );
typedef struct _stack
{
@@ -281,6 +281,15 @@ static void make1a( state * pState )
++pState->parent->asynccnt;
}
+ /*
+ * If the target has been previously updated with -n in
+ * effect, and we're ignoring -n, update it for real.
+ */
+ if ( !globs.noexec && pState->t->progress == T_MAKE_NOEXEC_DONE )
+ {
+ pState->t->progress = T_MAKE_INIT;
+ }
+
/* If this target is already being processed then do nothing. There is no
* need to start processing the same target all over again.
*/
@@ -350,10 +359,10 @@ static void make1atail( state * pState )
static void make1b( state * pState )
{
- TARGET * t = pState->t;
- TARGETS * c;
- TARGET * failed = 0;
- char * failed_name = "dependencies";
+ TARGET * t = pState->t;
+ TARGETS * c;
+ TARGET * failed = 0;
+ const char * failed_name = "dependencies";
/* If any dependencies are still outstanding, wait until they call make1b()
* to signal their completion.
@@ -376,7 +385,7 @@ static void make1b( state * pState )
if ( DEBUG_EXECCMD )
printf( "SEM: %s is busy, delaying launch of %s\n",
- t->semaphore->name, t->name );
+ object_str( t->semaphore->name ), object_str( t->name ) );
pop_state( &state_stack );
return;
}
@@ -384,13 +393,21 @@ static void make1b( state * pState )
/* Now ready to build target 't', if dependencies built OK. */
- /* Collect status from dependencies. */
- for ( c = t->depends; c; c = c->next )
- if ( c->target->status > t->status && !( c->target->flags & T_FLAG_NOCARE ) )
- {
- failed = c->target;
- pState->t->status = c->target->status;
- }
+ /* Collect status from dependencies. If -n was passed then
+ * act as though all dependencies built correctly. The only
+ * way they can fail is if UPDATE_NOW was called. If
+ * the dependencies can't be found or we got an interrupt,
+ * we can't get here.
+ */
+ if ( !globs.noexec )
+ {
+ for ( c = t->depends; c; c = c->next )
+ if ( c->target->status > t->status && !( c->target->flags & T_FLAG_NOCARE ) )
+ {
+ failed = c->target;
+ pState->t->status = c->target->status;
+ }
+ }
/* If an internal header node failed to build, we want to output the target
* that it failed on.
*/
@@ -398,7 +415,7 @@ static void make1b( state * pState )
{
failed_name = failed->flags & T_FLAG_INTERNAL
? failed->failed
- : failed->name;
+ : object_str( failed->name );
}
t->failed = failed_name;
@@ -410,11 +427,11 @@ static void make1b( state * pState )
++counts->skipped;
if ( ( pState->t->flags & ( T_FLAG_RMOLD | T_FLAG_NOTFILE ) ) == T_FLAG_RMOLD )
{
- if ( !unlink( pState->t->boundname ) )
- printf( "...removing outdated %s\n", pState->t->boundname );
+ if ( !unlink( object_str( pState->t->boundname ) ) )
+ printf( "...removing outdated %s\n", object_str( pState->t->boundname ) );
}
else
- printf( "...skipped %s for lack of %s...\n", pState->t->name, failed_name );
+ printf( "...skipped %s for lack of %s...\n", object_str( pState->t->name ), failed_name );
}
if ( pState->t->status == EXEC_CMD_OK )
@@ -436,7 +453,7 @@ static void make1b( state * pState )
case T_FATE_ISTMP:
if ( DEBUG_MAKE )
- printf( "...using %s...\n", pState->t->name );
+ printf( "...using %s...\n", object_str( pState->t->name ) );
break;
case T_FATE_TOUCHED:
@@ -467,7 +484,7 @@ static void make1b( state * pState )
/* All possible fates should have been accounted for by now. */
default:
- printf( "ERROR: %s has bad fate %d", pState->t->name,
+ printf( "ERROR: %s has bad fate %d", object_str( pState->t->name ),
pState->t->fate );
abort();
}
@@ -484,8 +501,8 @@ static void make1b( state * pState )
{
++pState->t->semaphore->asynccnt;
if ( DEBUG_EXECCMD )
- printf( "SEM: %s now used by %s\n", pState->t->semaphore->name,
- pState->t->name );
+ printf( "SEM: %s now used by %s\n", object_str( pState->t->semaphore->name ),
+ object_str( pState->t->name ) );
}
#endif
@@ -508,16 +525,16 @@ static void make1c( state * pState )
if ( cmd && ( pState->t->status == EXEC_CMD_OK ) )
{
- char * rule_name = 0;
- char * target = 0;
+ const char * rule_name = 0;
+ const char * target = 0;
if ( DEBUG_MAKEQ ||
( !( cmd->rule->actions->flags & RULE_QUIETLY ) && DEBUG_MAKE ) )
{
- rule_name = cmd->rule->name;
- target = lol_get( &cmd->args, 0 )->string;
+ rule_name = object_str( cmd->rule->name );
+ target = object_str( list_front( lol_get( &cmd->args, 0 ) ) );
if ( globs.noexec )
- out_action( rule_name, target, cmd->buf, "", "", EXIT_OK );
+ out_action( rule_name, target, cmd->buf->value, "", "", EXIT_OK );
}
if ( globs.noexec )
@@ -529,7 +546,7 @@ static void make1c( state * pState )
{
/* Pop state first because exec_cmd() could push state. */
pop_state( &state_stack );
- exec_cmd( cmd->buf, make_closure, pState->t, cmd->shell, rule_name,
+ exec_cmd( cmd->buf->value, make_closure, pState->t, cmd->shell, rule_name,
target );
}
}
@@ -560,13 +577,17 @@ static void make1c( state * pState )
TARGET * t = pState->t;
TARGET * additional_includes = NULL;
- t->progress = T_MAKE_DONE;
+ if ( globs.noexec )
+ t->progress = T_MAKE_NOEXEC_DONE;
+ else
+ t->progress = T_MAKE_DONE;
/* Target has been updated so rescan it for dependencies. */
if ( ( t->fate >= T_FATE_MISSING ) &&
( t->status == EXEC_CMD_OK ) &&
!t->rescanned )
{
+ TARGET * saved_includes;
TARGET * target_to_rescan = t;
SETTINGS * s;
@@ -576,16 +597,21 @@ static void make1c( state * pState )
target_to_rescan = t->original_target;
/* Clean current includes. */
+ saved_includes = target_to_rescan->includes;
target_to_rescan->includes = 0;
s = copysettings( target_to_rescan->settings );
- pushsettings( s );
+ pushsettings( root_module(), s );
headers( target_to_rescan );
- popsettings( s );
+ popsettings( root_module(), s );
freesettings( s );
if ( target_to_rescan->includes )
{
+ /* Link the old includes on to make sure that it gets
+ * cleaned up correctly.
+ */
+ target_to_rescan->includes->includes = saved_includes;
target_to_rescan->includes->rescanned = 1;
/* Tricky. The parents have already been processed, but they
* have not seen the internal node, because it was just
@@ -604,6 +630,10 @@ static void make1c( state * pState )
/* Will be processed below. */
additional_includes = target_to_rescan->includes;
}
+ else
+ {
+ target_to_rescan->includes = saved_includes;
+ }
}
if ( additional_includes )
@@ -621,7 +651,7 @@ static void make1c( state * pState )
--t->semaphore->asynccnt;
if ( DEBUG_EXECCMD )
- printf( "SEM: %s is now free\n", t->semaphore->name );
+ printf( "SEM: %s is now free\n", object_str( t->semaphore->name ) );
/* If anything is waiting, notify the next target. There is no
* point in notifying waiting targets, since they will be
@@ -635,7 +665,7 @@ static void make1c( state * pState )
t->semaphore->parents = first->next;
if ( DEBUG_EXECCMD )
- printf( "SEM: placing %s on stack\n", first->target->name );
+ printf( "SEM: placing %s on stack\n", object_str( first->target->name ) );
push_state( &temp_stack, first->target, NULL, T_STATE_MAKE1B );
BJAM_FREE( first );
}
@@ -662,11 +692,11 @@ static void call_timing_rule( TARGET * target, timing_info * time )
{
LIST * timing_rule;
- pushsettings( target->settings );
- timing_rule = var_get( "__TIMING_RULE__" );
- popsettings( target->settings );
+ pushsettings( root_module(), target->settings );
+ timing_rule = var_get( root_module(), constant_TIMING_RULE );
+ popsettings( root_module(), target->settings );
- if ( timing_rule )
+ if ( !list_empty( timing_rule ) )
{
/* rule timing-rule ( args * : target : start end user system ) */
@@ -675,20 +705,20 @@ static void call_timing_rule( TARGET * target, timing_info * time )
frame_init( frame );
/* args * :: $(__TIMING_RULE__[2-]) */
- lol_add( frame->args, list_copy( L0, timing_rule->next ) );
+ lol_add( frame->args, list_copy_range( timing_rule, list_next( list_begin( timing_rule ) ), list_end( timing_rule ) ) );
/* target :: the name of the target */
- lol_add( frame->args, list_new( L0, target->name ) );
+ lol_add( frame->args, list_new( object_copy( target->name ) ) );
/* start end user system :: info about the action command */
- lol_add( frame->args, list_new( list_new( list_new( list_new( L0,
+ lol_add( frame->args, list_push_back( list_push_back( list_push_back( list_new(
outf_time ( time->start ) ),
outf_time ( time->end ) ),
outf_double( time->user ) ),
outf_double( time->system ) ) );
/* Call the rule. */
- evaluate_rule( timing_rule->string, frame );
+ evaluate_rule( list_front( timing_rule ), frame );
/* Clean up. */
frame_free( frame );
@@ -707,17 +737,17 @@ static void call_action_rule
TARGET * target,
int status,
timing_info * time,
- char * executed_command,
- char * command_output
+ const char * executed_command,
+ const char * command_output
)
{
- LIST * action_rule;
+ LIST * action_rule;
- pushsettings( target->settings );
- action_rule = var_get( "__ACTION_RULE__" );
- popsettings( target->settings );
+ pushsettings( root_module(), target->settings );
+ action_rule = var_get( root_module(), constant_ACTION_RULE );
+ popsettings( root_module(), target->settings );
- if ( action_rule )
+ if ( !list_empty( action_rule ) )
{
/* rule action-rule (
args * :
@@ -730,15 +760,15 @@ static void call_action_rule
frame_init( frame );
/* args * :: $(__ACTION_RULE__[2-]) */
- lol_add( frame->args, list_copy( L0, action_rule->next ) );
+ lol_add( frame->args, list_copy_range( action_rule, list_next( list_begin( action_rule ) ), list_end( action_rule ) ) );
/* target :: the name of the target */
- lol_add( frame->args, list_new( L0, target->name ) );
+ lol_add( frame->args, list_new( object_copy( target->name ) ) );
/* command status start end user system :: info about the action command */
lol_add( frame->args,
- list_new( list_new( list_new( list_new( list_new( list_new( L0,
- newstr( executed_command ) ),
+ list_push_back( list_push_back( list_push_back( list_push_back( list_push_back( list_new(
+ object_new( executed_command ) ),
outf_int( status ) ),
outf_time( time->start ) ),
outf_time( time->end ) ),
@@ -747,12 +777,12 @@ static void call_action_rule
/* output ? :: the output of the action command */
if ( command_output )
- lol_add( frame->args, list_new( L0, newstr( command_output ) ) );
+ lol_add( frame->args, list_new( object_new( command_output ) ) );
else
lol_add( frame->args, L0 );
/* Call the rule. */
- evaluate_rule( action_rule->string, frame );
+ evaluate_rule( list_front( action_rule ), frame );
/* Clean up. */
frame_free( frame );
@@ -770,8 +800,8 @@ static void make_closure
void * closure,
int status,
timing_info * time,
- char * executed_command,
- char * command_output
+ const char * executed_command,
+ const char * command_output
)
{
TARGET * built = (TARGET *)closure;
@@ -801,7 +831,7 @@ static void make1d( state * pState )
CMD * cmd = (CMD *)t->cmds;
int status = pState->status;
- if ( t->flags & T_FLAG_FAIL_EXPECTED )
+ if ( t->flags & T_FLAG_FAIL_EXPECTED && !globs.noexec )
{
/* Invert execution result when FAIL_EXPECTED has been applied. */
switch ( status )
@@ -823,9 +853,9 @@ static void make1d( state * pState )
if ( ( status == EXEC_CMD_FAIL ) && DEBUG_MAKE )
{
if ( !DEBUG_EXEC )
- printf( "%s\n", cmd->buf );
+ printf( "%s\n", cmd->buf->value );
- printf( "...failed %s ", cmd->rule->name );
+ printf( "...failed %s ", object_str( cmd->rule->name ) );
list_print( lol_get( &cmd->args, 0 ) );
printf( "...\n" );
}
@@ -842,16 +872,17 @@ static void make1d( state * pState )
if (status != EXEC_CMD_OK)
{
LIST * targets = lol_get( &cmd->args, 0 );
- for ( ; targets; targets = list_next( targets ) )
+ LISTITER iter = list_begin( targets ), end = list_end( targets );
+ for ( ; iter != end; iter = list_next( iter ) )
{
int need_unlink = 1;
- TARGET* t = bindtarget ( targets->string );
+ TARGET* t = bindtarget ( list_item( iter ) );
if (t->flags & T_FLAG_PRECIOUS)
{
need_unlink = 0;
}
- if (need_unlink && !unlink( targets->string ) )
- printf( "...removing %s\n", targets->string );
+ if (need_unlink && !unlink( object_str( list_item( iter ) ) ) )
+ printf( "...removing %s\n", object_str( list_item( iter ) ) );
}
}
@@ -878,29 +909,17 @@ static void swap_settings
TARGET * new_target
)
{
- if ( new_module == root_module() )
- new_module = 0;
-
if ( ( new_target == *current_target ) && ( new_module == *current_module ) )
return;
if ( *current_target )
- popsettings( (*current_target)->settings );
-
- if ( new_module != *current_module )
- {
- if ( *current_module )
- exit_module( *current_module );
+ popsettings( *current_module, (*current_target)->settings );
- *current_module = new_module;
-
- if ( new_module )
- enter_module( new_module );
- }
+ if ( new_target )
+ pushsettings( new_module, new_target->settings );
+ *current_module = new_module;
*current_target = new_target;
- if ( new_target )
- pushsettings( new_target->settings );
}
@@ -916,10 +935,11 @@ static void swap_settings
static CMD * make1cmds( TARGET * t )
{
CMD * cmds = 0;
- LIST * shell = 0;
+ LIST * shell = L0;
module_t * settings_module = 0;
TARGET * settings_target = 0;
ACTIONS * a0;
+ int running_flag = globs.noexec ? A_RUNNING_NOEXEC : A_RUNNING;
/* Step through actions. Actions may be shared with other targets or grouped
* using RULE_TOGETHER, so actions already seen are skipped.
@@ -939,10 +959,10 @@ static CMD * make1cmds( TARGET * t )
/* Only do rules with commands to execute. If this action has already
* been executed, use saved status.
*/
- if ( !actions || a0->action->running )
+ if ( !actions || a0->action->running >= running_flag )
continue;
- a0->action->running = 1;
+ a0->action->running = running_flag;
/* Make LISTS of targets and sources. If `execute together` has been
* specified for this rule, tack on sources from each instance of this
@@ -952,28 +972,30 @@ static CMD * make1cmds( TARGET * t )
ns = make1list( L0, a0->action->sources, actions->flags );
if ( actions->flags & RULE_TOGETHER )
for ( a1 = a0->next; a1; a1 = a1->next )
- if ( a1->action->rule == rule && !a1->action->running )
+ if ( a1->action->rule == rule && a1->action->running < running_flag )
{
ns = make1list( ns, a1->action->sources, actions->flags );
- a1->action->running = 1;
+ a1->action->running = running_flag;
}
/* If doing only updated (or existing) sources, but none have been
* updated (or exist), skip this action.
*/
- if ( !ns && ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) )
+ if ( list_empty( ns ) && ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) )
{
list_free( nt );
continue;
}
swap_settings( &settings_module, &settings_target, rule->module, t );
- if ( !shell )
- shell = var_get( "JAMSHELL" ); /* shell is per-target */
+ if ( list_empty( shell ) )
+ {
+ shell = var_get( rule->module, constant_JAMSHELL ); /* shell is per-target */
+ }
/* If we had 'actions xxx bind vars' we bind the vars now. */
- boundvars = make1settings( actions->bindlist );
- pushsettings( boundvars );
+ boundvars = make1settings( rule->module, actions->bindlist );
+ pushsettings( rule->module, boundvars );
/*
* Build command, starting with all source args.
@@ -998,9 +1020,9 @@ static CMD * make1cmds( TARGET * t )
{
/* Build cmd: cmd_new consumes its lists. */
CMD * cmd = cmd_new( rule,
- list_copy( L0, nt ),
+ list_copy( nt ),
list_sublist( ns, start, chunk ),
- list_copy( L0, shell ) );
+ list_copy( shell ) );
if ( cmd )
{
@@ -1018,14 +1040,14 @@ static CMD * make1cmds( TARGET * t )
else
{
/* Too long and not splittable. */
- printf( "%s actions too long (max %d):\n", rule->name, MAXLINE
+ printf( "%s actions too long (max %d):\n", object_str( rule->name ), MAXLINE
);
/* Tell the user what didn't fit. */
- cmd = cmd_new( rule, list_copy( L0, nt ),
+ cmd = cmd_new( rule, list_copy( nt ),
list_sublist( ns, start, chunk ),
- list_new( L0, newstr( "%" ) ) );
- fputs( cmd->buf, stdout );
+ list_new( object_copy( constant_percent ) ) );
+ fputs( cmd->buf->value, stdout );
exit( EXITBAD );
}
}
@@ -1038,7 +1060,7 @@ static CMD * make1cmds( TARGET * t )
/* Free the variables whose values were bound by 'actions xxx bind
* vars'.
*/
- popsettings( boundvars );
+ popsettings( rule->module, boundvars );
freesettings( boundvars );
}
@@ -1077,16 +1099,16 @@ static LIST * make1list( LIST * l, TARGETS * targets, int flags )
/* Prohibit duplicates for RULE_TOGETHER. */
if ( flags & RULE_TOGETHER )
{
- LIST * m;
- for ( m = l; m; m = m->next )
- if ( !strcmp( m->string, t->boundname ) )
+ LISTITER iter = list_begin( l ), end = list_end( l );
+ for ( ; iter != end; iter = list_next( iter ) )
+ if ( object_equal( list_item( iter ), t->boundname ) )
break;
- if ( m )
+ if ( iter != end )
continue;
}
/* Build new list. */
- l = list_new( l, copystr( t->boundname ) );
+ l = list_push_back( l, object_copy( t->boundname ) );
}
return l;
@@ -1097,29 +1119,31 @@ static LIST * make1list( LIST * l, TARGETS * targets, int flags )
* make1settings() - for vars that get bound values, build up replacement lists.
*/
-static SETTINGS * make1settings( LIST * vars )
+static SETTINGS * make1settings( struct module_t * module, LIST * vars )
{
SETTINGS * settings = 0;
- for ( ; vars; vars = list_next( vars ) )
+ LISTITER vars_iter = list_begin( vars ), vars_end = list_end( vars );
+ for ( ; vars_iter != vars_end; vars_iter = list_next( vars_iter ) )
{
- LIST * l = var_get( vars->string );
- LIST * nl = 0;
+ LIST * l = var_get( module, list_item( vars_iter ) );
+ LIST * nl = L0;
+ LISTITER iter = list_begin( l ), end = list_end( l );
- for ( ; l; l = list_next( l ) )
+ for ( ; iter != end; iter = list_next( iter ) )
{
- TARGET * t = bindtarget( l->string );
+ TARGET * t = bindtarget( list_item( iter ) );
/* Make sure the target is bound. */
if ( t->binding == T_BIND_UNBOUND )
make1bind( t );
/* Build a new list. */
- nl = list_new( nl, copystr( t->boundname ) );
+ nl = list_push_back( nl, object_copy( t->boundname ) );
}
/* Add to settings chain. */
- settings = addsettings( settings, VAR_SET, vars->string, nl );
+ settings = addsettings( settings, VAR_SET, list_item( vars_iter ), nl );
}
return settings;
@@ -1138,8 +1162,9 @@ static void make1bind( TARGET * t )
if ( t->flags & T_FLAG_NOTFILE )
return;
- pushsettings( t->settings );
+ pushsettings( root_module(), t->settings );
+ object_free( t->boundname );
t->boundname = search( t->name, &t->time, 0, ( t->flags & T_FLAG_ISFILE ) );
t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
- popsettings( t->settings );
+ popsettings( root_module(), t->settings );
}