1use super::unit_graph::UnitGraph;
2use crate::resolver::Resolve;
3use crate::resolver::errors::describe_path;
4use crate::util::data_structures::{HashMap, HashSet};
5use crate::util::errors::CargoResult;
6use crate::workspace::PackageId;
7
8pub fn validate_links(resolve: &Resolve, unit_graph: &UnitGraph) -> CargoResult<()> {
22 let mut validated: HashSet<PackageId> = HashSet::default();
23 let mut links: HashMap<String, PackageId> = HashMap::default();
24 let mut units: Vec<_> = unit_graph.keys().collect();
25 units.sort_unstable();
27 for unit in units {
28 if !validated.insert(unit.pkg.package_id()) {
29 continue;
30 }
31 let Some(lib) = unit.pkg.manifest().links() else {
32 continue;
33 };
34 if let Some(&prev) = links.get(lib) {
35 let prev_path = resolve
36 .path_to_top(&prev)
37 .into_iter()
38 .map(|(p, d)| (p, d.and_then(|d| d.iter().next())));
39 let pkg = unit.pkg.package_id();
40 let path = resolve
41 .path_to_top(&pkg)
42 .into_iter()
43 .map(|(p, d)| (p, d.and_then(|d| d.iter().next())));
44 anyhow::bail!(
45 "multiple packages link to native library `{}`, \
46 but a native library can be linked only once\n\
47 \n\
48 {}\nlinks to native library `{}`\n\
49 \n\
50 {}\nalso links to native library `{}`",
51 lib,
52 describe_path(prev_path),
53 lib,
54 describe_path(path),
55 lib
56 )
57 }
58 links.insert(lib.to_string(), unit.pkg.package_id());
59 }
60 Ok(())
61}