diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index d16d7a520659b..6e77413f06188 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -280,7 +280,8 @@ pub struct Build { struct Crate { name: Interned, version: String, - deps: Vec>, + deps: HashSet>, + id: String, path: PathBuf, doc_step: String, build_step: String, diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 5f1df1d26e273..718a6da363724 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -11,6 +11,7 @@ use std::collections::HashMap; use std::process::Command; use std::path::PathBuf; +use std::collections::HashSet; use build_helper::output; use serde_json; @@ -45,12 +46,34 @@ struct ResolveNode { } pub fn build(build: &mut Build) { - build_krate(build, "src/libstd"); - build_krate(build, "src/libtest"); - build_krate(build, "src/rustc"); + let mut resolves = Vec::new(); + build_krate(&build.std_features(), build, &mut resolves, "src/libstd"); + build_krate("", build, &mut resolves, "src/libtest"); + build_krate(&build.rustc_features(), build, &mut resolves, "src/rustc"); + + let mut id2name = HashMap::new(); + for (name, krate) in build.crates.iter() { + id2name.insert(krate.id.clone(), name.clone()); + } + + for node in resolves { + let name = match id2name.get(&node.id) { + Some(name) => name, + None => continue, + }; + + let krate = build.crates.get_mut(name).unwrap(); + for dep in node.dependencies.iter() { + let dep = match id2name.get(dep) { + Some(dep) => dep, + None => continue, + }; + krate.deps.insert(*dep); + } + } } -fn build_krate(build: &mut Build, krate: &str) { +fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec, krate: &str) { // Run `cargo metadata` to figure out what crates we're testing. // // Down below we're going to call `cargo test`, but to test the right set @@ -60,14 +83,13 @@ fn build_krate(build: &mut Build, krate: &str) { let mut cargo = Command::new(&build.initial_cargo); cargo.arg("metadata") .arg("--format-version").arg("1") + .arg("--features").arg(features) .arg("--manifest-path").arg(build.src.join(krate).join("Cargo.toml")); let output = output(&mut cargo); let output: Output = serde_json::from_str(&output).unwrap(); - let mut id2name = HashMap::new(); for package in output.packages { if package.source.is_none() { let name = INTERNER.intern_string(package.name); - id2name.insert(package.id, name); let mut path = PathBuf::from(package.manifest_path); path.pop(); build.crates.insert(name, Crate { @@ -77,25 +99,11 @@ fn build_krate(build: &mut Build, krate: &str) { bench_step: format!("bench-crate-{}", name), name, version: package.version, - deps: Vec::new(), + id: package.id, + deps: HashSet::new(), path, }); } } - - for node in output.resolve.nodes { - let name = match id2name.get(&node.id) { - Some(name) => name, - None => continue, - }; - - let krate = build.crates.get_mut(name).unwrap(); - for dep in node.dependencies.iter() { - let dep = match id2name.get(dep) { - Some(dep) => dep, - None => continue, - }; - krate.deps.push(*dep); - } - } + resolves.extend(output.resolve.nodes); }