-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #7977 - ehuss:unit-graph, r=alexcrichton
Add unit-graph JSON output. This adds a `--unit-graph` flag that will emit a JSON object of Cargo's internal build graph. See unstable.md for more details. The primary motivator is to provide an accurate picture of which features are set. With the new feature resolver it is not possible to properly represent the features in the `cargo metadata` structure, because features are no longer unified. Also, features selected depend on the command, and exactly which packages are being built. To handle that in `cargo metadata`, it would need to add a "mode" flag, and a superset of flags for all build commands (test, check, build, etc.). To me that seemed like a difficult path to take. This may also be helpful for making visualizations of the true dependencies. `cargo metadata` doesn't show the intra-package dependencies like build scripts or test units, and walking the `cargo metadata` graph correctly isn't always obvious. This initial concept exposes almost all of the fields. That may be a little too much, but I imagine we could always trim it before stabilizing. This structure also has a high risk of being unstable, since it has a good chance of changing form in the future. I figure that can be addressed with documentation emphasizing that it may change and we may not always provide backwards-compatibility (though we will try if it is not too much burden). This could also potentially be extended in the future to include things like artifact paths, or "freshness", if we'd like to.
- Loading branch information
Showing
24 changed files
with
540 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
use crate::core::compiler::Unit; | ||
use crate::core::compiler::{CompileKind, CompileMode}; | ||
use crate::core::profiles::{Profile, UnitFor}; | ||
use crate::core::{nightly_features_allowed, InternedString, PackageId, Target}; | ||
use crate::util::CargoResult; | ||
use std::collections::HashMap; | ||
use std::io::Write; | ||
|
||
/// The dependency graph of Units. | ||
pub type UnitGraph<'a> = HashMap<Unit<'a>, Vec<UnitDep<'a>>>; | ||
|
||
/// A unit dependency. | ||
#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)] | ||
pub struct UnitDep<'a> { | ||
/// The dependency unit. | ||
pub unit: Unit<'a>, | ||
/// The purpose of this dependency (a dependency for a test, or a build | ||
/// script, etc.). | ||
pub unit_for: UnitFor, | ||
/// The name the parent uses to refer to this dependency. | ||
pub extern_crate_name: InternedString, | ||
/// Whether or not this is a public dependency. | ||
pub public: bool, | ||
/// If `true`, the dependency should not be added to Rust's prelude. | ||
pub noprelude: bool, | ||
} | ||
|
||
const VERSION: u32 = 1; | ||
|
||
#[derive(serde::Serialize)] | ||
struct SerializedUnitGraph<'a> { | ||
version: u32, | ||
units: Vec<SerializedUnit<'a>>, | ||
roots: Vec<usize>, | ||
} | ||
|
||
#[derive(serde::Serialize)] | ||
struct SerializedUnit<'a> { | ||
pkg_id: PackageId, | ||
target: &'a Target, | ||
profile: &'a Profile, | ||
platform: CompileKind, | ||
mode: CompileMode, | ||
features: &'a Vec<InternedString>, | ||
#[serde(skip_serializing_if = "std::ops::Not::not")] // hide for unstable build-std | ||
is_std: bool, | ||
dependencies: Vec<SerializedUnitDep>, | ||
} | ||
|
||
#[derive(serde::Serialize)] | ||
struct SerializedUnitDep { | ||
index: usize, | ||
extern_crate_name: InternedString, | ||
// This is only set on nightly since it is unstable. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
public: Option<bool>, | ||
// This is only set on nightly since it is unstable. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
noprelude: Option<bool>, | ||
// Intentionally not including `unit_for` because it is a low-level | ||
// internal detail that is mostly used for building the graph. | ||
} | ||
|
||
pub fn emit_serialized_unit_graph( | ||
root_units: &[Unit<'_>], | ||
unit_graph: &UnitGraph<'_>, | ||
) -> CargoResult<()> { | ||
let is_nightly = nightly_features_allowed(); | ||
let mut units: Vec<(&Unit<'_>, &Vec<UnitDep<'_>>)> = unit_graph.iter().collect(); | ||
units.sort_unstable(); | ||
// Create a map for quick lookup for dependencies. | ||
let indices: HashMap<&Unit<'_>, usize> = units | ||
.iter() | ||
.enumerate() | ||
.map(|(i, val)| (val.0, i)) | ||
.collect(); | ||
let roots = root_units.iter().map(|root| indices[root]).collect(); | ||
let ser_units = units | ||
.iter() | ||
.map(|(unit, unit_deps)| { | ||
let dependencies = unit_deps | ||
.iter() | ||
.map(|unit_dep| { | ||
// https://github.com/rust-lang/rust/issues/64260 when stabilized. | ||
let (public, noprelude) = if is_nightly { | ||
(Some(unit_dep.public), Some(unit_dep.noprelude)) | ||
} else { | ||
(None, None) | ||
}; | ||
SerializedUnitDep { | ||
index: indices[&unit_dep.unit], | ||
extern_crate_name: unit_dep.extern_crate_name, | ||
public, | ||
noprelude, | ||
} | ||
}) | ||
.collect(); | ||
SerializedUnit { | ||
pkg_id: unit.pkg.package_id(), | ||
target: unit.target, | ||
profile: &unit.profile, | ||
platform: unit.kind, | ||
mode: unit.mode, | ||
features: &unit.features, | ||
is_std: unit.is_std, | ||
dependencies, | ||
} | ||
}) | ||
.collect(); | ||
let s = SerializedUnitGraph { | ||
version: VERSION, | ||
units: ser_units, | ||
roots, | ||
}; | ||
|
||
let stdout = std::io::stdout(); | ||
let mut lock = stdout.lock(); | ||
serde_json::to_writer(&mut lock, &s)?; | ||
write!(lock, "\n")?; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.