diff --git a/xbuild/src/devices/adb.rs b/xbuild/src/devices/adb.rs index 524fa172..4662ceac 100644 --- a/xbuild/src/devices/adb.rs +++ b/xbuild/src/devices/adb.rs @@ -1,6 +1,6 @@ use crate::devices::{Backend, Device}; use crate::{Arch, Platform}; -use anyhow::Result; +use anyhow::{Context, Result}; use apk::Apk; use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; @@ -11,8 +11,44 @@ use std::time::Duration; pub(crate) struct Adb(PathBuf); impl Adb { - pub fn which() -> Result { - Ok(Self(which::which(exe!("adb"))?)) + pub fn which() -> Result { + const ADB: &str = exe!("adb"); + + match which::which(ADB) { + Err(which::Error::CannotFindBinaryPath) => { + let sdk_path = { + let sdk_path = std::env::var("ANDROID_SDK_ROOT").ok(); + if sdk_path.is_some() { + eprintln!( + "Warning: Environment variable ANDROID_SDK_ROOT is deprecated \ + (https://developer.android.com/studio/command-line/variables#envar). \ + It will be used until it is unset and replaced by ANDROID_HOME." + ); + } + + PathBuf::from( + sdk_path + .or_else(|| std::env::var("ANDROID_HOME").ok()) + .context( + "Cannot find `adb` on in PATH nor is ANDROID_HOME/ANDROID_SDK_ROOT set", + )?, + ) + }; + + let adb_path = sdk_path.join("platform-tools").join(ADB); + anyhow::ensure!( + adb_path.exists(), + "Expected `adb` at `{}`", + adb_path.display() + ); + Ok(adb_path) + } + r => r.context("Could not find `adb` in PATH"), + } + } + + pub fn new() -> Result { + Ok(Self(Self::which()?)) } fn adb(&self, device: &str) -> Command { diff --git a/xbuild/src/devices/mod.rs b/xbuild/src/devices/mod.rs index 4274d9de..8a330d59 100644 --- a/xbuild/src/devices/mod.rs +++ b/xbuild/src/devices/mod.rs @@ -5,9 +5,9 @@ use crate::{Arch, BuildEnv, Platform}; use anyhow::Result; use std::path::Path; -mod adb; -mod host; -mod imd; +pub(crate) mod adb; +pub(crate) mod host; +pub(crate) mod imd; #[derive(Clone, Debug)] enum Backend { @@ -31,7 +31,7 @@ impl std::str::FromStr for Device { } if let Some((backend, id)) = device.split_once(':') { let backend = match backend { - "adb" => Backend::Adb(Adb::which()?), + "adb" => Backend::Adb(Adb::new()?), "imd" => Backend::Imd(IMobileDevice::which()?), _ => anyhow::bail!("unsupported backend {}", backend), }; @@ -58,7 +58,7 @@ impl std::fmt::Display for Device { impl Device { pub fn list() -> Result> { let mut devices = vec![Self::host()]; - if let Ok(adb) = Adb::which() { + if let Ok(adb) = Adb::new() { adb.devices(&mut devices)?; } if let Ok(imd) = IMobileDevice::which() {