| //! [`BuildContext`] is a (mostly) static information about a build task. |
| |
| use crate::compiler::BuildConfig; |
| use crate::compiler::CompileKind; |
| use crate::compiler::Unit; |
| use crate::compiler::UnitIndex; |
| use crate::compiler::unit_graph::UnitGraph; |
| use crate::context::GlobalContext; |
| use crate::util::Rustc; |
| use crate::util::data_structures::{HashMap, HashSet}; |
| use crate::util::errors::CargoResult; |
| use crate::util::interning::InternedString; |
| use crate::util::logger::BuildLogger; |
| use crate::workspace::PackageSet; |
| use crate::workspace::Workspace; |
| use crate::workspace::dependency::DepKind; |
| use crate::workspace::profiles::Profiles; |
| |
| mod target_info; |
| pub use self::target_info::FileFlavor; |
| pub use self::target_info::FileType; |
| pub use self::target_info::RustcTargetData; |
| pub use self::target_info::TargetInfo; |
| |
| /// The build context, containing complete information needed for a build task |
| /// before it gets started. |
| /// |
| /// It is intended that this is mostly static information. Stuff that mutates |
| /// during the build can be found in the parent [`BuildRunner`]. (I say mostly, |
| /// because this has internal caching, but nothing that should be observable |
| /// or require &mut.) |
| /// |
| /// As a result, almost every field on `BuildContext` is public, including |
| /// |
| /// * a resolved [`UnitGraph`] of your dependencies, |
| /// * a [`Profiles`] containing compiler flags presets, |
| /// * a [`RustcTargetData`] containing host and target platform information, |
| /// * and a [`PackageSet`] for further package downloads, |
| /// |
| /// just to name a few. Learn more on each own documentation. |
| /// |
| /// # How to use |
| /// |
| /// To prepare a build task, you may not want to use [`BuildContext::new`] directly, |
| /// since it is often too lower-level. |
| /// Instead, [`ops::create_bcx`] is usually what you are looking for. |
| /// |
| /// After a `BuildContext` is built, the next stage of building is handled in [`BuildRunner`]. |
| /// |
| /// [`BuildRunner`]: crate::compiler::BuildRunner |
| /// [`ops::create_bcx`]: crate::ops::create_bcx |
| pub struct BuildContext<'a, 'gctx> { |
| /// The workspace the build is for. |
| pub ws: &'a Workspace<'gctx>, |
| |
| /// The cargo context. |
| pub gctx: &'gctx GlobalContext, |
| |
| /// Build logger for `-Zbuild-analysis`. |
| pub logger: Option<&'a BuildLogger>, |
| |
| /// This contains a collection of compiler flags presets. |
| pub profiles: Profiles, |
| |
| /// Configuration information for a rustc build. |
| pub build_config: &'a BuildConfig, |
| |
| /// Associated [`DepKind`]s for root targets |
| pub selected_dep_kinds: DepKindSet, |
| |
| /// Extra compiler args for either `rustc` or `rustdoc`. |
| pub extra_compiler_args: HashMap<Unit, Vec<String>>, |
| |
| /// Package downloader. |
| /// |
| /// This holds ownership of the `Package` objects. |
| pub packages: PackageSet<'gctx>, |
| |
| /// Information about rustc and the target platform. |
| pub target_data: RustcTargetData<'gctx>, |
| |
| /// The root units of `unit_graph` (units requested on the command-line). |
| pub roots: Vec<Unit>, |
| |
| /// The dependency graph of units to compile. |
| pub unit_graph: UnitGraph, |
| |
| /// A map from unit to index. |
| pub unit_to_index: HashMap<Unit, UnitIndex>, |
| |
| /// Reverse-dependencies of documented units, used by the `rustdoc --scrape-examples` flag. |
| pub scrape_units: Vec<Unit>, |
| |
| /// The list of all kinds that are involved in this build |
| pub all_kinds: HashSet<CompileKind>, |
| } |
| |
| impl<'a, 'gctx> BuildContext<'a, 'gctx> { |
| pub fn new( |
| ws: &'a Workspace<'gctx>, |
| logger: Option<&'a BuildLogger>, |
| packages: PackageSet<'gctx>, |
| build_config: &'a BuildConfig, |
| selected_dep_kinds: DepKindSet, |
| profiles: Profiles, |
| extra_compiler_args: HashMap<Unit, Vec<String>>, |
| target_data: RustcTargetData<'gctx>, |
| roots: Vec<Unit>, |
| unit_graph: UnitGraph, |
| unit_to_index: HashMap<Unit, UnitIndex>, |
| scrape_units: Vec<Unit>, |
| ) -> CargoResult<BuildContext<'a, 'gctx>> { |
| let all_kinds = unit_graph |
| .keys() |
| .map(|u| u.kind) |
| .chain(build_config.requested_kinds.iter().copied()) |
| .chain(std::iter::once(CompileKind::Host)) |
| .collect(); |
| |
| Ok(BuildContext { |
| ws, |
| gctx: ws.gctx(), |
| logger, |
| packages, |
| build_config, |
| selected_dep_kinds, |
| profiles, |
| extra_compiler_args, |
| target_data, |
| roots, |
| unit_graph, |
| unit_to_index, |
| scrape_units, |
| all_kinds, |
| }) |
| } |
| |
| /// Information of the `rustc` this build task will use. |
| pub fn rustc(&self) -> &Rustc { |
| &self.target_data.rustc |
| } |
| |
| /// Gets the host architecture triple. |
| /// |
| /// For example, `x86_64-unknown-linux-gnu`, would be |
| /// - machine: `x86_64`, |
| /// - hardware-platform: `unknown`, |
| /// - operating system: `linux-gnu`. |
| pub fn host_triple(&self) -> InternedString { |
| self.target_data.rustc.host |
| } |
| |
| /// Gets the number of jobs specified for this build. |
| pub fn jobs(&self) -> u32 { |
| self.build_config.jobs |
| } |
| |
| /// Extra compiler args for either `rustc` or `rustdoc`. |
| /// |
| /// As of now, these flags come from the trailing args of either |
| /// `cargo rustc` or `cargo rustdoc`. |
| pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec<String>> { |
| self.extra_compiler_args.get(unit) |
| } |
| } |
| |
| #[derive(Copy, Clone, Default, Debug)] |
| pub struct DepKindSet { |
| pub build: bool, |
| pub normal: bool, |
| pub dev: bool, |
| } |
| |
| impl DepKindSet { |
| pub fn contains(&self, kind: DepKind) -> bool { |
| match kind { |
| DepKind::Build => self.build, |
| DepKind::Normal => self.normal, |
| DepKind::Development => self.dev, |
| } |
| } |
| } |