Artifact Content
Not logged in

Artifact b717aba488c744a0844f513b6ba9c15ee33f89c2:


use std::collections::{HashMap, HashSet};

use core::PackageId;
use util::CargoResult;
use super::Unit;

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(),
        }
    }

    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 => return Ok(()),
        };
        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, 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, pkg)
            }
        }
        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", unit.pkg.package_id(), lib)
        }
        self.links.insert(lib.to_string(), unit.pkg.package_id());
        Ok(())
    }
}