use std::{env, fs, process::Command};
fn main() {
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
println!("cargo:rustc-check-cfg=cfg(simd_popcnt_have_sve)");
if target_arch == "aarch64" && probe_sve_intrinsics() {
println!("cargo:rustc-cfg=simd_popcnt_have_sve");
}
}
fn probe_sve_intrinsics() -> bool {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".to_string());
let target = match env::var("TARGET") {
Ok(t) => t,
Err(_) => return false,
};
let out = match env::var("OUT_DIR") {
Ok(o) => o,
Err(_) => return false,
};
let src = format!("{out}/probe_sve.rs");
let meta = format!("{out}/libprobe_sve.rmeta");
let probe = r#"
#![no_std]
#![feature(stdarch_aarch64_sve)]
#[cfg(target_arch = "aarch64")]
pub fn probe() {
unsafe { let _ = core::arch::aarch64::svptrue_b8(); }
}
"#;
if fs::write(&src, probe).is_err() {
return false;
}
Command::new(rustc)
.args([
"--edition=2024",
"--crate-type=lib",
"--emit=metadata",
"--target",
&target,
"-o",
&meta,
&src,
])
.output()
.map(|o| o.status.success())
.unwrap_or(false)
}