use std::{env, fs, path::Path, process::Command}; use anyhow::anyhow; fn join(root: &str, next: &str) -> anyhow::Result { Ok(Path::new(root) .join(next) .to_str() .ok_or_else(|| anyhow::anyhow!("Failed to path into string."))? .to_string()) } fn is_exsit(dir: &str) -> bool { fs::metadata(dir).is_ok() } fn exec(command: &str, work_dir: &str) -> anyhow::Result { let output = Command::new(if cfg!(target_os = "windows") { "powershell" } else { "bash" }) .arg(if cfg!(target_os = "windows") { "-command" } else { "-c" }) .arg(if cfg!(target_os = "windows") { format!("$ProgressPreference = 'SilentlyContinue';{}", command) } else { command.to_string() }) .current_dir(work_dir) .output()?; if !output.status.success() { Err(anyhow!("{}", unsafe { String::from_utf8_unchecked(output.stderr) })) } else { Ok(unsafe { String::from_utf8_unchecked(output.stdout) }) } } fn library_name(complete: bool) -> String { let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); let os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let ext = if cfg!(target_os = "windows") { "lib" } else { "a" }; let flag = if cfg!(target_os = "windows") { "" } else { "lib" }; let name = format!("yuv-{}-{}", os, arch); if complete { format!("{}{}.{}", flag, name, ext) } else { name } } fn main() -> anyhow::Result<()> { println!("cargo:cargo:rerun-if-env-changed=./src"); let repository = env::var("CARGO_PKG_REPOSITORY").unwrap(); let version = env::var("CARGO_PKG_VERSION").unwrap(); let output = env::var("OUT_DIR").unwrap(); if !is_exsit(&join(&output, &library_name(true))?) { let url = format!("{}/releases/download/v{}/{}", repository, version, library_name(true)); if cfg!(target_os = "windows") { exec(&format!("Invoke-WebRequest -Uri {} -OutFile {}", url, library_name(true)), &output) } else { exec(&format!("wget {}", url), &output) }.expect("There is no precompiled binary library file in git \ releases, please try to compile it yourself according to the \ README, see https://github.com/colourful-rtc/libyuv-rs"); } println!("cargo:rustc-link-search=all={}", output); println!("cargo:rustc-link-lib={}", library_name(false)); Ok(()) }