2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-12 12:02:24 +00:00

More correct behavior of -n with FAIL_EXPECTED targets and across multiple calls to UPDATE_NOW.

[SVN r76045]
This commit is contained in:
Steven Watanabe
2011-12-18 16:51:43 +00:00
parent c992a83af5
commit 3fd7ecbccd
6 changed files with 244 additions and 14 deletions

View File

@@ -126,7 +126,11 @@ int make( int n_targets, OBJECT * * targets, int anyhow )
{
PROFILE_ENTER( MAKE_MAKE0 );
for ( i = 0; i < n_targets; ++i )
make0( bindtarget( targets[ i ] ), 0, 0, counts, anyhow );
{
TARGET * t = bindtarget( targets[ i ] );
if ( t->fate == T_FATE_INIT )
make0( t, 0, 0, counts, anyhow );
}
PROFILE_EXIT( MAKE_MAKE0 );
}

View File

@@ -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.
*/
@@ -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.
*/
@@ -560,7 +577,10 @@ 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 ) &&
@@ -811,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 )
@@ -918,6 +938,7 @@ static CMD * make1cmds( TARGET * t )
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.
@@ -937,10 +958,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
@@ -950,10 +971,10 @@ 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

View File

@@ -110,6 +110,9 @@ struct _action
TARGETS * targets;
TARGETS * sources; /* aka $(>) */
char running; /* has been started */
#define A_INIT 0
#define A_RUNNING_NOEXEC 1
#define A_RUNNING 2
char status; /* see TARGET status */
int refs;
};

View File

@@ -25,6 +25,7 @@ echo [$(<:B)] 2
NOTFILE subtest ;
.a. subtest_a : subtest ;
.a. subtest_b : subtest ;
FAIL_EXPECTED subtest_b ;
DEPENDS all : subtest_a subtest_b ;
""")
@@ -45,4 +46,6 @@ echo [subtest_b] 2
...updated 2 targets...
""")
t.expect_nothing_more()
t.cleanup()

198
test/core_update_now.py Executable file
View File

@@ -0,0 +1,198 @@
#!/usr/bin/python
# Copyright 2011 Steven Watanabe
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
import BoostBuild
import os
def basic():
# Basic test
t = BoostBuild.Tester(pass_toolset=0, pass_d0=False)
t.write("file.jam", """
actions do-print
{
echo updating $(<)
}
NOTFILE target1 ;
ALWAYS target1 ;
do-print target1 ;
UPDATE_NOW target1 ;
DEPENDS all : target1 ;
""")
t.run_build_system("-ffile.jam", stdout="""...found 1 target...
...updating 1 target...
do-print target1
updating target1
...updated 1 target...
...found 1 target...
""")
t.cleanup()
def ignore_minus_n():
# ignore-minus-n
t = BoostBuild.Tester(pass_toolset=0, pass_d0=False)
t.write("file.jam", """
actions do-print
{
echo updating $(<)
}
NOTFILE target1 ;
ALWAYS target1 ;
do-print target1 ;
UPDATE_NOW target1 : : ignore-minus-n ;
DEPENDS all : target1 ;
""")
t.run_build_system("-ffile.jam -n", stdout="""...found 1 target...
...updating 1 target...
do-print target1
echo updating target1
updating target1
...updated 1 target...
...found 1 target...
""")
t.cleanup()
def failed_target():
t = BoostBuild.Tester(pass_toolset=0, pass_d0=False)
t.write("file.jam", """
actions fail
{
exit 1
}
NOTFILE target1 ;
ALWAYS target1 ;
fail target1 ;
actions do-print
{
echo updating $(<)
}
NOTFILE target2 ;
do-print target2 ;
DEPENDS target2 : target1 ;
UPDATE_NOW target1 : : ignore-minus-n ;
DEPENDS all : target1 target2 ;
""")
t.run_build_system("-ffile.jam -n", stdout="""...found 1 target...
...updating 1 target...
fail target1
exit 1
...failed fail target1...
...failed updating 1 target...
...found 2 targets...
...updating 1 target...
do-print target2
echo updating target2
...updated 1 target...
""")
t.cleanup()
def missing_target():
t = BoostBuild.Tester(pass_toolset=0, pass_d0=False)
t.write("file.jam", """
actions do-print
{
echo updating $(<)
}
NOTFILE target2 ;
do-print target2 ;
DEPENDS target2 : target1 ;
UPDATE_NOW target1 : : ignore-minus-n ;
DEPENDS all : target1 target2 ;
""")
t.run_build_system("-ffile.jam -n", status=1, stdout="""don't know how to make target1
...found 1 target...
...can't find 1 target...
...found 2 targets...
...can't make 1 target...
""")
t.cleanup()
# Make sure that if we call UPDATE_NOW with ignore-minus-n,
# the target gets updated exactly once regardless of previous
# calls to UPDATE_NOW with -n in effect.
def build_once():
t = BoostBuild.Tester(pass_toolset=0, pass_d0=False)
t.write("file.jam", """
actions do-print
{
echo updating $(<)
}
NOTFILE target1 ;
ALWAYS target1 ;
do-print target1 ;
UPDATE_NOW target1 ;
UPDATE_NOW target1 : : ignore-minus-n ;
UPDATE_NOW target1 : : ignore-minus-n ;
DEPENDS all : target1 ;
""")
t.run_build_system("-ffile.jam -n", stdout="""...found 1 target...
...updating 1 target...
do-print target1
echo updating target1
...updated 1 target...
do-print target1
echo updating target1
updating target1
...updated 1 target...
...found 1 target...
""")
t.cleanup()
basic()
ignore_minus_n()
failed_target()
missing_target()
build_once()

View File

@@ -151,6 +151,7 @@ tests = [ "absolute_sources",
"core_parallel_actions",
"core_parallel_multifile_actions_1",
"core_parallel_multifile_actions_2",
"core_update_now",
"custom_generator",
"default_build",
"default_features",