about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2018-03-27 12:44:33 +0200
committerMark Simulacrum <mark.simulacrum@gmail.com>2018-04-03 11:43:12 -0600
commitb0dbc7c15d4f3027410b3836154da1ae63e0a7d3 (patch)
tree3cb21d315f0ef395fc0005beaf61b16c275e5cb2 /src/bootstrap
parentf4620a3d1471fd7943ebd413dcbc94d51bcfea8e (diff)
downloadrust-b0dbc7c15d4f3027410b3836154da1ae63e0a7d3.tar.gz
rust-b0dbc7c15d4f3027410b3836154da1ae63e0a7d3.zip
Implement generating graphs of the build steps
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/builder.rs40
-rw-r--r--src/bootstrap/lib.rs9
3 files changed, 46 insertions, 4 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index c09a3d86523..2f9c4e148a6 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -42,6 +42,7 @@ serde_json = "1.0.2"
 toml = "0.4"
 lazy_static = "0.2"
 time = "0.1"
+petgraph = "0.4.12"
 
 [dev-dependencies]
 pretty_assertions = "0.5"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 49d4864190a..86a51c8e26b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -19,6 +19,7 @@ use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::time::{Instant, Duration};
+use std::collections::HashMap;
 
 use compile;
 use install;
@@ -35,6 +36,9 @@ use native;
 
 pub use Compiler;
 
+use petgraph::Graph;
+use petgraph::graph::NodeIndex;
+
 pub struct Builder<'a> {
     pub build: &'a Build,
     pub top_stage: u32,
@@ -43,6 +47,9 @@ pub struct Builder<'a> {
     stack: RefCell<Vec<Box<Any>>>,
     time_spent_on_dependencies: Cell<Duration>,
     pub paths: Vec<PathBuf>,
+    graph_nodes: RefCell<HashMap<String, NodeIndex>>,
+    graph: RefCell<Graph<String, bool>>,
+    parent: Cell<Option<NodeIndex>>,
 }
 
 impl<'a> Deref for Builder<'a> {
@@ -353,6 +360,9 @@ impl<'a> Builder<'a> {
             stack: RefCell::new(Vec::new()),
             time_spent_on_dependencies: Cell::new(Duration::new(0, 0)),
             paths: vec![],
+            graph_nodes: RefCell::new(HashMap::new()),
+            graph: RefCell::new(Graph::new()),
+            parent: Cell::new(None),
         };
 
         let builder = &builder;
@@ -389,6 +399,9 @@ impl<'a> Builder<'a> {
             stack: RefCell::new(Vec::new()),
             time_spent_on_dependencies: Cell::new(Duration::new(0, 0)),
             paths: paths.to_owned(),
+            graph_nodes: RefCell::new(HashMap::new()),
+            graph: RefCell::new(Graph::new()),
+            parent: Cell::new(None),
         };
 
         if kind == Kind::Dist {
@@ -833,12 +846,37 @@ impl<'a> Builder<'a> {
             if let Some(out) = self.cache.get(&step) {
                 self.build.verbose(&format!("{}c {:?}", "  ".repeat(stack.len()), step));
 
+                {
+                    let mut graph = self.graph.borrow_mut();
+                    let parent = self.parent.get();
+                    let us = *self.graph_nodes.borrow_mut()
+                        .entry(format!("{:?}", step))
+                        .or_insert_with(|| graph.add_node(format!("{:?}", step)));
+                    if let Some(parent) = parent {
+                        graph.add_edge(parent, us, false);
+                    }
+                }
+
                 return out;
             }
             self.build.verbose(&format!("{}> {:?}", "  ".repeat(stack.len()), step));
             stack.push(Box::new(step.clone()));
         }
 
+        let prev_parent = self.parent.get();
+
+        {
+            let mut graph = self.graph.borrow_mut();
+            let parent = self.parent.get();
+            let us = *self.graph_nodes.borrow_mut()
+                .entry(format!("{:?}", step))
+                .or_insert_with(|| graph.add_node(format!("{:?}", step)));
+            self.parent.set(Some(us));
+            if let Some(parent) = parent {
+                graph.add_edge(parent, us, true);
+            }
+        }
+
         let (out, dur) = {
             let start = Instant::now();
             let zero = Duration::new(0, 0);
@@ -849,6 +887,8 @@ impl<'a> Builder<'a> {
             (out, dur - deps)
         };
 
+        self.parent.set(prev_parent);
+
         if self.build.config.print_step_timings && dur > Duration::from_millis(100) {
             println!("[TIMING] {:?} -- {}.{:03}",
                      step,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index fca265fe41c..5b13fa27fbf 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -131,6 +131,7 @@ extern crate getopts;
 extern crate num_cpus;
 extern crate toml;
 extern crate time;
+extern crate petgraph;
 
 #[cfg(test)]
 #[macro_use]
@@ -600,14 +601,14 @@ impl Build {
 
     /// Runs a command, printing out nice contextual information if it fails.
     fn run(&self, cmd: &mut Command) {
-        if cfg!(test) { return; }
+        if self.config.dry_run { return; }
         self.verbose(&format!("running: {:?}", cmd));
         run_silent(cmd)
     }
 
     /// Runs a command, printing out nice contextual information if it fails.
     fn run_quiet(&self, cmd: &mut Command) {
-        if cfg!(test) { return; }
+        if self.config.dry_run { return; }
         self.verbose(&format!("running: {:?}", cmd));
         run_suppressed(cmd)
     }
@@ -616,7 +617,7 @@ impl Build {
     /// Exits if the command failed to execute at all, otherwise returns its
     /// `status.success()`.
     fn try_run(&self, cmd: &mut Command) -> bool {
-        if cfg!(test) { return true; }
+        if self.config.dry_run { return true; }
         self.verbose(&format!("running: {:?}", cmd));
         try_run_silent(cmd)
     }
@@ -625,7 +626,7 @@ impl Build {
     /// Exits if the command failed to execute at all, otherwise returns its
     /// `status.success()`.
     fn try_run_quiet(&self, cmd: &mut Command) -> bool {
-        if cfg!(test) { return true; }
+        if self.config.dry_run { return true; }
         self.verbose(&format!("running: {:?}", cmd));
         try_run_suppressed(cmd)
     }