cargo/core/compiler/
unit_graph.rs1use cargo_util_schemas::core::PackageIdSpec;
6
7use crate::GlobalContext;
8use crate::core::Target;
9use crate::core::compiler::Unit;
10use crate::core::compiler::{CompileKind, CompileMode};
11use crate::core::profiles::{Profile, UnitFor};
12use crate::util::CargoResult;
13use crate::util::interning::InternedString;
14use std::collections::HashMap;
15
16pub type UnitGraph = HashMap<Unit, Vec<UnitDep>>;
18
19#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
21pub struct UnitDep {
22 pub unit: Unit,
24 pub unit_for: UnitFor,
27 pub extern_crate_name: InternedString,
29 pub dep_name: Option<InternedString>,
39 pub public: bool,
41 pub noprelude: bool,
43}
44
45const VERSION: u32 = 1;
46
47#[derive(serde::Serialize)]
48struct SerializedUnitGraph<'a> {
49 version: u32,
50 units: Vec<SerializedUnit<'a>>,
51 roots: Vec<usize>,
52}
53
54#[derive(serde::Serialize)]
55struct SerializedUnit<'a> {
56 pkg_id: PackageIdSpec,
57 target: &'a Target,
58 profile: &'a Profile,
59 platform: CompileKind,
60 mode: CompileMode,
61 features: &'a Vec<InternedString>,
62 #[serde(skip_serializing_if = "std::ops::Not::not")] is_std: bool,
64 dependencies: Vec<SerializedUnitDep>,
65}
66
67#[derive(serde::Serialize)]
68struct SerializedUnitDep {
69 index: usize,
70 extern_crate_name: InternedString,
71 #[serde(skip_serializing_if = "Option::is_none")]
73 public: Option<bool>,
74 #[serde(skip_serializing_if = "Option::is_none")]
76 noprelude: Option<bool>,
77 }
80
81pub fn emit_serialized_unit_graph(
84 root_units: &[Unit],
85 unit_graph: &UnitGraph,
86 gctx: &GlobalContext,
87) -> CargoResult<()> {
88 let mut units: Vec<(&Unit, &Vec<UnitDep>)> = unit_graph.iter().collect();
89 units.sort_unstable();
90 let indices: HashMap<&Unit, usize> = units
92 .iter()
93 .enumerate()
94 .map(|(i, val)| (val.0, i))
95 .collect();
96 let roots = root_units.iter().map(|root| indices[root]).collect();
97 let ser_units = units
98 .iter()
99 .map(|(unit, unit_deps)| {
100 let dependencies = unit_deps
101 .iter()
102 .map(|unit_dep| {
103 let (public, noprelude) = if gctx.nightly_features_allowed {
105 (Some(unit_dep.public), Some(unit_dep.noprelude))
106 } else {
107 (None, None)
108 };
109 SerializedUnitDep {
110 index: indices[&unit_dep.unit],
111 extern_crate_name: unit_dep.extern_crate_name,
112 public,
113 noprelude,
114 }
115 })
116 .collect();
117 SerializedUnit {
118 pkg_id: unit.pkg.package_id().to_spec(),
119 target: &unit.target,
120 profile: &unit.profile,
121 platform: unit.kind,
122 mode: unit.mode,
123 features: &unit.features,
124 is_std: unit.is_std,
125 dependencies,
126 }
127 })
128 .collect();
129
130 gctx.shell().print_json(&SerializedUnitGraph {
131 version: VERSION,
132 units: ser_units,
133 roots,
134 })
135}