about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Beránek <berykubik@gmail.com>2025-08-10 21:13:50 +0200
committerJakub Beránek <berykubik@gmail.com>2025-08-11 18:21:06 +0200
commite6dddcb8ec095dc520be16f7c45b91de8c55b10a (patch)
treeab51ee2d8e0344d6dbe8a6be9817c842cfc72d00
parent577166503aee7290e09374da21f4045c455acfd5 (diff)
downloadrust-e6dddcb8ec095dc520be16f7c45b91de8c55b10a.tar.gz
rust-e6dddcb8ec095dc520be16f7c45b91de8c55b10a.zip
Store bootstrap tracing outputs to a unified directory
-rw-r--r--src/bootstrap/src/bin/main.rs25
-rw-r--r--src/bootstrap/src/lib.rs8
-rw-r--r--src/bootstrap/src/utils/exec.rs19
-rw-r--r--src/bootstrap/src/utils/step_graph.rs10
4 files changed, 34 insertions, 28 deletions
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index cf24fedaebb..70db6fad0f6 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -18,10 +18,14 @@ use bootstrap::{
 #[cfg(feature = "tracing")]
 use tracing::instrument;
 
-fn is_bootstrap_profiling_enabled() -> bool {
+fn is_profiling_enabled() -> bool {
     env::var("BOOTSTRAP_PROFILE").is_ok_and(|v| v == "1")
 }
 
+fn is_tracing_enabled() -> bool {
+    is_profiling_enabled() || cfg!(feature = "tracing")
+}
+
 #[cfg_attr(feature = "tracing", instrument(level = "trace", name = "main"))]
 fn main() {
     #[cfg(feature = "tracing")]
@@ -102,6 +106,13 @@ fn main() {
     let dump_bootstrap_shims = config.dump_bootstrap_shims;
     let out_dir = config.out.clone();
 
+    let tracing_enabled = is_tracing_enabled();
+    let tracing_dir = out_dir.join("bootstrap-trace").join(std::process::id().to_string());
+    if tracing_enabled {
+        let _ = std::fs::remove_dir_all(&tracing_dir);
+        std::fs::create_dir_all(&tracing_dir).unwrap();
+    }
+
     debug!("creating new build based on config");
     let mut build = Build::new(config);
     build.build();
@@ -156,12 +167,16 @@ fn main() {
         }
     }
 
-    if is_bootstrap_profiling_enabled() {
-        build.report_summary(start_time);
+    if is_profiling_enabled() {
+        build.report_summary(&tracing_dir.join("command-stats.txt"), start_time);
     }
 
     #[cfg(feature = "tracing")]
-    build.report_step_graph();
+    build.report_step_graph(&tracing_dir);
+
+    if tracing_enabled {
+        eprintln!("Tracing/profiling output has been written to {}", tracing_dir.display());
+    }
 }
 
 fn check_version(config: &Config) -> Option<String> {
@@ -241,7 +256,7 @@ fn setup_tracing() -> impl Drop {
     let mut chrome_layer = tracing_chrome::ChromeLayerBuilder::new().include_args(true);
 
     // Writes the Chrome profile to trace-<unix-timestamp>.json if enabled
-    if !is_bootstrap_profiling_enabled() {
+    if !is_profiling_enabled() {
         chrome_layer = chrome_layer.writer(io::sink());
     }
 
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 4abf386e5de..b02c1081a74 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -2016,13 +2016,13 @@ to download LLVM rather than building it.
         &self.config.exec_ctx
     }
 
-    pub fn report_summary(&self, start_time: Instant) {
-        self.config.exec_ctx.profiler().report_summary(start_time);
+    pub fn report_summary(&self, path: &Path, start_time: Instant) {
+        self.config.exec_ctx.profiler().report_summary(path, start_time);
     }
 
     #[cfg(feature = "tracing")]
-    pub fn report_step_graph(self) {
-        self.step_graph.into_inner().store_to_dot_files();
+    pub fn report_step_graph(self, directory: &Path) {
+        self.step_graph.into_inner().store_to_dot_files(directory);
     }
 }
 
diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs
index 03760faec69..ff79a176552 100644
--- a/src/bootstrap/src/utils/exec.rs
+++ b/src/bootstrap/src/utils/exec.rs
@@ -15,7 +15,6 @@ use std::hash::Hash;
 use std::io::{BufWriter, Write};
 use std::panic::Location;
 use std::path::Path;
-use std::process;
 use std::process::{
     Child, ChildStderr, ChildStdout, Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio,
 };
@@ -26,10 +25,10 @@ use build_helper::ci::CiEnv;
 use build_helper::drop_bomb::DropBomb;
 use build_helper::exit;
 
-use crate::PathBuf;
 use crate::core::config::DryRun;
 #[cfg(feature = "tracing")]
 use crate::trace_cmd;
+use crate::{PathBuf, t};
 
 /// What should be done when the command fails.
 #[derive(Debug, Copy, Clone)]
@@ -121,17 +120,9 @@ impl CommandProfiler {
         entry.traces.push(ExecutionTrace::CacheHit);
     }
 
-    pub fn report_summary(&self, start_time: Instant) {
-        let pid = process::id();
-        let filename = format!("bootstrap-profile-{pid}.txt");
-
-        let file = match File::create(&filename) {
-            Ok(f) => f,
-            Err(e) => {
-                eprintln!("Failed to create profiler output file: {e}");
-                return;
-            }
-        };
+    /// Report summary of executed commands file at the specified `path`.
+    pub fn report_summary(&self, path: &Path, start_time: Instant) {
+        let file = t!(File::create(path));
 
         let mut writer = BufWriter::new(file);
         let stats = self.stats.lock().unwrap();
@@ -221,8 +212,6 @@ impl CommandProfiler {
         writeln!(writer, "Total cache hits: {total_cache_hits}").unwrap();
         writeln!(writer, "Estimated time saved due to cache hits: {total_saved_duration:.2?}")
             .unwrap();
-
-        println!("Command profiler report saved to {filename}");
     }
 }
 
diff --git a/src/bootstrap/src/utils/step_graph.rs b/src/bootstrap/src/utils/step_graph.rs
index c45825a4222..30a7853b816 100644
--- a/src/bootstrap/src/utils/step_graph.rs
+++ b/src/bootstrap/src/utils/step_graph.rs
@@ -1,8 +1,10 @@
 use std::collections::{HashMap, HashSet};
 use std::fmt::Debug;
 use std::io::BufWriter;
+use std::path::Path;
 
 use crate::core::builder::{AnyDebug, Step};
+use crate::t;
 
 /// Records the executed steps and their dependencies in a directed graph,
 /// which can then be rendered into a DOT file for visualization.
@@ -80,10 +82,10 @@ impl StepGraph {
         }
     }
 
-    pub fn store_to_dot_files(self) {
+    pub fn store_to_dot_files(self, directory: &Path) {
         for (key, graph) in self.graphs.into_iter() {
-            let filename = format!("bootstrap-steps{key}.dot");
-            graph.render(&filename).unwrap();
+            let filename = directory.join(format!("step-graph{key}.dot"));
+            t!(graph.render(&filename));
         }
     }
 }
@@ -147,7 +149,7 @@ impl DotGraph {
         self.key_to_index.get(key).copied()
     }
 
-    fn render(&self, path: &str) -> std::io::Result<()> {
+    fn render(&self, path: &Path) -> std::io::Result<()> {
         use std::io::Write;
 
         let mut file = BufWriter::new(std::fs::File::create(path)?);