1#![deny(missing_docs, warnings)]
14
15#[macro_use]
16extern crate error_chain;
17extern crate pkg_config;
18extern crate toml;
19
20use std::collections::HashMap;
21use std::env;
22use std::fs;
23use std::io::Read;
24use std::path::PathBuf;
25use pkg_config::{Config, Library};
26
27error_chain! {
28 foreign_links {
29 PkgConfig(pkg_config::Error) #[doc="pkg-config error"];
30 }
31}
32
33pub fn probe() -> Result<HashMap<String, Library>> {
36 let dir = try!(env::var_os("CARGO_MANIFEST_DIR").ok_or("$CARGO_MANIFEST_DIR not set"));
37 let mut path = PathBuf::from(dir);
38 path.push("Cargo.toml");
39 let mut manifest = try!(fs::File::open(&path).chain_err(||
40 format!("Error opening {}", path.display())
41 ));
42 let mut manifest_str = String::new();
43 try!(manifest.read_to_string(&mut manifest_str).chain_err(||
44 format!("Error reading {}", path.display())
45 ));
46 let toml = try!(manifest_str.parse::<toml::Value>().map_err(|e|
47 format!("Error parsing TOML from {}: {:?}", path.display(), e)
48 ));
49 let key = "package.metadata.pkg-config";
50 let meta = try!(toml.lookup(key).ok_or(
51 format!("No {} in {}", key, path.display())
52 ));
53 let table = try!(meta.as_table().ok_or(
54 format!("{} not a table in {}", key, path.display())
55 ));
56 let mut libraries = HashMap::new();
57 for (name, value) in table {
58 let ref version = match value {
59 &toml::Value::String(ref s) => s,
60 &toml::Value::Table(ref t) => {
61 let mut feature = None;
62 let mut version = None;
63 for (tname, tvalue) in t {
64 match (tname.as_str(), tvalue) {
65 ("feature", &toml::Value::String(ref s)) => { feature = Some(s); }
66 ("version", &toml::Value::String(ref s)) => { version = Some(s); }
67 _ => bail!("Unexpected key {}.{}.{} type {}", key, name, tname, tvalue.type_str()),
68 }
69 }
70 if let Some(feature) = feature {
71 let var = format!("CARGO_FEATURE_{}", feature.to_uppercase().replace('-', "_"));
72 if env::var_os(var).is_none() {
73 continue;
74 }
75 }
76 try!(version.ok_or(format!("No version in {}.{}", key, name)))
77 }
78 _ => bail!("{}.{} not a string or table", key, name),
79 };
80 let library = try!(Config::new().atleast_version(&version).probe(name));
81 libraries.insert(name.clone(), library);
82 }
83 Ok(libraries)
84}