cargo/core/compiler/build_context/mod.rs
1//! [`BuildContext`] is a (mostly) static information about a build task.
2
3use crate::core::PackageSet;
4use crate::core::Workspace;
5use crate::core::compiler::BuildConfig;
6use crate::core::compiler::CompileKind;
7use crate::core::compiler::Unit;
8use crate::core::compiler::UnitIndex;
9use crate::core::compiler::unit_graph::UnitGraph;
10use crate::core::dependency::DepKind;
11use crate::core::profiles::Profiles;
12use crate::util::Rustc;
13use crate::util::context::GlobalContext;
14use crate::util::errors::CargoResult;
15use crate::util::interning::InternedString;
16use crate::util::logger::BuildLogger;
17use std::collections::{HashMap, HashSet};
18
19mod target_info;
20pub use self::target_info::FileFlavor;
21pub use self::target_info::FileType;
22pub use self::target_info::RustcTargetData;
23pub use self::target_info::TargetInfo;
24
25/// The build context, containing complete information needed for a build task
26/// before it gets started.
27///
28/// It is intended that this is mostly static information. Stuff that mutates
29/// during the build can be found in the parent [`BuildRunner`]. (I say mostly,
30/// because this has internal caching, but nothing that should be observable
31/// or require &mut.)
32///
33/// As a result, almost every field on `BuildContext` is public, including
34///
35/// * a resolved [`UnitGraph`] of your dependencies,
36/// * a [`Profiles`] containing compiler flags presets,
37/// * a [`RustcTargetData`] containing host and target platform information,
38/// * and a [`PackageSet`] for further package downloads,
39///
40/// just to name a few. Learn more on each own documentation.
41///
42/// # How to use
43///
44/// To prepare a build task, you may not want to use [`BuildContext::new`] directly,
45/// since it is often too lower-level.
46/// Instead, [`ops::create_bcx`] is usually what you are looking for.
47///
48/// After a `BuildContext` is built, the next stage of building is handled in [`BuildRunner`].
49///
50/// [`BuildRunner`]: crate::core::compiler::BuildRunner
51/// [`ops::create_bcx`]: crate::ops::create_bcx
52pub struct BuildContext<'a, 'gctx> {
53 /// The workspace the build is for.
54 pub ws: &'a Workspace<'gctx>,
55
56 /// The cargo context.
57 pub gctx: &'gctx GlobalContext,
58
59 /// Build logger for `-Zbuild-analysis`.
60 pub logger: Option<&'a BuildLogger>,
61
62 /// This contains a collection of compiler flags presets.
63 pub profiles: Profiles,
64
65 /// Configuration information for a rustc build.
66 pub build_config: &'a BuildConfig,
67
68 /// Associated [`DepKind`]s for root targets
69 pub selected_dep_kinds: DepKindSet,
70
71 /// Extra compiler args for either `rustc` or `rustdoc`.
72 pub extra_compiler_args: HashMap<Unit, Vec<String>>,
73
74 /// Package downloader.
75 ///
76 /// This holds ownership of the `Package` objects.
77 pub packages: PackageSet<'gctx>,
78
79 /// Information about rustc and the target platform.
80 pub target_data: RustcTargetData<'gctx>,
81
82 /// The root units of `unit_graph` (units requested on the command-line).
83 pub roots: Vec<Unit>,
84
85 /// The dependency graph of units to compile.
86 pub unit_graph: UnitGraph,
87
88 /// A map from unit to index.
89 pub unit_to_index: HashMap<Unit, UnitIndex>,
90
91 /// Reverse-dependencies of documented units, used by the `rustdoc --scrape-examples` flag.
92 pub scrape_units: Vec<Unit>,
93
94 /// The list of all kinds that are involved in this build
95 pub all_kinds: HashSet<CompileKind>,
96}
97
98impl<'a, 'gctx> BuildContext<'a, 'gctx> {
99 pub fn new(
100 ws: &'a Workspace<'gctx>,
101 logger: Option<&'a BuildLogger>,
102 packages: PackageSet<'gctx>,
103 build_config: &'a BuildConfig,
104 selected_dep_kinds: DepKindSet,
105 profiles: Profiles,
106 extra_compiler_args: HashMap<Unit, Vec<String>>,
107 target_data: RustcTargetData<'gctx>,
108 roots: Vec<Unit>,
109 unit_graph: UnitGraph,
110 unit_to_index: HashMap<Unit, UnitIndex>,
111 scrape_units: Vec<Unit>,
112 ) -> CargoResult<BuildContext<'a, 'gctx>> {
113 let all_kinds = unit_graph
114 .keys()
115 .map(|u| u.kind)
116 .chain(build_config.requested_kinds.iter().copied())
117 .chain(std::iter::once(CompileKind::Host))
118 .collect();
119
120 Ok(BuildContext {
121 ws,
122 gctx: ws.gctx(),
123 logger,
124 packages,
125 build_config,
126 selected_dep_kinds,
127 profiles,
128 extra_compiler_args,
129 target_data,
130 roots,
131 unit_graph,
132 unit_to_index,
133 scrape_units,
134 all_kinds,
135 })
136 }
137
138 /// Information of the `rustc` this build task will use.
139 pub fn rustc(&self) -> &Rustc {
140 &self.target_data.rustc
141 }
142
143 /// Gets the host architecture triple.
144 ///
145 /// For example, `x86_64-unknown-linux-gnu`, would be
146 /// - machine: `x86_64`,
147 /// - hardware-platform: `unknown`,
148 /// - operating system: `linux-gnu`.
149 pub fn host_triple(&self) -> InternedString {
150 self.target_data.rustc.host
151 }
152
153 /// Gets the number of jobs specified for this build.
154 pub fn jobs(&self) -> u32 {
155 self.build_config.jobs
156 }
157
158 /// Extra compiler args for either `rustc` or `rustdoc`.
159 ///
160 /// As of now, these flags come from the trailing args of either
161 /// `cargo rustc` or `cargo rustdoc`.
162 pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
163 self.extra_compiler_args.get(unit)
164 }
165}
166
167#[derive(Copy, Clone, Default, Debug)]
168pub struct DepKindSet {
169 pub build: bool,
170 pub normal: bool,
171 pub dev: bool,
172}
173
174impl DepKindSet {
175 pub fn contains(&self, kind: DepKind) -> bool {
176 match kind {
177 DepKind::Build => self.build,
178 DepKind::Normal => self.normal,
179 DepKind::Development => self.dev,
180 }
181 }
182}