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}