use std::collections::HashMap;
use std::env;
fn main() { build_numkong().expect("Failed to build NumKong"); }
fn build_numkong() -> Result<HashMap<String, bool>, String> {
let mut flags = HashMap::<String, bool>::new();
let mut build = cc::Build::new();
build
.std("c99") .file("c/numkong.c")
.file("c/dispatch_f64c.c")
.file("c/dispatch_f32c.c")
.file("c/dispatch_bf16c.c")
.file("c/dispatch_f16c.c")
.file("c/dispatch_f64.c")
.file("c/dispatch_f32.c")
.file("c/dispatch_bf16.c")
.file("c/dispatch_f16.c")
.file("c/dispatch_e5m2.c")
.file("c/dispatch_e4m3.c")
.file("c/dispatch_e3m2.c")
.file("c/dispatch_e2m3.c")
.file("c/dispatch_i64.c")
.file("c/dispatch_i32.c")
.file("c/dispatch_i16.c")
.file("c/dispatch_i8.c")
.file("c/dispatch_i4.c")
.file("c/dispatch_u64.c")
.file("c/dispatch_u32.c")
.file("c/dispatch_u16.c")
.file("c/dispatch_u8.c")
.file("c/dispatch_u4.c")
.file("c/dispatch_u1.c")
.file("c/dispatch_other.c")
.include("include")
.define("NK_NATIVE_F16", "0")
.define("NK_NATIVE_BF16", "0")
.define("NK_DYNAMIC_DISPATCH", "1")
.opt_level(3)
.flag_if_supported("-pedantic") .flag_if_supported("-Wno-psabi") .warnings(false);
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
if target_arch == "x86" {
build.flag_if_supported("-mstackrealign");
build.flag_if_supported("-mpreferred-stack-boundary=4");
}
let target_bits = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap_or_default();
if target_arch == "x86_64" && target_bits == "64" {
build.define("NK_IS_64BIT_X86", "1");
build.define("NK_IS_64BIT_ARM", "0");
build.define("NK_IS_64BIT_RISCV", "0");
flags.insert("NK_IS_64BIT_X86".to_string(), true);
flags.insert("NK_IS_64BIT_ARM".to_string(), false);
flags.insert("NK_IS_64BIT_RISCV".to_string(), false);
} else if target_arch == "aarch64" && target_bits == "64" {
build.define("NK_IS_64BIT_X86", "0");
build.define("NK_IS_64BIT_ARM", "1");
build.define("NK_IS_64BIT_RISCV", "0");
flags.insert("NK_IS_64BIT_X86".to_string(), false);
flags.insert("NK_IS_64BIT_ARM".to_string(), true);
flags.insert("NK_IS_64BIT_RISCV".to_string(), false);
} else if target_arch == "riscv64" && target_bits == "64" {
build.define("NK_IS_64BIT_X86", "0");
build.define("NK_IS_64BIT_ARM", "0");
build.define("NK_IS_64BIT_RISCV", "1");
flags.insert("NK_IS_64BIT_X86".to_string(), false);
flags.insert("NK_IS_64BIT_ARM".to_string(), false);
flags.insert("NK_IS_64BIT_RISCV".to_string(), true);
} else {
build.define("NK_IS_64BIT_X86", "0");
build.define("NK_IS_64BIT_ARM", "0");
build.define("NK_IS_64BIT_RISCV", "0");
flags.insert("NK_IS_64BIT_X86".to_string(), false);
flags.insert("NK_IS_64BIT_ARM".to_string(), false);
flags.insert("NK_IS_64BIT_RISCV".to_string(), false);
}
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
let is_freebsd = target_os == "freebsd";
let is_linux = target_os == "linux";
let is_windows = target_os == "windows";
let is_macos = target_os == "macos";
let is_android = target_os == "android";
let flags_to_try = match target_arch.as_str() {
"arm" | "aarch64" => {
let mut flags = Vec::new();
if is_linux || is_freebsd || is_macos || is_android {
flags.extend_from_slice(&[
"NK_TARGET_SMELUT2",
"NK_TARGET_SMEBF16",
"NK_TARGET_SMEBI32",
"NK_TARGET_SMEHALF",
"NK_TARGET_SMEFA64",
"NK_TARGET_SMEF64",
"NK_TARGET_SME2P1",
"NK_TARGET_SME2",
"NK_TARGET_SME",
]);
}
if is_linux || is_freebsd || is_android {
flags.extend_from_slice(&[
"NK_TARGET_SVE2P1",
"NK_TARGET_SVE2",
"NK_TARGET_SVESDOT",
"NK_TARGET_SVEBFDOT",
"NK_TARGET_SVEHALF",
"NK_TARGET_SVE",
]);
}
flags.extend_from_slice(&[
"NK_TARGET_NEONFHM",
"NK_TARGET_NEONBFDOT",
"NK_TARGET_NEONSDOT",
"NK_TARGET_NEONHALF",
"NK_TARGET_NEON",
]);
flags
}
"x86_64" => {
let mut flags = Vec::new();
if is_linux || is_windows {
flags.extend_from_slice(&["NK_TARGET_GRANITEAMX", "NK_TARGET_SAPPHIREAMX"]);
}
if is_linux || is_freebsd || is_windows {
flags.extend_from_slice(&[
"NK_TARGET_ALDER",
"NK_TARGET_SIERRA",
"NK_TARGET_TURIN",
"NK_TARGET_SAPPHIRE",
"NK_TARGET_GENOA",
"NK_TARGET_ICELAKE",
"NK_TARGET_SKYLAKE",
]);
}
flags.push("NK_TARGET_HASWELL");
flags
}
"riscv64" => {
if is_linux || is_freebsd {
vec![
"NK_TARGET_RVVBB",
"NK_TARGET_RVVBF16",
"NK_TARGET_RVVHALF",
"NK_TARGET_RVV",
]
} else {
vec![]
}
}
"wasm32" | "wasm64" => vec!["NK_TARGET_V128RELAXED"],
_ => vec![],
};
for flag in flags_to_try.iter() {
let enabled = match env::var(flag) {
Ok(val) => val != "0" && val.to_lowercase() != "false",
Err(_) => true, };
if enabled {
build.define(flag, "1");
flags.insert(flag.to_string(), true);
} else {
build.define(flag, "0");
flags.insert(flag.to_string(), false);
println!("cargo:warning=Disabled {} via environment variable", flag);
}
}
if build.try_compile("numkong").is_err() {
println!("cargo:warning=Failed to compile NumKong with all SIMD backends...");
let mut compiled = false;
for flag in flags_to_try.iter() {
build.define(flag, "0");
flags.insert(flag.to_string(), false);
if build.try_compile("numkong").is_ok() {
println!(
"cargo:warning=Successfully compiled after disabling {}",
flag
);
compiled = true;
break;
}
println!(
"cargo:warning=Failed to compile after disabling {}, trying next configuration...",
flag
);
}
if !compiled {
return Err("Failed to compile NumKong with any SIMD configuration".into());
}
}
println!("cargo:rerun-if-changed=c/dispatch.h");
println!("cargo:rerun-if-changed=c/dispatch_f64c.c");
println!("cargo:rerun-if-changed=c/dispatch_f32c.c");
println!("cargo:rerun-if-changed=c/dispatch_bf16c.c");
println!("cargo:rerun-if-changed=c/dispatch_f16c.c");
println!("cargo:rerun-if-changed=c/dispatch_f64.c");
println!("cargo:rerun-if-changed=c/dispatch_f32.c");
println!("cargo:rerun-if-changed=c/dispatch_bf16.c");
println!("cargo:rerun-if-changed=c/dispatch_f16.c");
println!("cargo:rerun-if-changed=c/dispatch_e5m2.c");
println!("cargo:rerun-if-changed=c/dispatch_e4m3.c");
println!("cargo:rerun-if-changed=c/dispatch_e3m2.c");
println!("cargo:rerun-if-changed=c/dispatch_e2m3.c");
println!("cargo:rerun-if-changed=c/dispatch_i64.c");
println!("cargo:rerun-if-changed=c/dispatch_i32.c");
println!("cargo:rerun-if-changed=c/dispatch_i16.c");
println!("cargo:rerun-if-changed=c/dispatch_i8.c");
println!("cargo:rerun-if-changed=c/dispatch_i4.c");
println!("cargo:rerun-if-changed=c/dispatch_u64.c");
println!("cargo:rerun-if-changed=c/dispatch_u32.c");
println!("cargo:rerun-if-changed=c/dispatch_u16.c");
println!("cargo:rerun-if-changed=c/dispatch_u8.c");
println!("cargo:rerun-if-changed=c/dispatch_u4.c");
println!("cargo:rerun-if-changed=c/dispatch_u1.c");
println!("cargo:rerun-if-changed=c/dispatch_other.c");
println!("cargo:rerun-if-changed=c/numkong.c");
println!("cargo:rerun-if-changed=include/numkong/numkong.h");
println!("cargo:rerun-if-changed=include/numkong/types.h");
println!("cargo:rerun-if-changed=include/numkong/capabilities.h");
println!("cargo:rerun-if-changed=include/numkong/scalar.h");
println!("cargo:rerun-if-changed=include/numkong/cast.h");
println!("cargo:rerun-if-changed=include/numkong/set.h");
println!("cargo:rerun-if-changed=include/numkong/curved.h");
println!("cargo:rerun-if-changed=include/numkong/dot.h");
println!("cargo:rerun-if-changed=include/numkong/dots.h");
println!("cargo:rerun-if-changed=include/numkong/each.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim.h");
println!("cargo:rerun-if-changed=include/numkong/mesh.h");
println!("cargo:rerun-if-changed=include/numkong/probability.h");
println!("cargo:rerun-if-changed=include/numkong/reduce.h");
println!("cargo:rerun-if-changed=include/numkong/sets.h");
println!("cargo:rerun-if-changed=include/numkong/sparse.h");
println!("cargo:rerun-if-changed=include/numkong/spatial.h");
println!("cargo:rerun-if-changed=include/numkong/spatials.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry.h");
println!("cargo:rerun-if-changed=include/numkong/cast/serial.h");
println!("cargo:rerun-if-changed=include/numkong/cast/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/cast/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/cast/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/cast/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/cast/neon.h");
println!("cargo:rerun-if-changed=include/numkong/cast/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/cast/v128relaxed.h");
println!("cargo:rerun-if-changed=include/numkong/curved/serial.h");
println!("cargo:rerun-if-changed=include/numkong/curved/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/curved/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/curved/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/curved/neon.h");
println!("cargo:rerun-if-changed=include/numkong/curved/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/curved/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/curved/smef64.h");
println!("cargo:rerun-if-changed=include/numkong/curved/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/dot/serial.h");
println!("cargo:rerun-if-changed=include/numkong/dot/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/dot/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/dot/ice.h");
println!("cargo:rerun-if-changed=include/numkong/dot/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/dot/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/dot/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/dot/neon.h");
println!("cargo:rerun-if-changed=include/numkong/dot/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/dot/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/dot/neonsdot.h");
println!("cargo:rerun-if-changed=include/numkong/dot/neonfhm.h");
println!("cargo:rerun-if-changed=include/numkong/dot/sve.h");
println!("cargo:rerun-if-changed=include/numkong/dot/svehalf.h");
println!("cargo:rerun-if-changed=include/numkong/dot/spacemit.h");
println!("cargo:rerun-if-changed=include/numkong/dot/sifive.h");
println!("cargo:rerun-if-changed=include/numkong/dot/xuantie.h");
println!("cargo:rerun-if-changed=include/numkong/dots/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/dots/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/dots/ice.h");
println!("cargo:rerun-if-changed=include/numkong/dots/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/dots/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/dots/sapphire_amx.h");
println!("cargo:rerun-if-changed=include/numkong/dots/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/dots/sve.h");
println!("cargo:rerun-if-changed=include/numkong/dots/svehalf.h");
println!("cargo:rerun-if-changed=include/numkong/each/serial.h");
println!("cargo:rerun-if-changed=include/numkong/each/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/each/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/each/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/each/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/each/neon.h");
println!("cargo:rerun-if-changed=include/numkong/each/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/each/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/each/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial/serial.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial/neon.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/geospatial/v128relaxed.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim/serial.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim/neonsdot.h");
println!("cargo:rerun-if-changed=include/numkong/maxsim/sme.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/serial.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/ice.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/neon.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/mesh/neonsdot.h");
println!("cargo:rerun-if-changed=include/numkong/probability/serial.h");
println!("cargo:rerun-if-changed=include/numkong/probability/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/probability/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/probability/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/probability/neon.h");
println!("cargo:rerun-if-changed=include/numkong/probability/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/serial.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/ice.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/reduce/neonsdot.h");
println!("cargo:rerun-if-changed=include/numkong/scalar/serial.h");
println!("cargo:rerun-if-changed=include/numkong/scalar/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/scalar/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/scalar/neon.h");
println!("cargo:rerun-if-changed=include/numkong/scalar/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/scalar/v128relaxed.h");
println!("cargo:rerun-if-changed=include/numkong/set/serial.h");
println!("cargo:rerun-if-changed=include/numkong/set/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/set/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/set/neon.h");
println!("cargo:rerun-if-changed=include/numkong/set/sve.h");
println!("cargo:rerun-if-changed=include/numkong/set/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/set/rvvbb.h");
println!("cargo:rerun-if-changed=include/numkong/set/v128relaxed.h");
println!("cargo:rerun-if-changed=include/numkong/sets/serial.h");
println!("cargo:rerun-if-changed=include/numkong/sets/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/sets/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/sets/neon.h");
println!("cargo:rerun-if-changed=include/numkong/sets/smebi32.h");
println!("cargo:rerun-if-changed=include/numkong/sparse/serial.h");
println!("cargo:rerun-if-changed=include/numkong/sparse/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/sparse/turin.h");
println!("cargo:rerun-if-changed=include/numkong/sparse/neon.h");
println!("cargo:rerun-if-changed=include/numkong/sparse/sve2.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/serial.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/ice.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/sapphire.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/neon.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/neonsdot.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/sve.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/svehalf.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/svebfdot.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/spacemit.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/sifive.h");
println!("cargo:rerun-if-changed=include/numkong/spatial/xuantie.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/serial.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/icelake.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/sapphireamx.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/neon.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/neonhalf.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/neonsdot.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/neonfhm.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/sme.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/smef64.h");
println!("cargo:rerun-if-changed=include/numkong/spatials/rvv.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/serial.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/haswell.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/skylake.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/ice.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/genoa.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/sierra.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/neon.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/neonbfdot.h");
println!("cargo:rerun-if-changed=include/numkong/trigonometry/neonsdot.h");
for flag in flags_to_try.iter() {
println!("cargo:rerun-if-env-changed={}", flag);
}
Ok(flags)
}