use std::path::PathBuf;
fn main() {
#[cfg(feature = "ffi")]
{
let lib_dir = get_lib_dir();
println!("cargo:rustc-link-search=native={}", lib_dir.display());
println!("cargo:rustc-link-lib=static=bb-external");
let target = std::env::var("TARGET").unwrap();
if target.contains("apple") || target.contains("android") {
println!("cargo:rustc-link-lib=dylib=c++");
} else {
println!("cargo:rustc-link-lib=dylib=stdc++");
}
}
}
#[cfg(feature = "ffi")]
fn get_lib_dir() -> PathBuf {
if let Ok(lib_dir) = std::env::var("BB_LIB_DIR") {
let lib_dir = PathBuf::from(&lib_dir);
if lib_dir.join("libbb-external.a").exists() {
return lib_dir.canonicalize().unwrap();
}
panic!(
"BB_LIB_DIR is set to {:?} but libbb-external.a not found there. \
Build barretenberg locally: cd barretenberg/cpp && ./bootstrap.sh",
lib_dir
);
}
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let lib_path = out_dir.join("libbb-external.a");
if !lib_path.exists() {
download_lib(&out_dir);
}
out_dir
}
#[cfg(feature = "ffi")]
fn download_lib(out_dir: &PathBuf) {
let target = std::env::var("TARGET").unwrap();
let arch = match target.as_str() {
t if t.contains("aarch64") && t.contains("android") => "arm64-android",
t if t.contains("x86_64") && t.contains("android") => "x86_64-android",
t if t.contains("x86_64") && t.contains("linux") => "amd64-linux",
t if t.contains("aarch64") && t.contains("linux") => "arm64-linux",
t if t.contains("x86_64") && t.contains("apple") && t.contains("darwin") => "amd64-darwin",
t if t.contains("aarch64") && t.contains("apple") && t.contains("darwin") => "arm64-darwin",
t if t.contains("aarch64") && t.contains("apple") && t.contains("ios-sim") => {
"arm64-ios-sim"
}
t if t.contains("aarch64") && t.contains("apple") && t.contains("ios") => "arm64-ios",
_ => panic!(
"Unsupported target for FFI backend: {}. \
Supported: x86_64-linux, aarch64-linux, x86_64-apple-darwin, aarch64-apple-darwin, \
aarch64-apple-ios, aarch64-apple-ios-sim, aarch64-linux-android, x86_64-linux-android",
target
),
};
let version = std::env::var("BARRETENBERG_VERSION")
.unwrap_or_else(|_| env!("CARGO_PKG_VERSION").to_string());
if version.starts_with("0.") && std::env::var("BARRETENBERG_VERSION").is_err() {
panic!(
"Cannot download pre-built library for development version {}. \
Either set BARRETENBERG_VERSION to a released version, or \
set BB_LIB_DIR to point to a local build: cd barretenberg/cpp && ./bootstrap.sh",
version
);
}
let url = format!(
"https://github.com/AztecProtocol/aztec-packages/releases/download/v{}/barretenberg-static-{}.tar.gz",
version, arch
);
println!("cargo:warning=Downloading barretenberg static library from {}", url);
let tar_gz_path = out_dir.join("barretenberg-static.tar.gz");
let status = std::process::Command::new("curl")
.args(["-L", "-f", "-o"])
.arg(&tar_gz_path)
.arg(&url)
.status()
.expect("Failed to run curl");
if !status.success() {
panic!(
"Failed to download barretenberg static library from {}. \
Make sure version v{} exists as a GitHub release.",
url, version
);
}
let status = std::process::Command::new("tar")
.args(["-xzf"])
.arg(&tar_gz_path)
.arg("-C")
.arg(out_dir)
.status()
.expect("Failed to run tar");
if !status.success() {
panic!("Failed to extract barretenberg static library");
}
std::fs::remove_file(&tar_gz_path).ok();
}