use std::process::Command;
fn main() {
println!("cargo:rerun-if-env-changed=OPENH264_DIR");
println!("cargo:rerun-if-env-changed=NASM");
if std::env::var("CARGO_CFG_TARGET_ARCH").as_deref() != Ok("x86_64") {
println!(
"cargo:warning=rusty_h264-accel: non-x86_64 target — skipping x86 SIMD asm \
kernels (the codec uses its pure-Rust scalar path)."
);
return;
}
let out_dir = std::env::var("OUT_DIR").unwrap();
let oh = std::env::var("OPENH264_DIR")
.unwrap_or_else(|_| format!("{}/vendor", env!("CARGO_MANIFEST_DIR")));
let nasm = std::env::var("NASM").unwrap_or_else(|_| "nasm".to_string());
if std::process::Command::new(&nasm).arg("-v").output().is_err() {
println!(
"cargo:warning=rusty_h264-accel: `nasm` not found — skipping asm kernels. \
Install nasm (e.g. `apt install nasm` / `brew install nasm`) to enable the \
`asm` feature's SIMD, or set NASM to the nasm path."
);
return;
}
let inc_dirs = [
"codec/common/x86",
"codec/encoder/core/x86",
"codec/decoder/core/x86",
];
let asm_files = [
"codec/common/x86/dct.asm",
"codec/common/x86/intra_pred_com.asm",
"codec/encoder/core/x86/intra_pred.asm",
"codec/encoder/core/x86/quant.asm",
"codec/decoder/core/x86/dct.asm",
];
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
let (obj_fmt, plat_defs): (&str, &[&str]) = match target_os.as_str() {
"windows" => ("win64", &["-DWIN64"]),
"macos" | "ios" => ("macho64", &["-DUNIX64", "-DPREFIX"]),
_ => ("elf64", &["-DUNIX64"]),
};
let mut build = cc::Build::new();
let mut nasm_args: Vec<String> = vec!["-f".into(), obj_fmt.into(), "-DHAVE_AVX2".into()];
nasm_args.extend(plat_defs.iter().map(|s| s.to_string()));
for d in inc_dirs {
nasm_args.push("-I".into());
nasm_args.push(format!("{oh}/{d}/"));
}
for rel in asm_files {
let asm = format!("{oh}/{rel}");
let stem = rel
.trim_end_matches(".asm")
.replace(['/', '\\'], "_");
let obj = format!("{out_dir}/{stem}.obj");
let mut args = nasm_args.clone();
args.push(asm.clone());
args.push("-o".into());
args.push(obj.clone());
let status = Command::new(&nasm)
.args(&args)
.status()
.expect("failed to run nasm — set NASM to the nasm.exe path");
assert!(status.success(), "nasm failed assembling {asm}");
build.object(&obj);
println!("cargo:rerun-if-changed={asm}");
}
build.compile("wels_asm");
println!("cargo:rerun-if-changed=build.rs");
}