Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cargo-apk: Add --device arg to select adb device by serial #329

Merged
merged 10 commits into from
Sep 7, 2022
2 changes: 2 additions & 0 deletions cargo-apk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Add `--device` argument to select `adb` device by serial (see `adb devices` for connected devices and their serial). ([#329](https://github.com/rust-windowing/android-ndk-rs/pull/329))

# 0.9.3 (2022-07-05)

- Allow configuration of alternate debug keystore location; require keystore location for release builds. ([#299](https://github.com/rust-windowing/android-ndk-rs/pull/299))
Expand Down
17 changes: 12 additions & 5 deletions cargo-apk/src/apk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@ pub struct ApkBuilder<'a> {
manifest: Manifest,
build_dir: PathBuf,
build_targets: Vec<Target>,
device_serial: Option<String>,
}

impl<'a> ApkBuilder<'a> {
pub fn from_subcommand(cmd: &'a Subcommand) -> Result<Self, Error> {
pub fn from_subcommand(
cmd: &'a Subcommand,
device_serial: Option<String>,
) -> Result<Self, Error> {
let ndk = Ndk::from_env()?;
let mut manifest = Manifest::parse_from_toml(cmd.manifest())?;
let build_targets = if let Some(target) = cmd.target() {
vec![Target::from_rust_triple(target)?]
} else if !manifest.build_targets.is_empty() {
manifest.build_targets.clone()
} else {
vec![ndk.detect_abi().unwrap_or(Target::Arm64V8a)]
vec![ndk
.detect_abi(device_serial.as_deref())
.unwrap_or(Target::Arm64V8a)]
};
let build_dir = dunce::simplified(cmd.target_dir())
.join(cmd.profile())
Expand Down Expand Up @@ -93,6 +99,7 @@ impl<'a> ApkBuilder<'a> {
manifest,
build_dir,
build_targets,
device_serial,
})
}

Expand Down Expand Up @@ -236,14 +243,14 @@ impl<'a> ApkBuilder<'a> {

pub fn run(&self, artifact: &Artifact) -> Result<(), Error> {
let apk = self.build(artifact)?;
apk.install()?;
apk.start()?;
apk.install(self.device_serial.as_deref())?;
apk.start(self.device_serial.as_deref())?;
Ok(())
}

pub fn gdb(&self, artifact: &Artifact) -> Result<(), Error> {
self.run(artifact)?;
let abi = self.ndk.detect_abi()?;
let abi = self.ndk.detect_abi(self.device_serial.as_deref())?;
let target_dir = self.build_dir.join(artifact);
let jni_dir = target_dir.join("jni");
std::fs::create_dir_all(&jni_dir)?;
Expand Down
23 changes: 21 additions & 2 deletions cargo-apk/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@ use std::process::Command;
fn main() -> anyhow::Result<()> {
env_logger::init();
let args = std::env::args();
let cmd = Subcommand::new(args, "apk", |_, _| Ok(false)).map_err(Error::Subcommand)?;
let builder = ApkBuilder::from_subcommand(&cmd)?;
let mut device_serial = None;
let cmd = Subcommand::new(args, "apk", |name, value| {
if name == "--device" {
if let Some(value) = value {
println!("Running on {}", value);
device_serial = Some(value.to_owned());
Ok(true)
} else {
Err(cargo_subcommand::Error::InvalidArgs)
}
} else {
Ok(false)
}
})
.map_err(Error::Subcommand)?;
let builder = ApkBuilder::from_subcommand(&cmd, device_serial)?;

match cmd.cmd() {
"check" | "c" => builder.check()?,
Expand All @@ -17,6 +31,7 @@ fn main() -> anyhow::Result<()> {
}
"run" | "r" => {
anyhow::ensure!(cmd.artifacts().len() == 1, Error::invalid_args());

builder.run(&cmd.artifacts()[0])?;
}
"--" => {
Expand Down Expand Up @@ -70,6 +85,10 @@ SUBCOMMAND:
run, r Run a binary or example of the local package
gdb Start a gdb session attached to an adb device with symbols loaded
version Print the version of cargo-apk

OPTIONS:
--device Serial of the device to use in `adb` commands. See `adb devices`
for a list of connected Android devices.
"#
);
}
Expand Down
2 changes: 2 additions & 0 deletions ndk-build/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased

- Add `adb` device serial parameter to `detect_abi()` and `Apk::{install,start}()`. ([#329](https://github.com/rust-windowing/android-ndk-rs/pull/329))

# 0.7.0 (2022-07-05)

- Fix NDK r23 `-lgcc` workaround for target directories containing spaces. ([#298](https://github.com/rust-windowing/android-ndk-rs/pull/298))
Expand Down
14 changes: 12 additions & 2 deletions ndk-build/src/apk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,27 @@ impl Apk {
}
}

pub fn install(&self) -> Result<(), NdkError> {
pub fn install(&self, device_serial: Option<&str>) -> Result<(), NdkError> {
let mut adb = self.ndk.platform_tool(bin!("adb"))?;

if let Some(device_serial) = device_serial {
adb.arg("-s").arg(device_serial);
}

adb.arg("install").arg("-r").arg(&self.path);
if !adb.status()?.success() {
return Err(NdkError::CmdFailed(adb));
}
Ok(())
}

pub fn start(&self) -> Result<(), NdkError> {
pub fn start(&self, device_serial: Option<&str>) -> Result<(), NdkError> {
let mut adb = self.ndk.platform_tool(bin!("adb"))?;

if let Some(device_serial) = device_serial {
adb.arg("-s").arg(device_serial);
}

adb.arg("shell")
.arg("am")
.arg("start")
Expand Down
11 changes: 8 additions & 3 deletions ndk-build/src/ndk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,14 @@ impl Ndk {
Err(NdkError::PlatformNotFound(min_sdk_version))
}

pub fn detect_abi(&self) -> Result<Target, NdkError> {
let stdout = self
.platform_tool("adb")?
pub fn detect_abi(&self, device_serial: Option<&str>) -> Result<Target, NdkError> {
let mut adb = self.platform_tool("adb")?;

if let Some(device_serial) = device_serial {
adb.arg("-s").arg(device_serial);
}

let stdout = adb
.arg("shell")
.arg("getprop")
.arg("ro.product.cpu.abi")
Expand Down