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