use cc::Build;
use std::env::consts::OS;
fn linux_has_getrandom() -> bool {
#[cfg(target_os = "linux")]
{
use std::{ffi::CStr, os::raw::c_char, str::FromStr};
extern "C" {
fn gnu_get_libc_version() -> *const c_char;
}
let version_ptr = unsafe { gnu_get_libc_version() };
let version_str = unsafe { CStr::from_ptr(version_ptr) }
.to_str()
.expect("glibc version is not a valid string?!");
let version: Vec<_> = version_str
.split('.')
.map(|s| u8::from_str(s).expect("Invalid glibc version?!"))
.collect();
match version.as_slice() {
[2..=255, 25..=255, ..] => return true,
_ => return false,
}
}
#[allow(unreachable_code)]
false
}
fn select_random() -> &'static str {
match OS {
"macos" | "ios" => {
println!("cargo:rustc-link-lib=framework=Security");
"librandom/secrandomcopybytes.c"
}
"freebsd" | "openbsd" | "netbsd" => "librandom/arc4random.c",
"windows" => "librandom/cryptgenrandom.c",
"linux" if linux_has_getrandom() => "librandom/getrandom.c",
"linux" => "librandom/urandom.c",
os => panic!("Unsupported target OS: {os}"),
}
}
fn main() {
Build::new()
.file(select_random())
.warnings_into_errors(true)
.compile("helpers");
}