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