use std::env;
use std::fs;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::path::{Path, PathBuf};
const SUPPORTED_TARGETS: &[&str] = &["aarch64-unknown-linux-gnu"];
fn main() {
println!("cargo:rerun-if-env-changed=ADAMO_LIB_DIR");
println!("cargo:rerun-if-changed=build.rs");
if env::var_os("DOCS_RS").is_some() {
return;
}
let target = env::var("TARGET").expect("cargo sets TARGET");
if !SUPPORTED_TARGETS.contains(&target.as_str()) && env::var_os("ADAMO_LIB_DIR").is_none() {
panic!(
"adamo-sys: target `{target}` is not currently supported. \
Supported targets: {}. \
Set ADAMO_LIB_DIR to override if you have a libadamo built for your host.",
SUPPORTED_TARGETS.join(", ")
);
}
let crate_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let lib_dir = resolve_lib_dir(&crate_dir, &target);
println!("cargo:rerun-if-changed={}", lib_dir.display());
let lib = pick_library(&lib_dir).unwrap_or_else(|| {
panic!(
"adamo-sys: no libadamo.so or libadamo.so.xz found in {}. Set ADAMO_LIB_DIR to override.",
lib_dir.display()
)
});
let staged = out_dir.join(lib.staged_name);
stage_library(&lib, &staged).unwrap_or_else(|err| {
panic!(
"adamo-sys: failed to stage {} to {}: {err}",
lib.path.display(),
staged.display()
)
});
println!("cargo:rustc-link-search=native={}", out_dir.display());
println!("cargo:rustc-link-lib=dylib=adamo");
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", out_dir.display());
println!("cargo:lib_dir={}", out_dir.display());
}
fn resolve_lib_dir(crate_dir: &Path, target: &str) -> PathBuf {
if let Ok(custom) = env::var("ADAMO_LIB_DIR") {
return PathBuf::from(custom);
}
crate_dir.join("prebuilt").join(target)
}
struct LibrarySource {
path: PathBuf,
staged_name: &'static str,
compressed_xz: bool,
}
fn pick_library(dir: &Path) -> Option<LibrarySource> {
for name in ["libadamo.so", "libadamo.dylib"] {
let p = dir.join(name);
if p.is_file() {
return Some(LibrarySource {
path: p,
staged_name: name,
compressed_xz: false,
});
}
}
let compressed = dir.join("libadamo.so.xz");
if compressed.is_file() {
return Some(LibrarySource {
path: compressed,
staged_name: "libadamo.so",
compressed_xz: true,
});
}
None
}
fn stage_library(lib: &LibrarySource, staged: &Path) -> Result<(), String> {
if !lib.compressed_xz {
fs::copy(&lib.path, staged)
.map(|_| ())
.map_err(|err| err.to_string())
} else {
let input = File::open(&lib.path).map_err(|err| err.to_string())?;
let output = File::create(staged).map_err(|err| err.to_string())?;
let mut input = BufReader::new(input);
let mut output = BufWriter::new(output);
lzma_rs::xz_decompress(&mut input, &mut output).map_err(|err| err.to_string())
}
}