11use std:: any:: { Any , type_name} ;
2- use std:: cell:: { Cell , RefCell } ;
2+ use std:: cell:: Cell ;
33use std:: collections:: BTreeSet ;
44use std:: fmt:: { self , Debug , Write } ;
55use std:: hash:: Hash ;
66use std:: ops:: Deref ;
77use std:: path:: { Path , PathBuf } ;
8- use std:: sync:: { LazyLock , OnceLock } ;
8+ use std:: sync:: { Arc , LazyLock , Mutex , OnceLock } ;
99use std:: time:: { Duration , Instant } ;
1010use std:: { env, fs} ;
1111
@@ -32,6 +32,25 @@ mod cargo;
3232#[ cfg( test) ]
3333mod tests;
3434
35+ type StepStack = Arc < Mutex < Vec < Box < dyn AnyDebug > > > > ;
36+
37+ /// Pointer to the active step stack of the currently executing `Builder`.
38+ static ACTIVE_BUILDER_STEP_STACK : Mutex < Option < StepStack > > = Mutex :: new ( None ) ;
39+
40+ /// Prints the current contents of the active builder's step stack.
41+ fn print_step_stack ( ) {
42+ if let Ok ( stack) = ACTIVE_BUILDER_STEP_STACK . try_lock ( )
43+ && let Some ( ref stack) = * stack
44+ && let Ok ( stack) = stack. try_lock ( )
45+ {
46+ eprintln ! ( "\n ---BOOTSTRAP step stack start---\n " ) ;
47+ for step in & * stack {
48+ eprintln ! ( "{step:?}" ) ;
49+ }
50+ eprintln ! ( "\n ---BOOTSTRAP step stack end---\n " ) ;
51+ }
52+ }
53+
3554/// Builds and performs different [`Self::kind`]s of stuff and actions, taking
3655/// into account build configuration from e.g. bootstrap.toml.
3756pub struct Builder < ' a > {
@@ -52,7 +71,7 @@ pub struct Builder<'a> {
5271
5372 /// A stack of [`Step`]s to run before we can run this builder. The output
5473 /// of steps is cached in [`Self::cache`].
55- stack : RefCell < Vec < Box < dyn AnyDebug > > > ,
74+ stack : StepStack ,
5675
5776 /// The total amount of time we spent running [`Step`]s in [`Self::stack`].
5877 time_spent_on_dependencies : Cell < Duration > ,
@@ -78,8 +97,8 @@ impl Deref for Builder<'_> {
7897/// type's [`Debug`] implementation.
7998///
8099/// (Trying to debug-print `dyn Any` results in the unhelpful `"Any { .. }"`.)
81- pub trait AnyDebug : Any + Debug { }
82- impl < T : Any + Debug > AnyDebug for T { }
100+ pub trait AnyDebug : Any + Debug + Send { }
101+ impl < T : Any + Debug + Send > AnyDebug for T { }
83102impl dyn AnyDebug {
84103 /// Equivalent to `<dyn Any>::downcast_ref`.
85104 fn downcast_ref < T : Any > ( & self ) -> Option < & T > {
@@ -89,7 +108,7 @@ impl dyn AnyDebug {
89108 // Feel free to add other `dyn Any` methods as necessary.
90109}
91110
92- pub trait Step : ' static + Clone + Debug + PartialEq + Eq + Hash {
111+ pub trait Step : ' static + Clone + Debug + PartialEq + Eq + Hash + Send {
93112 /// Result type of `Step::run`.
94113 type Output : Clone ;
95114
@@ -1265,12 +1284,20 @@ impl<'a> Builder<'a> {
12651284 }
12661285
12671286 fn new_internal ( build : & Build , kind : Kind , paths : Vec < PathBuf > ) -> Builder < ' _ > {
1287+ let stack = Arc :: new ( Mutex :: new ( Vec :: new ( ) ) ) ;
1288+
1289+ // Store the current step stack
1290+ * ACTIVE_BUILDER_STEP_STACK . lock ( ) . unwrap ( ) = Some ( stack. clone ( ) ) ;
1291+
1292+ // And configure `build_helper` to print it on exit
1293+ * build_helper:: util:: EXIT_CONTEXT . lock ( ) . unwrap ( ) = Some ( print_step_stack) ;
1294+
12681295 Builder {
12691296 build,
12701297 top_stage : build. config . stage ,
12711298 kind,
12721299 cache : Cache :: new ( ) ,
1273- stack : RefCell :: new ( Vec :: new ( ) ) ,
1300+ stack,
12741301 time_spent_on_dependencies : Cell :: new ( Duration :: new ( 0 , 0 ) ) ,
12751302 paths,
12761303 submodule_paths_cache : Default :: default ( ) ,
@@ -1673,9 +1700,9 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
16731700 /// Ensure that a given step is built, returning its output. This will
16741701 /// cache the step, so it is safe (and good!) to call this as often as
16751702 /// needed to ensure that all dependencies are built.
1676- pub fn ensure < S : Step > ( & ' a self , step : S ) -> S :: Output {
1703+ pub fn ensure < S : Step + Send > ( & ' a self , step : S ) -> S :: Output {
16771704 {
1678- let mut stack = self . stack . borrow_mut ( ) ;
1705+ let mut stack = self . stack . lock ( ) . unwrap ( ) ;
16791706 for stack_step in stack. iter ( ) {
16801707 // should skip
16811708 if stack_step. downcast_ref :: < S > ( ) . is_none_or ( |stack_step| * stack_step != step) {
@@ -1754,7 +1781,7 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
17541781 self . metrics . exit_step ( self ) ;
17551782
17561783 {
1757- let mut stack = self . stack . borrow_mut ( ) ;
1784+ let mut stack = self . stack . lock ( ) . unwrap ( ) ;
17581785 let cur_step = stack. pop ( ) . expect ( "step stack empty" ) ;
17591786 assert_eq ! ( cur_step. downcast_ref( ) , Some ( & step) ) ;
17601787 }
0 commit comments