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