use std::fs::OpenOptions; fn main() { #[cfg(feature = "local")] { let target_path = get_target_lib_path(); let extension = target_path.extension().unwrap().to_str().unwrap(); let source_path = target_path.parent().unwrap().join(format!( "../../../../target/debug/libagent_gstreamer_dylib.{extension}" )); std::fs::copy(source_path, target_path).expect("failed to copy libagent_gstreamer_dylib"); } #[cfg(feature = "staging")] { download_lib("https://dl.staging.segfault.ai"); } #[cfg(not(any(feature = "local", feature = "staging")))] { download_lib("https://dl.app.segfault.ai"); } } fn get_target_lib_path() -> std::path::PathBuf { let target = std::env::var("TARGET").unwrap(); let extension = if target.contains("windows") { "dll" } else if target.contains("macos") { "dylib" } else { "so" }; let target_dir = get_cargo_target_dir().expect("failed to get cargo target dir"); let target_path = target_dir.join(format!("libsegfaultaisdk.{extension}")); println!("cargo:rustc-link-search=native={}", target_dir.display()); println!("cargo:rerun-if-changed={}", target_path.display()); println!("cargo:rustc-link-lib=dylib=segfaultaisdk"); target_path } #[allow(unused)] fn download_lib(url: &str) { let target = std::env::var("TARGET").unwrap(); let target_path = get_target_lib_path(); let extension = target_path.extension().unwrap().to_str().unwrap(); println!("cargo:rerun-if-env-changed=SEGFAULTAI_SDK_FORCE_UPDATE"); if target_path.exists() && std::env::var("SEGFAULTAI_SDK_FORCE_UPDATE").is_err() { eprintln!("libsegfaultai already exists in target dir, skipping download"); return; } let url = format!("{url}/libsegfault-{target}.{extension}"); eprintln!("downloading {url} to {target_path:?}"); let mut response = reqwest::blocking::get(url) .and_then(|r| r.error_for_status()) .expect("failed to download libsegfault"); let mut file = OpenOptions::new() .create(true) .write(true) .open(target_path) .expect("failed to create file in target dir"); std::io::copy(&mut response, &mut file).expect("failed to copy libsegfault to target dir"); } fn get_cargo_target_dir() -> Result> { let skip_triple = std::env::var("TARGET")? == std::env::var("HOST")?; let skip_parent_dirs = if skip_triple { 3 } else { 4 }; let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?); let mut current = out_dir.as_path(); for _ in 0..skip_parent_dirs { current = current.parent().ok_or("not found")?; } Ok(std::path::PathBuf::from(current)) }