|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r78249 - in trunk/tools/build/v2: engine test
From: steven_at_[hidden]
Date: 2012-04-28 18:05:29
Author: steven_watanabe
Date: 2012-04-28 18:05:28 EDT (Sat, 28 Apr 2012)
New Revision: 78249
URL: http://svn.boost.org/trac/boost/changeset/78249
Log:
Detect cycles created by rescanning.
Text files modified:
trunk/tools/build/v2/engine/make1.c | 60 ++++++++++++++++++++++++++++++++++++++-
trunk/tools/build/v2/engine/rules.h | 2 +
trunk/tools/build/v2/test/rescan_header.py | 56 ++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 3 deletions(-)
Modified: trunk/tools/build/v2/engine/make1.c
==============================================================================
--- trunk/tools/build/v2/engine/make1.c (original)
+++ trunk/tools/build/v2/engine/make1.c 2012-04-28 18:05:28 EDT (Sat, 28 Apr 2012)
@@ -74,6 +74,7 @@
static LIST * make1list ( LIST *, TARGETS *, int flags );
static SETTINGS * make1settings( struct module_t * module, LIST * vars );
static void make1bind ( TARGET * );
+static int make1findcycle( TARGET * t );
/* Ugly static - it is too hard to carry it through the callbacks. */
@@ -85,6 +86,8 @@
int made;
} counts[ 1 ] ;
+int handling_rescan;
+
/* Target state - remove recursive calls by just keeping track of state target
* is in.
*/
@@ -97,7 +100,8 @@
#define T_STATE_MAKE1ATAIL 1 /* make1atail() should be called */
#define T_STATE_MAKE1B 2 /* make1b() should be called */
#define T_STATE_MAKE1C 3 /* make1c() should be called */
-#define T_STATE_MAKE1D 4 /* make1d() should be called */
+#define T_STATE_MAKE1CTAIL 4 /* make1ctail() should be called */
+#define T_STATE_MAKE1D 5 /* make1d() should be called */
int curstate; /* current state */
int status;
} state;
@@ -106,6 +110,7 @@
static void make1atail ( state * );
static void make1b ( state * );
static void make1c ( state * );
+static void make1ctail ( state * );
static void make1d ( state * );
static void make_closure( void * closure, int status, timing_info *, const char *, const char * );
@@ -227,6 +232,7 @@
case T_STATE_MAKE1ATAIL: make1atail( pState ); break;
case T_STATE_MAKE1B : make1b ( pState ); break;
case T_STATE_MAKE1C : make1c ( pState ); break;
+ case T_STATE_MAKE1CTAIL: make1ctail( pState ); break;
case T_STATE_MAKE1D : make1d ( pState ); break;
}
}
@@ -273,8 +279,9 @@
if ( pState->parent )
switch ( pState->t->progress )
{
- case T_MAKE_INIT:
case T_MAKE_ACTIVE:
+ if ( handling_rescan && make1findcycle( t ) ) break;
+ case T_MAKE_INIT:
case T_MAKE_RUNNING:
pState->t->parents = targetentry( pState->t->parents,
pState->parent );
@@ -632,8 +639,12 @@
}
if ( additional_includes )
+ {
+ ++handling_rescan;
for ( c = t->parents; c; c = c->next )
push_state( &temp_stack, additional_includes, c->target, T_STATE_MAKE1A );
+ push_state( &temp_stack, additional_includes, NULL, T_STATE_MAKE1CTAIL );
+ }
for ( c = t->parents; c; c = c->next )
push_state( &temp_stack, c->target, NULL, T_STATE_MAKE1B );
@@ -676,6 +687,12 @@
}
}
+static void make1ctail( state * pState )
+{
+ --handling_rescan;
+ pop_state( &state_stack );
+}
+
/*
* call_timing_rule() - Look up the __TIMING_RULE__ variable on the given
@@ -1163,3 +1180,42 @@
t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
popsettings( root_module(), t->settings );
}
+
+
+static int make1findcycle_impl( TARGET * t )
+{
+ TARGETS * c;
+
+ if ( t->progress == T_MAKE_ONSTACK )
+ return 1;
+ else if ( t->progress != T_MAKE_ACTIVE )
+ return 0;
+
+ t->progress = T_MAKE_FINDCYCLE;
+
+ for ( c = t->depends; c; c = c->next )
+ if ( make1findcycle_impl( c->target ) )
+ return 1;
+
+ return 0;
+}
+
+static void make1findcycle_cleanup( TARGET * t )
+{
+ TARGETS * c;
+
+ if ( t->progress != T_MAKE_FINDCYCLE )
+ return;
+
+ t->progress = T_MAKE_ACTIVE;
+
+ for ( c = t->depends; c; c = c->next )
+ make1findcycle_cleanup( c->target );
+}
+
+static int make1findcycle( TARGET * t )
+{
+ int result = make1findcycle_impl( t );
+ make1findcycle_cleanup( t );
+ return result;
+}
Modified: trunk/tools/build/v2/engine/rules.h
==============================================================================
--- trunk/tools/build/v2/engine/rules.h (original)
+++ trunk/tools/build/v2/engine/rules.h 2012-04-28 18:05:28 EDT (Sat, 28 Apr 2012)
@@ -212,6 +212,8 @@
#define T_MAKE_RUNNING 3 /* make1(target) running commands */
#define T_MAKE_DONE 4 /* make1(target) done */
#define T_MAKE_NOEXEC_DONE 5 /* make1(target) done with -n in effect */
+#define T_MAKE_FINDCYCLE 6 /* make1(target) searching for cyclic includes after
+ rescanning a generated file. */
#ifdef OPT_SEMAPHORE
#define T_MAKE_SEMAPHORE 5 /* Special target type for semaphores */
Modified: trunk/tools/build/v2/test/rescan_header.py
==============================================================================
--- trunk/tools/build/v2/test/rescan_header.py (original)
+++ trunk/tools/build/v2/test/rescan_header.py 2012-04-28 18:05:28 EDT (Sat, 28 Apr 2012)
@@ -82,7 +82,7 @@
make header1.h : header1.in : @common.copy ;
make header2.h : header2.in : @common.copy ;
-make header3.h : header2.in : @common.copy ;
+make header3.h : header3.in : @common.copy ;
obj test : test.cpp :
<implicit-dependency>header1.h
<implicit-dependency>header2.h
@@ -97,4 +97,58 @@
t.expect_addition("bin/$toolset/debug/test.obj")
t.expect_nothing_more()
+t.rm(".")
+
+# Test a loop in generated headers.
+t.write("test.cpp", """
+#include "header1.h"
+""")
+
+t.write("header1.in", """
+#ifndef HEADER1_H
+#define HEADER1_H
+#include "header2.h"
+#endif
+""")
+
+t.write("header2.in", """
+#ifndef HEADER2_H
+#define HEADER2_H
+#include "header3.h"
+#endif
+""")
+
+t.write("header3.in", """
+#ifndef HEADER2_H
+#define HEADER2_H
+#include "header1.h"
+#endif
+""")
+
+t.write("Jamroot.jam", """
+import common ;
+
+actions copy {
+ sleep 1
+ cp $(>) $(<)
+}
+
+make header1.h : header1.in : @common.copy ;
+make header2.h : header2.in : @common.copy ;
+make header3.h : header3.in : @common.copy ;
+obj test : test.cpp :
+ <implicit-dependency>header1.h
+ <implicit-dependency>header2.h
+ <implicit-dependency>header3.h
+ ;
+""")
+
+t.run_build_system("-j2 test")
+t.expect_addition("bin/$toolset/debug/header1.h")
+t.expect_addition("bin/$toolset/debug/header2.h")
+t.expect_addition("bin/$toolset/debug/header3.h")
+t.expect_addition("bin/$toolset/debug/test.obj")
+t.expect_nothing_more()
+
+
t.cleanup()
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk