-
Notifications
You must be signed in to change notification settings - Fork 84
/
Copy pathfeatures.rs
106 lines (93 loc) · 3.68 KB
/
features.rs
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::collections::{HashMap, HashSet};
use std::env;
pub struct Features {
platform_components: HashMap<&'static str, HashSet<&'static str>>,
automatic_features: HashSet<&'static str>,
}
lazy_static! {
pub static ref FEATURES: Features = {
let mut ret = Features {
platform_components: HashMap::new(),
automatic_features: HashSet::new(),
};
ret.init();
ret
};
}
impl Features {
fn init(&mut self) {
if env_have_target_cfg("env", "sgx") {
self.automatic_features.insert("custom_has_support");
self.automatic_features.insert("aes_alt");
self.automatic_features.insert("aesni");
}
self.automatic_features.insert("c_compiler");
// deprecated, needed for backcompat
let have_custom_threading = self.have_feature("custom_threading");
let have_custom_gmtime_r = self.have_feature("custom_gmtime_r");
if !self.have_feature("std") || env_have_target_cfg("env", "sgx") || env_have_target_cfg("os", "none") {
self.with_feature("c_compiler").unwrap().insert("freestanding");
}
if let Some(components) = self.with_feature("threading") {
if !have_custom_threading && env_have_target_cfg("family", "unix") {
components.insert("pthread");
} else {
components.insert("custom");
}
}
if let Some(components) = self.with_feature("std") {
if env_have_target_cfg("family", "unix") || env_have_target_cfg("family", "windows") {
components.insert("net");
components.insert("fs");
components.insert("entropy");
}
}
if let Some(components) = self.with_feature("time") {
if !have_custom_gmtime_r && (env_have_target_cfg("family", "unix") || env_have_target_cfg("family", "windows")) {
components.insert("libc");
} else {
components.insert("custom");
}
}
for (feature, components) in &self.platform_components {
for component in components {
println!(r#"cargo:rustc-cfg={}_component="{}""#, feature, component);
}
}
println!(
"cargo:platform-components={}",
self.platform_components
.iter()
.flat_map(|(feature, components)| {
components
.iter()
.map(move |component| format!(r#"{}_component={}"#, feature, component))
})
.collect::<Vec<_>>()
.join(",")
);
}
fn with_feature(&mut self, feature: &'static str) -> Option<&mut HashSet<&'static str>> {
if self.have_feature(feature) {
Some(self.platform_components.entry(feature).or_insert_with(HashSet::new))
} else {
None
}
}
pub fn have_platform_component(&self, feature: &'static str, component: &'static str) -> bool {
self.platform_components
.get(feature)
.map_or(false, |feat| feat.contains(component))
}
pub fn have_feature(&self, feature: &'static str) -> bool {
self.automatic_features.contains(feature) || env_have_feature(feature)
}
}
fn env_have_target_cfg(var: &'static str, value: &'static str) -> bool {
let env = format!("CARGO_CFG_TARGET_{}", var).to_uppercase().replace("-", "_");
env::var_os(env).map_or(false, |s| s == value)
}
fn env_have_feature(feature: &'static str) -> bool {
let env = format!("CARGO_FEATURE_{}", feature).to_uppercase().replace("-", "_");
env::var_os(env).is_some()
}