use std::path::Path;
fn main() {
let out_dir = std::env::var("OUT_DIR").unwrap();
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_else(|_| std::env::consts::OS.to_string());
let ext = if target_os == "windows" { "exe" } else { "" };
let bin_name = if ext.is_empty() { "arduino-cli".to_string() } else { format!("arduino-cli.{}", ext) };
let bin_path = Path::new(&out_dir).join(&bin_name);
if !bin_path.exists() {
download_arduino_cli(&bin_path);
}
println!("cargo:rustc-env=ARDUINO_CLI_PATH={}", bin_path.display());
println!("cargo:rerun-if-changed=build.rs");
}
fn download_arduino_cli(dest: &Path) {
let version = "1.1.1";
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_else(|_| std::env::consts::OS.to_string());
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_else(|_| std::env::consts::ARCH.to_string());
let (os, archive_ext) = if target_os == "windows" {
("Windows", "zip")
} else if target_os == "macos" {
("macOS", "tar.gz")
} else {
("Linux", "tar.gz")
};
let arch = if target_arch == "aarch64" { "ARM64" } else { "64bit" };
let url = format!(
"https://github.com/arduino/arduino-cli/releases/download/v{version}/arduino-cli_{version}_{os}_{arch}.{archive_ext}"
);
let archive_path = format!("{}.{}", dest.display(), archive_ext);
let status = std::process::Command::new("curl")
.args(["-L", "--fail", "-o", &archive_path, &url])
.status()
.expect("curl not found — install curl to build loop-arduino");
assert!(status.success(), "failed to download arduino-cli from {url}");
if archive_ext == "zip" {
let out_parent = dest.parent().unwrap().display().to_string();
let status = std::process::Command::new("powershell")
.args([
"-NoProfile", "-Command",
&format!("Expand-Archive -LiteralPath '{}' -DestinationPath '{}' -Force", archive_path, out_parent),
])
.status()
.expect("powershell not found");
assert!(status.success(), "failed to extract arduino-cli zip");
let extracted = Path::new(&out_parent).join("arduino-cli.exe");
if extracted.exists() && extracted != dest {
std::fs::rename(&extracted, dest).unwrap();
}
} else {
let out_parent = dest.parent().unwrap().display().to_string();
let status = std::process::Command::new("tar")
.args(["-xzf", &archive_path, "-C", &out_parent, "arduino-cli"])
.status()
.expect("tar not found");
assert!(status.success(), "failed to extract arduino-cli tarball");
}
}