use reqwest::blocking::get;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::time::Instant;
use std::{env, error, fs, io};
fn main() {
#[cfg(not(feature = "docsrs"))]
{
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
{
panic!(
"\x1b[31mError vzense-rust: Sorry, no libraries for this architecture. Libraries are only provided for x86_64 and aarch64.\x1b[0m"
)
}
#[cfg(target_arch = "x86_64")]
let arch = "x86_64";
#[cfg(target_arch = "aarch64")]
let arch = "aarch64";
let lib_path = env::current_dir().unwrap().join("target/vzense-lib");
if !existing(lib_path.join(arch)) {
fs::create_dir_all(lib_path.clone()).unwrap();
let lib_url = format!(
"https://github.com/h-a-n-n-e-s/vzense-rust/raw/refs/heads/main/lib/{arch}.tar.xz"
);
download(&lib_url, lib_path.join(format!("{}{}", arch, ".tar.xz")))
.expect("\x1b[31mError vzense-rust: Unable to download libraries.\x1b[0m");
execute(
"unxz",
&[&format!("{arch}.tar.xz")],
lib_path.clone(),
"could not unxz vzense-lib",
);
execute(
"tar",
&["-xf", &format!("{arch}.tar")],
lib_path.clone(),
"could not untar vzense-lib",
);
}
let deps_path = Path::new(&env::var("OUT_DIR").unwrap()).join("../../../deps");
symlink_dir_all(lib_path.join(arch), deps_path.clone())
.expect("\x1b[31mfailed to create symlinks to libraries\x1b[0m");
println!("cargo:rustc-link-search={}", deps_path.to_str().unwrap());
println!(
"cargo:rustc-link-arg=-Wl,-rpath,{}",
deps_path.to_str().unwrap()
);
println!("cargo:rustc-link-lib=vzense_api");
println!("cargo:rustc-link-lib=Scepter_api");
}
}
fn existing(path: PathBuf) -> bool {
path.try_exists().expect("cannot check if path exists")
}
fn execute(command: &str, args: &[&str], dir: PathBuf, err: &str) {
std::process::Command::new(command)
.current_dir(dir)
.args(args)
.output()
.expect(err);
}
fn symlink_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let file = dst.as_ref().join(entry.file_name());
let ty = entry.file_type()?;
if ty.is_dir() {
symlink_dir_all(entry.path(), file)?;
} else if !existing(file.clone()) {
std::os::unix::fs::symlink(entry.path(), file)?;
}
}
Ok(())
}
fn download(url: &str, file_name: PathBuf) -> Result<(), Box<dyn error::Error>> {
let now = Instant::now();
let response = get(url)?;
let content = response.bytes()?;
let mut downloaded_file = fs::File::create(file_name)?;
downloaded_file.write_all(&content)?;
let duration = now.elapsed();
println!("Downloaded file {url} in {duration:?}");
Ok(())
}