From e7327a4d8666dd030e2b410daf97222878d35065 Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Mon, 31 Mar 2025 20:29:46 -0400 Subject: [PATCH 1/5] Make modules graph, densemap and depfile public for external tools --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 44411ce..761ef00 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,9 @@ pub mod canon; mod db; -mod densemap; -mod depfile; +pub mod densemap; +pub mod depfile; mod eval; -mod graph; +pub mod graph; mod hash; pub mod load; pub mod parse; From d34a26fc68760642e8a03afbaf924ee68b3a328b Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Mon, 31 Mar 2025 20:38:46 -0400 Subject: [PATCH 2/5] Refactor parse_showincludes as method on Build to expose value of deps on Build --- src/graph.rs | 17 +++++++++++++---- src/load.rs | 10 +++++----- src/task.rs | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index a5b23ae..149f1d1 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -155,12 +155,12 @@ pub struct Build { /// Command line to run. Absent for phony builds. pub cmdline: Option, + /// Controls how dependency information is processed after compilation. + pub deps: Option, + /// Path to generated `.d` file, if any. pub depfile: Option, - /// If true, extract "/showIncludes" lines from output. - pub parse_showincludes: bool, - // Struct that contains the path to the rsp file and its contents, if any. pub rspfile: Option, @@ -186,8 +186,8 @@ impl Build { location: loc, desc: None, cmdline: None, + deps: None, depfile: None, - parse_showincludes: false, rspfile: None, pool: None, ins, @@ -243,6 +243,15 @@ impl Build { pub fn outs(&self) -> &[FileId] { &self.outs.ids } + + /// If true, extract "/showIncludes" lines from output. + pub fn parse_showincludes(&self) -> bool { + match self.deps.as_deref() { + Some("msvc") => true, + _ => false, + } + } + } /// The build graph: owns Files/Builds and maps FileIds/BuildIds to them. diff --git a/src/load.rs b/src/load.rs index 4624c51..c67292d 100644 --- a/src/load.rs +++ b/src/load.rs @@ -140,10 +140,10 @@ impl Loader { let cmdline = lookup("command"); let desc = lookup("description"); let depfile = lookup("depfile"); - let parse_showincludes = match lookup("deps").as_deref() { - None => false, - Some("gcc") => false, - Some("msvc") => true, + let deps = match lookup("deps").as_deref() { + None => None, + Some("gcc") => Some("gcc".to_string()), + Some("msvc") => Some("msvc".to_string()), Some(other) => bail!("invalid deps attribute {:?}", other), }; let pool = lookup("pool"); @@ -164,7 +164,7 @@ impl Loader { build.cmdline = cmdline; build.desc = desc; build.depfile = depfile; - build.parse_showincludes = parse_showincludes; + build.deps = deps; build.rspfile = rspfile; build.pool = pool; build.hide_success = hide_success; diff --git a/src/task.rs b/src/task.rs index bf4e816..c67eecd 100644 --- a/src/task.rs +++ b/src/task.rs @@ -214,7 +214,7 @@ impl Runner { let cmdline = build.cmdline.clone().unwrap(); let depfile = build.depfile.clone().map(PathBuf::from); let rspfile = build.rspfile.clone(); - let parse_showincludes = build.parse_showincludes; + let parse_showincludes = build.parse_showincludes(); let hide_progress = build.hide_progress; let tid = self.tids.claim(); From 2d1d1377c5fa15fccfe35e2342442a196b6a9fda Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Mon, 31 Mar 2025 21:01:01 -0400 Subject: [PATCH 3/5] Refactor graph::Build ins & outs to BuildDependencies and derive Clone --- src/graph.rs | 121 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 75 insertions(+), 46 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index 149f1d1..ed8252f 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -6,9 +6,12 @@ use crate::{ densemap::{self, DenseMap}, hash::BuildHash, }; -use std::collections::{hash_map::Entry, HashMap}; use std::path::{Path, PathBuf}; use std::time::SystemTime; +use std::{ + collections::{hash_map::Entry, HashMap}, + ops::{Deref, DerefMut}, +}; /// Id for File nodes in the Graph. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -74,6 +77,7 @@ pub struct RspFile { } /// Input files to a Build. +#[derive(Clone)] pub struct BuildIns { /// Internally we stuff explicit/implicit/order-only ins all into one Vec. /// This is mostly to simplify some of the iteration and is a little more @@ -88,6 +92,7 @@ pub struct BuildIns { } /// Output files from a Build. +#[derive(Clone)] pub struct BuildOuts { /// Similar to ins, we keep both explicit and implicit outs in one Vec. pub ids: Vec, @@ -144,29 +149,9 @@ mod tests { } } -/// A single build action, generating File outputs from File inputs with a command. -pub struct Build { - /// Source location this Build was declared. - pub location: FileLoc, - - /// User-provided description of the build step. - pub desc: Option, - - /// Command line to run. Absent for phony builds. - pub cmdline: Option, - - /// Controls how dependency information is processed after compilation. - pub deps: Option, - - /// Path to generated `.d` file, if any. - pub depfile: Option, - - // Struct that contains the path to the rsp file and its contents, if any. - pub rspfile: Option, - - /// Pool to execute this build in, if any. - pub pool: Option, - +#[derive(Clone)] +pub struct BuildDependencies { + /// Input files. pub ins: BuildIns, /// Additional inputs discovered from a previous build. @@ -174,30 +159,9 @@ pub struct Build { /// Output files. pub outs: BuildOuts, - - /// True if output of command should be hidden on successful completion. - pub hide_success: bool, - /// True if last line of output should not be shown in status. - pub hide_progress: bool, } -impl Build { - pub fn new(loc: FileLoc, ins: BuildIns, outs: BuildOuts) -> Self { - Build { - location: loc, - desc: None, - cmdline: None, - deps: None, - depfile: None, - rspfile: None, - pool: None, - ins, - discovered_ins: Vec::new(), - outs, - hide_success: false, - hide_progress: false, - } - } +impl BuildDependencies { /// Input paths that appear in `$in`. pub fn explicit_ins(&self) -> &[FileId] { &self.ins.ids[0..self.ins.explicit] @@ -243,6 +207,58 @@ impl Build { pub fn outs(&self) -> &[FileId] { &self.outs.ids } +} + +/// A single build action, generating File outputs from File inputs with a command. +pub struct Build { + /// Source location this Build was declared. + pub location: FileLoc, + + /// Inputs and outputs for this build. + pub dependencies: BuildDependencies, + + /// User-provided description of the build step. + pub desc: Option, + + /// Command line to run. Absent for phony builds. + pub cmdline: Option, + + /// Controls how dependency information is processed after compilation. + pub deps: Option, + + /// Path to generated `.d` file, if any. + pub depfile: Option, + + // Struct that contains the path to the rsp file and its contents, if any. + pub rspfile: Option, + + /// Pool to execute this build in, if any. + pub pool: Option, + + /// True if output of command should be hidden on successful completion. + pub hide_success: bool, + /// True if last line of output should not be shown in status. + pub hide_progress: bool, +} +impl Build { + pub fn new(loc: FileLoc, ins: BuildIns, outs: BuildOuts) -> Self { + Build { + location: loc, + dependencies: BuildDependencies { + ins, + discovered_ins: Vec::new(), + outs, + }, + desc: None, + cmdline: None, + deps: None, + depfile: None, + rspfile: None, + pool: None, + hide_success: false, + hide_progress: false, + } + } /// If true, extract "/showIncludes" lines from output. pub fn parse_showincludes(&self) -> bool { @@ -251,7 +267,20 @@ impl Build { _ => false, } } +} +impl Deref for Build { + type Target = BuildDependencies; + + fn deref(&self) -> &Self::Target { + &self.dependencies + } +} + +impl DerefMut for Build { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.dependencies + } } /// The build graph: owns Files/Builds and maps FileIds/BuildIds to them. From 328d70366f92573a82ded44f9d1535f753b532fc Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Mon, 31 Mar 2025 21:10:23 -0400 Subject: [PATCH 4/5] Derive Clone on graph::File --- src/graph.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graph.rs b/src/graph.rs index ed8252f..650f219 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -42,7 +42,7 @@ impl From for BuildId { } /// A single file referenced as part of a build. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct File { /// Canonical path to the file. pub name: String, From 341b5112f69bd77a4345a0855fafd14a73d2689a Mon Sep 17 00:00:00 2001 From: Edgar Lee Date: Mon, 31 Mar 2025 21:12:35 -0400 Subject: [PATCH 5/5] Move all_ids implementation into DenseMap --- src/densemap.rs | 4 ++++ src/graph.rs | 4 ---- src/work.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/densemap.rs b/src/densemap.rs index 2d9878e..a099a0a 100644 --- a/src/densemap.rs +++ b/src/densemap.rs @@ -50,6 +50,10 @@ impl DenseMap { self.vec.push(val); id } + + pub fn all_ids(&self) -> impl Iterator { + (0..self.vec.len()).map(|id| K::from(id)) + } } impl DenseMap { diff --git a/src/graph.rs b/src/graph.rs index 650f219..5f7a1c2 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -368,10 +368,6 @@ impl GraphFiles { } } } - - pub fn all_ids(&self) -> impl Iterator { - (0..self.by_id.next_id().0).map(|id| FileId(id)) - } } /// MTime info gathered for a file. This also models "file is absent". diff --git a/src/work.rs b/src/work.rs index 9b618a6..4e8903e 100644 --- a/src/work.rs +++ b/src/work.rs @@ -383,7 +383,7 @@ impl<'a> Work<'a> { } pub fn want_every_file(&mut self, exclude: Option) -> anyhow::Result<()> { - for id in self.graph.files.all_ids() { + for id in self.graph.files.by_id.all_ids() { if let Some(exclude) = exclude { if id == exclude { continue;