From: Aleksey Kladov Date: Wed, 21 Mar 2018 07:54:15 +0000 (+0300) Subject: Preprobe info for known crate type X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~22^2~2^2~19^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=9f7618b36c07e91f10ce643fc6538a289f3c8935;p=cargo.git Preprobe info for known crate type Previously, we've calculated the set of crate types to learn about by recursively walking the graph of units. However, to actually know dependencies of a unit exactly, we must know target specific info, and we don't know it at this moment (in fact, we are trying calculating it). Note that crate-type calculation is already lazy, we don't have to calc all crate-types upfront. So, let's just scrape this info once for well-known crate types, and fill whatever is left lazily. --- diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index f56e1d580..a9e9b9066 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -96,7 +96,7 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> { } } - cx.probe_target_info(&units)?; + cx.probe_target_info()?; for unit in units.iter() { rm_rf(&cx.fingerprint_dir(unit), config)?; diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index dd258ee07..cdcfe414f 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -1,6 +1,6 @@ #![allow(deprecated)] -use std::collections::{BTreeSet, HashMap, HashSet}; +use std::collections::{HashMap, HashSet}; use std::collections::hash_map::Entry; use std::env; use std::fmt; @@ -234,60 +234,18 @@ impl<'a, 'cfg> Context<'a, 'cfg> { /// Ensure that we've collected all target-specific information to compile /// all the units mentioned in `units`. - pub fn probe_target_info(&mut self, units: &[Unit<'a>]) -> CargoResult<()> { - let mut crate_types = BTreeSet::new(); - let mut visited_units = HashSet::new(); - // pre-fill with `bin` for learning about tests (nothing may be - // explicitly `bin`) as well as `rlib` as it's the coalesced version of - // `lib` in the compiler and we're not sure which we'll see. - crate_types.insert("bin".to_string()); - crate_types.insert("rlib".to_string()); - for unit in units { - self.visit_crate_type(unit, &mut crate_types, &mut visited_units)?; - } - debug!("probe_target_info: crate_types={:?}", crate_types); - self.probe_target_info_kind(&crate_types, Kind::Target)?; + pub fn probe_target_info(&mut self) -> CargoResult<()> { + debug!("probe_target_info"); + self.probe_target_info_kind(Kind::Target)?; if self.requested_target().is_none() { self.host_info = self.target_info.clone(); } else { - self.probe_target_info_kind(&crate_types, Kind::Host)?; + self.probe_target_info_kind(Kind::Host)?; } Ok(()) } - /// A recursive function that checks all crate types (`rlib`, ...) are in `crate_types` - /// for this unit and its dependencies. - /// - /// Tracks visited units to avoid unnecessary work. - fn visit_crate_type( - &self, - unit: &Unit<'a>, - crate_types: &mut BTreeSet, - visited_units: &mut HashSet>, - ) -> CargoResult<()> { - if !visited_units.insert(*unit) { - return Ok(()); - } - for target in unit.pkg.manifest().targets() { - crate_types.extend(target.rustc_crate_types().iter().map(|s| { - if *s == "lib" { - "rlib".to_string() - } else { - s.to_string() - } - })); - } - for dep in self.dep_targets(unit)? { - self.visit_crate_type(&dep, crate_types, visited_units)?; - } - Ok(()) - } - - fn probe_target_info_kind( - &mut self, - crate_types: &BTreeSet, - kind: Kind, - ) -> CargoResult<()> { + fn probe_target_info_kind(&mut self, kind: Kind) -> CargoResult<()> { let rustflags = env_args( self.config, &self.build_config, @@ -309,8 +267,9 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } let crate_type_process = process.clone(); - - for crate_type in crate_types { + const KNOWN_CRATE_TYPES: &[&str] = + &["bin", "rlib", "dylib", "cdylib", "staticlib", "proc-macro"]; + for crate_type in KNOWN_CRATE_TYPES.iter() { process.arg("--crate-type").arg(crate_type); } @@ -331,7 +290,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { let output = str::from_utf8(&output.stdout).unwrap(); let mut lines = output.lines(); let mut map = HashMap::new(); - for crate_type in crate_types { + for crate_type in KNOWN_CRATE_TYPES { let out = parse_crate_type(crate_type, error, &mut lines)?; map.insert(crate_type.to_string(), out); } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 700230d85..a602c7c84 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -169,7 +169,7 @@ pub fn compile_targets<'a, 'cfg: 'a>( let mut queue = JobQueue::new(&cx); cx.prepare()?; - cx.probe_target_info(&units)?; + cx.probe_target_info()?; cx.build_used_in_plugin_map(&units)?; custom_build::build_map(&mut cx, &units)?; diff --git a/tests/testsuite/bad_config.rs b/tests/testsuite/bad_config.rs index 0486297f3..574d84bff 100644 --- a/tests/testsuite/bad_config.rs +++ b/tests/testsuite/bad_config.rs @@ -529,7 +529,7 @@ fn bad_crate_type() { assert_that( p.cargo("build").arg("-v"), execs().with_status(101).with_stderr_contains( - "error: failed to run `rustc` to learn about target-specific information", + "error: failed to run `rustc` to learn about crate-type bad_type information", ), ); }