Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub struct BuildContext<'a, 'cfg> {
pub packages: PackageSet<'cfg>,

/// Information about rustc and the target platform.
pub target_data: RustcTargetData,
pub target_data: RustcTargetData<'cfg>,

/// The root units of `unit_graph` (units requested on the command-line).
pub roots: Vec<Unit>,
Expand All @@ -56,7 +56,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
build_config: &'a BuildConfig,
profiles: Profiles,
extra_compiler_args: HashMap<Unit, Vec<String>>,
target_data: RustcTargetData,
target_data: RustcTargetData<'cfg>,
roots: Vec<Unit>,
unit_graph: UnitGraph,
) -> CargoResult<BuildContext<'a, 'cfg>> {
Expand Down Expand Up @@ -86,12 +86,13 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
}

/// Gets the user-specified linker for a particular host or target.
pub fn linker(&self, kind: CompileKind) -> Option<PathBuf> {
self.target_data
.target_config(kind)
pub fn linker(&self, kind: CompileKind) -> CargoResult<Option<PathBuf>> {
Ok(self
.target_data
.target_config(kind)?
.linker
.as_ref()
.map(|l| l.val.clone().resolve_program(self.config))
.map(|l| l.val.clone().resolve_program(self.config)))
}

/// Gets the host architecture triple.
Expand All @@ -109,12 +110,12 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
self.build_config.jobs
}

