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