diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index d16d7a52065..6e77413f061 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 5f1df1d26e2..718a6da3637 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,45 +46,17 @@ 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"); -fn build_krate(build: &mut Build, 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 - // of packages we're going to have to know what `-p` arguments to pass it - // to know what crates to test. Here we run `cargo metadata` to learn about - // the dependency graph and what `-p` arguments there are. - let mut cargo = Command::new(&build.initial_cargo); - cargo.arg("metadata") - .arg("--format-version").arg("1") - .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 { - build_step: format!("build-crate-{}", name), - doc_step: format!("doc-crate-{}", name), - test_step: format!("test-crate-{}", name), - bench_step: format!("bench-crate-{}", name), - name, - version: package.version, - deps: Vec::new(), - path, - }); - } + for (name, krate) in build.crates.iter() { + id2name.insert(krate.id.clone(), name.clone()); } - for node in output.resolve.nodes { + for node in resolves { let name = match id2name.get(&node.id) { Some(name) => name, None => continue, @@ -95,7 +68,42 @@ fn build_krate(build: &mut Build, krate: &str) { Some(dep) => dep, None => continue, }; - krate.deps.push(*dep); + krate.deps.insert(*dep); } } } + +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 + // of packages we're going to have to know what `-p` arguments to pass it + // to know what crates to test. Here we run `cargo metadata` to learn about + // the dependency graph and what `-p` arguments there are. + 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(); + for package in output.packages { + if package.source.is_none() { + let name = INTERNER.intern_string(package.name); + let mut path = PathBuf::from(package.manifest_path); + path.pop(); + build.crates.insert(name, Crate { + build_step: format!("build-crate-{}", name), + doc_step: format!("doc-crate-{}", name), + test_step: format!("test-crate-{}", name), + bench_step: format!("bench-crate-{}", name), + name, + version: package.version, + id: package.id, + deps: HashSet::new(), + path, + }); + } + } + resolves.extend(output.resolve.nodes); +}