pub fn rustflags_args(&self, unit: &Unit) -> &[String] {
&self.target_data.info(unit.kind).rustflags
pub fn rustflags_args(&self, unit: &Unit) -> CargoResult<&[String]> {
Ok(&self.target_data.info(unit.kind)?.rustflags)
}

pub fn rustdocflags_args(&self, unit: &Unit) -> &[String] {
&self.target_data.info(unit.kind).rustdocflags
pub fn rustdocflags_args(&self, unit: &Unit) -> CargoResult<&[String]> {
Ok(&self.target_data.info(unit.kind)?.rustdocflags)
}

pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
Expand Down
119 changes: 71 additions & 48 deletions src/cargo/core/compiler/build_context/target_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::cell::RefCell;
use std::collections::hash_map::{Entry, HashMap};
use std::env;
use std::path::PathBuf;
use std::rc::Rc;
use std::str::{self, FromStr};

/// Information about the platform target gleaned from querying rustc.
Expand Down Expand Up @@ -646,60 +647,63 @@ fn env_args(
}

/// Collection of information about `rustc` and the host and target.
pub struct RustcTargetData {
pub struct RustcTargetData<'cfg> {
/// Configuration from the Workspace this was built with.
config: &'cfg Config,

/// Information about `rustc` itself.
pub rustc: Rustc,

/// Build information for the "host", which is information about when
/// `rustc` is invoked without a `--target` flag. This is used for
/// procedural macros, build scripts, etc.
host_config: TargetConfig,
host_info: TargetInfo,
host_config: Rc<TargetConfig>,
host_info: Rc<TargetInfo>,

/// Build information for targets that we're building for. This is
/// a cache that will be filled on-demand.
target_config: RefCell<HashMap<CompileTarget, Rc<TargetConfig>>>,
target_info: RefCell<HashMap<CompileTarget, Rc<TargetInfo>>>,

/// Build information for targets that we're building for. This will be
/// empty if the `--target` flag is not passed.
target_config: HashMap<CompileTarget, TargetConfig>,
target_info: HashMap<CompileTarget, TargetInfo>,
// TODO: can we get rid of this? in other words, does
// TargetInfo::new really need the list of requested kinds?
requested_kinds: Vec<CompileKind>,
}

impl RustcTargetData {
impl<'cfg> RustcTargetData<'cfg> {
pub fn new(
ws: &Workspace<'_>,
ws: &Workspace<'cfg>,
requested_kinds: &[CompileKind],
) -> CargoResult<RustcTargetData> {
) -> CargoResult<RustcTargetData<'cfg>> {
let config = ws.config();
let rustc = config.load_global_rustc(Some(ws))?;
let host_config = config.target_cfg_triple(&rustc.host)?;
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
let mut target_config = HashMap::new();
let mut target_info = HashMap::new();
for kind in requested_kinds {
if let CompileKind::Target(target) = *kind {
let tcfg = config.target_cfg_triple(target.short_name())?;
target_config.insert(target, tcfg);
target_info.insert(
target,
TargetInfo::new(config, requested_kinds, &rustc, *kind)?,
);
}
}
let host_config = Rc::new(config.target_cfg_triple(&rustc.host)?);
let host_info = Rc::new(TargetInfo::new(
config,
requested_kinds,
&rustc,
CompileKind::Host,
)?);

// This is a hack. The unit_dependency graph builder "pretends" that
// `CompileKind::Host` is `CompileKind::Target(host)` if the
// `--target` flag is not specified. Since the unit_dependency code
// needs access to the target config data, create a copy so that it
// can be found. See `rebuild_unit_graph_shared` for why this is done.
if requested_kinds.iter().any(CompileKind::is_host) {
let ct = CompileTarget::new(&rustc.host)?;
target_info.insert(ct, host_info.clone());
target_config.insert(ct, host_config.clone());
}
let mut target_config = HashMap::new();
let mut target_info = HashMap::new();
let ct = CompileTarget::new(&rustc.host)?;
target_info.insert(ct, host_info.clone());
target_config.insert(ct, host_config.clone());

Ok(RustcTargetData {
config,
rustc,
target_config,
target_info,
target_config: RefCell::new(target_config),
target_info: RefCell::new(target_info),
host_config,
host_info,
requested_kinds: requested_kinds.to_owned(),
})
}

Expand All @@ -714,43 +718,62 @@ impl RustcTargetData {

/// Whether a dependency should be compiled for the host or target platform,
/// specified by `CompileKind`.
pub fn dep_platform_activated(&self, dep: &Dependency, kind: CompileKind) -> bool {
pub fn dep_platform_activated(&self, dep: &Dependency, kind: CompileKind) -> CargoResult<bool> {
// If this dependency is only available for certain platforms,
// make sure we're only enabling it for that platform.
let platform = match dep.platform() {
Some(p) => p,
None => return true,
None => return Ok(true),
};
let name = self.short_name(&kind);
platform.matches(name, self.cfg(kind))
Ok(platform.matches(name, self.cfg(kind)?))
}

/// Gets the list of `cfg`s printed out from the compiler for the specified kind.
pub fn cfg(&self, kind: CompileKind) -> &[Cfg] {
self.info(kind).cfg()
pub fn cfg(&self, kind: CompileKind) -> CargoResult<&[Cfg]> {
Ok(self.info(kind)?.cfg())
}

/// Information about the given target platform, learned by querying rustc.
pub fn info(&self, kind: CompileKind) -> &TargetInfo {
match kind {
CompileKind::Host => &self.host_info,
CompileKind::Target(s) => &self.target_info[&s],
}
pub fn info(&self, kind: CompileKind) -> CargoResult<Rc<TargetInfo>> {
Ok(match kind {
CompileKind::Host => self.host_info.clone(),
CompileKind::Target(s) => match self.target_info.borrow_mut().entry(s) {
std::collections::hash_map::Entry::Occupied(o) => o.get().clone(),
std::collections::hash_map::Entry::Vacant(v) => v
.insert(Rc::new(TargetInfo::new(
self.config,
&self.requested_kinds,
&self.rustc,
kind,
)?))
.clone(),
},
})
}

/// Gets the target configuration for a particular host or target.
pub fn target_config(&self, kind: CompileKind) -> &TargetConfig {
match kind {
CompileKind::Host => &self.host_config,
CompileKind::Target(s) => &self.target_config[&s],
}
pub fn target_config(&self, kind: CompileKind) -> CargoResult<Rc<TargetConfig>> {
Ok(match kind {
CompileKind::Host => self.host_config.clone(),
CompileKind::Target(s) => match self.target_config.borrow_mut().entry(s) {
std::collections::hash_map::Entry::Occupied(o) => o.get().clone(),
std::collections::hash_map::Entry::Vacant(v) => v
.insert(Rc::new(self.config.target_cfg_triple(s.short_name())?))
.clone(),
},
})
}

/// If a build script is overridden, this returns the `BuildOutput` to use.
///
/// `lib_name` is the `links` library name and `kind` is whether it is for
/// Host or Target.
pub fn script_override(&self, lib_name: &str, kind: CompileKind) -> Option<&BuildOutput> {
self.target_config(kind).links_overrides.get(lib_name)
pub fn script_override(
&self,
lib_name: &str,
kind: CompileKind,
) -> CargoResult<Option<&BuildOutput>> {
Ok(self.target_config(kind)?.links_overrides.get(lib_name))
}
}
12 changes: 6 additions & 6 deletions src/cargo/core/compiler/compilation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,19 @@ impl<'cfg> Compilation<'cfg> {
deps_output: HashMap::new(),
sysroot_host_libdir: bcx
.target_data
.info(CompileKind::Host)
.info(CompileKind::Host)?
.sysroot_host_libdir
.clone(),
sysroot_target_libdir: bcx
.all_kinds
.iter()
.map(|kind| {
(
Ok((
*kind,
bcx.target_data.info(*kind).sysroot_target_libdir.clone(),
)
bcx.target_data.info(*kind)?.sysroot_target_libdir.clone(),
))
})
.collect(),
.collect::<CargoResult<_>>()?,
tests: Vec::new(),
binaries: Vec::new(),
cdylibs: Vec::new(),
Expand Down Expand Up @@ -351,7 +351,7 @@ fn target_runner(
}

// try target.'cfg(...)'.runner
let target_cfg = bcx.target_data.info(kind).cfg();
let target_cfg = bcx.target_data.info(kind)?.cfg();
let mut cfgs = bcx
.config
.target_cfgs()?
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/context/compilation_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
) -> CargoResult<PathBuf> {
assert!(target.is_bin());
let dest = self.layout(kind).dest();
let info = bcx.target_data.info(kind);
let info = bcx.target_data.info(kind)?;
let (file_types, _) = info
.rustc_outputs(
CompileMode::Build,
Expand Down Expand Up @@ -422,7 +422,7 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
) -> CargoResult<Vec<OutputFile>> {
let out_dir = self.out_dir(unit);

let info = bcx.target_data.info(unit.kind);
let info = bcx.target_data.info(unit.kind)?;
let triple = bcx.target_data.short_name(&unit.kind);
let (file_types, unsupported) =
info.rustc_outputs(unit.mode, unit.target.kind(), triple)?;
Expand Down
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
unit: unit.clone(),
args,
unstable_opts,
linker: self.bcx.linker(unit.kind),
linker: self.bcx.linker(unit.kind)?,
});
}

Expand All @@ -235,7 +235,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
}

// Collect rustdocflags.
let rustdocflags = self.bcx.rustdocflags_args(unit);
let rustdocflags = self.bcx.rustdocflags_args(unit)?;
if !rustdocflags.is_empty() {
self.compilation
.rustdocflags
Expand Down
6 changes: 3 additions & 3 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
.env("RUSTDOC", &*bcx.config.rustdoc()?)
.inherit_jobserver(&cx.jobserver);

if let Some(linker) = &bcx.target_data.target_config(unit.kind).linker {
if let Some(linker) = &bcx.target_data.target_config(unit.kind)?.linker {
cmd.env(
"RUSTC_LINKER",
linker.val.clone().resolve_program(bcx.config),
Expand All @@ -216,7 +216,7 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
}

let mut cfg_map = HashMap::new();
for cfg in bcx.target_data.cfg(unit.kind) {
for cfg in bcx.target_data.cfg(unit.kind)? {
match *cfg {
Cfg::Name(ref n) => {
cfg_map.insert(n.clone(), None);
Expand Down Expand Up @@ -727,7 +727,7 @@ pub fn build_map(cx: &mut Context<'_, '_>) -> CargoResult<()> {
// If there is a build script override, pre-fill the build output.
if unit.mode.is_run_custom_build() {
if let Some(links) = unit.pkg.manifest().links() {
if let Some(output) = cx.bcx.target_data.script_override(links, unit.kind) {
if let Some(output) = cx.bcx.target_data.script_override(links, unit.kind)? {
let metadata = cx.get_run_build_script_metadata(unit);
cx.build_script_outputs.lock().unwrap().insert(
unit.pkg.package_id(),
Expand Down
10 changes: 5 additions & 5 deletions src/cargo/core/compiler/fingerprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1296,9 +1296,9 @@ fn calculate_normal(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Finger
// hashed to take up less space on disk as we just need to know when things
// change.
let extra_flags = if unit.mode.is_doc() {
cx.bcx.rustdocflags_args(unit)
cx.bcx.rustdocflags_args(unit)?
} else {
cx.bcx.rustflags_args(unit)
cx.bcx.rustflags_args(unit)?
}
.to_vec();

Expand Down Expand Up @@ -1432,9 +1432,9 @@ fn build_script_local_fingerprints(
) -> (
Box<
dyn FnOnce(
&BuildDeps,
Option<&dyn Fn() -> CargoResult<String>>,
) -> CargoResult<Option<Vec<LocalFingerprint>>>
&BuildDeps,
Option<&dyn Fn() -> CargoResult<String>>,
) -> CargoResult<Option<Vec<LocalFingerprint>>>
+ Send,
>,
bool,
Expand Down
6 changes: 3 additions & 3 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc<dyn Executor>) -> Car
let rustc_dep_info_loc = root.join(dep_info_name);
let dep_info_loc = fingerprint::dep_info_loc(cx, unit);

rustc.args(cx.bcx.rustflags_args(unit));
rustc.args(cx.bcx.rustflags_args(unit)?);
if cx.bcx.config.cli_unstable().binary_dep_depinfo {
rustc.arg("-Z").arg("binary-dep-depinfo");
}
Expand Down Expand Up @@ -612,7 +612,7 @@ fn rustdoc(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Work> {
build_deps_args(&mut rustdoc, cx, unit)?;
rustdoc::add_root_urls(cx, unit, &mut rustdoc)?;

rustdoc.args(bcx.rustdocflags_args(unit));
rustdoc.args(bcx.rustdocflags_args(unit)?);

if !crate_version_flag_already_present(&rustdoc) {
append_crate_version_flag(unit, &mut rustdoc);
Expand Down Expand Up @@ -921,7 +921,7 @@ fn build_base_args(
cmd,
"-C",
"linker=",
bcx.linker(unit.kind).as_ref().map(|s| s.as_ref()),
bcx.linker(unit.kind)?.as_ref().map(|s| s.as_ref()),
);
if incremental {
let dir = cx.files().layout(unit.kind).incremental().as_os_str();
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/compiler/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ pub fn add_root_urls(
let std_url = match &map.std {
None | Some(RustdocExternMode::Remote) => None,
Some(RustdocExternMode::Local) => {
let sysroot = &cx.bcx.target_data.info(CompileKind::Host).sysroot;
let sysroot = &cx.bcx.target_data.info(CompileKind::Host)?.sysroot;
let html_root = sysroot.join("share").join("doc").join("rust").join("html");
if html_root.exists() {
let url = Url::from_file_path(&html_root).map_err(|()| {
Expand Down
Loading