macro_rules! cfg_version {
($($item:tt)*) => ({
#[rustversion::$($item)*]
const RES: bool = true;
#[rustversion::not($($item)*)]
const RES: bool = false;
RES
});
}
fn has_feature(name: &str) -> bool {
let name = name.replace('-', "_").to_uppercase();
std::env::var_os(format!("CARGO_FEATURE_{}", name)).is_some()
}
fn join<T: IntoIterator<Item = String>>(sep: &str, values: T) -> String {
let mut values = values.into_iter();
let mut buffer = String::new();
if let Some(first) = values.next() {
buffer.push_str(&first);
for remaining in values {
buffer.push_str(sep);
buffer.push_str(&remaining);
}
}
buffer
}
fn emit_check_cfg(name: &str, values: Option<&[&str]>) {
let values = match values {
None => "none()".into(),
Some(items) => join(",", items.iter().map(&|x| format!("\"{}\"", x))),
};
println!("cargo:rustc-check-cfg=cfg({}, values({}))", name, values);
}
fn emit_cfg(name: &str, value: Option<&str>) {
let value = match value {
Some(value) => format!("=\"{}\"", value),
None => String::new(),
};
println!("cargo:rustc-cfg={}{}", name, value);
}
const PARKING_LOT_VERSIONS: &[&str] = &["v0_12"];
const SPIN_VERSIONS: &[&str] = &["v0_10", "v0_9"];
fn find_dep_version<'a>(dep: &str, versions: &[&'a str]) -> Option<&'a str> {
versions
.iter()
.find(|&&v| has_feature(&format!("{}_{}", dep, v)))
.cloned()
}
pub fn main() {
println!("cargo:rerun-if-changed=build.rs");
if cfg_version!(since(1.80)) {
emit_check_cfg("sync_backend", Some(&["parking_lot", "std", "spin"]));
emit_check_cfg("parking_lot_version", Some(PARKING_LOT_VERSIONS));
emit_check_cfg("spin_version", Some(SPIN_VERSIONS));
emit_check_cfg("missing_sync_backend", None);
emit_check_cfg("has_maybe_uninit", None);
emit_check_cfg("has_compile_error", None);
emit_check_cfg("has_once_is_completed", None);
emit_check_cfg("has_track_caller", None);
}
if cfg_version!(since(1.36)) {
emit_cfg("has_maybe_uninit", None);
}
if cfg_version!(since(1.38)) {
emit_cfg("has_compile_error", None);
}
if cfg_version!(since(1.43)) {
emit_cfg("has_once_is_completed", None);
}
if cfg_version!(since(1.46)) {
emit_cfg("has_track_caller", None);
}
if let Some(version) = find_dep_version("parking_lot", PARKING_LOT_VERSIONS) {
emit_cfg("parking_lot_version", Some(version));
emit_cfg("sync_backend", Some("parking_lot"));
} else if has_feature("std") {
emit_cfg("sync_backend", Some("std"));
} else if let Some(version) = find_dep_version("spin", SPIN_VERSIONS) {
emit_cfg("spin_version", Some(version));
emit_cfg("sync_backend", Some("spin"));
} else {
emit_cfg("missing_sync_backend", None);
}
}