use super::custom_build::{BuildState, BuildScripts};
use super::fingerprint::Fingerprint;
use super::layout::{Layout, LayoutProxy};
+use super::links::Links;
use super::{Kind, Compilation, BuildConfig};
use super::{ProcessEngine, ExecEngine};
pub compiled: HashSet<Unit<'a>>,
pub build_config: BuildConfig,
pub build_scripts: HashMap<Unit<'a>, Arc<BuildScripts>>,
+ pub links: Links<'a>,
host: Layout,
target: Option<Layout>,
compiled: HashSet::new(),
build_scripts: HashMap::new(),
build_explicit_deps: HashMap::new(),
+ links: Links::new(),
})
}
-use std::collections::HashMap;
+use std::collections::{HashMap, HashSet};
-use core::{PackageId, PackageSet};
+use core::PackageId;
use util::CargoResult;
+use super::Unit;
-// Validate that there are no duplicated native libraries among packages and
-// that all packages with `links` also have a build script.
-pub fn validate(deps: &PackageSet) -> CargoResult<()> {
- let mut map: HashMap<_, &PackageId> = HashMap::new();
+pub struct Links<'a> {
+ validated: HashSet<&'a PackageId>,
+ links: HashMap<String, &'a PackageId>,
+}
+
+impl<'a> Links<'a> {
+ pub fn new() -> Links<'a> {
+ Links {
+ validated: HashSet::new(),
+ links: HashMap::new(),
+ }
+ }
- for dep in deps.packages() {
- let lib = match dep.manifest().links() {
+ pub fn validate(&mut self, unit: &Unit<'a>) -> CargoResult<()> {
+ if !self.validated.insert(unit.pkg.package_id()) {
+ return Ok(())
+ }
+ let lib = match unit.pkg.manifest().links() {
Some(lib) => lib,
- None => continue,
+ None => return Ok(()),
};
- if let Some(prev) = map.get(&lib) {
- let dep = dep.package_id();
- if prev.name() == dep.name() && prev.source_id() == dep.source_id() {
+ if let Some(prev) = self.links.get(lib) {
+ let pkg = unit.pkg.package_id();
+ if prev.name() == pkg.name() && prev.source_id() == pkg.source_id() {
bail!("native library `{}` is being linked to by more \
than one version of the same package, but it can \
only be linked once; try updating or pinning your \
dependencies to ensure that this package only shows \
- up once\n\n {}\n {}", lib, prev, dep)
+ up once\n\n {}\n {}", lib, prev, pkg)
} else {
bail!("native library `{}` is being linked to by more than \
one package, and can only be linked to by one \
- package\n\n {}\n {}", lib, prev, dep)
+ package\n\n {}\n {}", lib, prev, pkg)
}
}
- if !dep.manifest().targets().iter().any(|t| t.is_custom_build()) {
+ if !unit.pkg.manifest().targets().iter().any(|t| t.is_custom_build()) {
bail!("package `{}` specifies that it links to `{}` but does not \
- have a custom build script", dep.package_id(), lib)
+ have a custom build script", unit.pkg.package_id(), lib)
}
- map.insert(lib, dep.package_id());
+ self.links.insert(lib.to_string(), unit.pkg.package_id());
+ Ok(())
}
-
- Ok(())
}
}
})
}).collect::<Vec<_>>();
- try!(links::validate(packages));
let dest = if build_config.release {"release"} else {"debug"};
let root = packages.packages().find(|p| {
let p = profile::start(format!("preparing: {}/{}", unit.pkg,
unit.target.name()));
try!(fingerprint::prepare_init(cx, unit));
+ try!(cx.links.validate(unit));
let (dirty, fresh, freshness) = if unit.profile.run_custom_build {
try!(custom_build::prepare(cx, unit))