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