Skip to main content

cargo/core/compiler/build_context/
mod.rs

1use crate::core::compiler::unit::UnitInterner;
2use crate::core::compiler::{BuildConfig, BuildOutput, CompileKind, Unit};
3use crate::core::profiles::Profiles;
4use crate::core::{InternedString, Workspace};
5use crate::core::{PackageId, PackageSet};
6use crate::util::config::Config;
7use crate::util::errors::CargoResult;
8use crate::util::Rustc;
9use std::cell::RefCell;
10use std::collections::{HashMap, HashSet};
11use std::path::PathBuf;
12use std::str;
13
14mod target_info;
15pub use self::target_info::{FileFlavor, RustcTargetData, TargetInfo};
16
17/// The build context, containing all information about a build task.
18///
19/// It is intended that this is mostly static information. Stuff that mutates
20/// during the build can be found in the parent `Context`. (I say mostly,
21/// because this has internal caching, but nothing that should be observable
22/// or require &mut.)
23pub struct BuildContext<'a, 'cfg> {
24    /// The workspace the build is for.
25    pub ws: &'a Workspace<'cfg>,
26    /// The cargo configuration.
27    pub config: &'cfg Config,
28    pub profiles: Profiles,
29    pub build_config: &'a BuildConfig,
30    /// Extra compiler args for either `rustc` or `rustdoc`.
31    pub extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
32    /// Package downloader.
33    pub packages: &'a PackageSet<'cfg>,
34
35    /// Source of interning new units as they're created.
36    pub units: &'a UnitInterner<'a>,
37
38    /// Information about rustc and the target platform.
39    pub target_data: RustcTargetData,
40
41    /// Units which should be skipped, use in dependency builds
42    pub skip_units: RefCell<HashSet<Unit<'a>>>,
43}
44
45impl<'a, 'cfg> BuildContext<'a, 'cfg> {
46    pub fn new(
47        ws: &'a Workspace<'cfg>,
48        packages: &'a PackageSet<'cfg>,
49        config: &'cfg Config,
50        build_config: &'a BuildConfig,
51        profiles: Profiles,
52        units: &'a UnitInterner<'a>,
53        extra_compiler_args: HashMap<Unit<'a>, Vec<String>>,
54        target_data: RustcTargetData,
55    ) -> CargoResult<BuildContext<'a, 'cfg>> {
56        Ok(BuildContext {
57            ws,
58            packages,
59            config,
60            build_config,
61            profiles,
62            extra_compiler_args,
63            units,
64            target_data,
65            skip_units: RefCell::new(HashSet::new()),
66        })
67    }
68
69    pub fn rustc(&self) -> &Rustc {
70        &self.target_data.rustc
71    }
72
73    /// Gets the user-specified linker for a particular host or target.
74    pub fn linker(&self, kind: CompileKind) -> Option<PathBuf> {
75        self.target_data
76            .target_config(kind)
77            .linker
78            .as_ref()
79            .map(|l| l.val.clone().resolve_program(self.config))
80    }
81
82    /// Gets the host architecture triple.
83    ///
84    /// For example, x86_64-unknown-linux-gnu, would be
85    /// - machine: x86_64,
86    /// - hardware-platform: unknown,
87    /// - operating system: linux-gnu.
88    pub fn host_triple(&self) -> InternedString {
89        self.target_data.rustc.host
90    }
91
92    /// Gets the number of jobs specified for this build.
93    pub fn jobs(&self) -> u32 {
94        self.build_config.jobs
95    }
96
97    pub fn rustflags_args(&self, unit: &Unit<'_>) -> &[String] {
98        &self.target_data.info(unit.kind).rustflags
99    }
100
101    pub fn rustdocflags_args(&self, unit: &Unit<'_>) -> &[String] {
102        &self.target_data.info(unit.kind).rustdocflags
103    }
104
105    pub fn show_warnings(&self, pkg: PackageId) -> bool {
106        pkg.source_id().is_path() || self.config.extra_verbose()
107    }
108
109    pub fn extra_args_for(&self, unit: &Unit<'a>) -> Option<&Vec<String>> {
110        self.extra_compiler_args.get(unit)
111    }
112
113    /// If a build script is overridden, this returns the `BuildOutput` to use.
114    ///
115    /// `lib_name` is the `links` library name and `kind` is whether it is for
116    /// Host or Target.
117    pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
118        self.target_data
119            .target_config(kind)
120            .links_overrides
121            .get(lib_name)
122    }
123}