diff --git a/Cargo.toml b/Cargo.toml index 7c4aba1..de45d4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,12 +130,14 @@ opentelemetry = { version = "0.31", default-features = false, features = ["trace opentelemetry_sdk = { version = "0.31", default-features = false, features = ["trace", "metrics"] } opentelemetry-otlp = { version = "0.31", default-features = false, features = ["trace", "metrics", "http-proto", "reqwest-client", "reqwest-rustls-webpki-roots"] } -# USB device enumeration (hardware discovery) -nusb = { version = "0.2", default-features = false, optional = true } - # Serial port for peripheral communication (STM32, etc.) tokio-serial = { version = "5", default-features = false, optional = true } +# USB device enumeration (hardware discovery) — only on platforms nusb supports +# (Linux, macOS, Windows). Android/Termux uses target_os="android" and is excluded. +[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))'.dependencies] +nusb = { version = "0.2", default-features = false, optional = true } + # probe-rs for STM32/Nucleo memory read (Phase B) probe-rs = { version = "0.30", optional = true } diff --git a/src/hardware/discover.rs b/src/hardware/discover.rs index 4bbf31f..9f514da 100644 --- a/src/hardware/discover.rs +++ b/src/hardware/discover.rs @@ -1,4 +1,10 @@ //! USB device discovery — enumerate devices and enrich with board registry. +//! +//! USB enumeration via `nusb` is only supported on Linux, macOS, and Windows. +//! On Android (Termux) and other unsupported platforms this module is excluded +//! from compilation; callers in `hardware/mod.rs` fall back to an empty result. + +#![cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] use super::registry; use anyhow::Result; diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index 18f6dcc..d9dbc1c 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -4,10 +4,10 @@ pub mod registry; -#[cfg(feature = "hardware")] +#[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] pub mod discover; -#[cfg(feature = "hardware")] +#[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] pub mod introspect; use crate::config::Config; @@ -28,8 +28,9 @@ pub struct DiscoveredDevice { /// Auto-discover connected hardware devices. /// Returns an empty vec on platforms without hardware support. pub fn discover_hardware() -> Vec { - // USB/serial discovery is behind the "hardware" feature gate. - #[cfg(feature = "hardware")] + // USB/serial discovery is behind the "hardware" feature gate and only + // available on platforms where nusb supports device enumeration. + #[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] { if let Ok(devices) = discover::list_usb_devices() { return devices @@ -102,7 +103,15 @@ pub fn handle_command(cmd: crate::HardwareCommands, _config: &Config) -> Result< return Ok(()); } - #[cfg(feature = "hardware")] + #[cfg(all(feature = "hardware", not(any(target_os = "linux", target_os = "macos", target_os = "windows"))))] + { + let _ = &cmd; + println!("Hardware USB discovery is not supported on this platform."); + println!("Supported platforms: Linux, macOS, Windows."); + return Ok(()); + } + + #[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] match cmd { crate::HardwareCommands::Discover => run_discover(), crate::HardwareCommands::Introspect { path } => run_introspect(&path), @@ -110,7 +119,7 @@ pub fn handle_command(cmd: crate::HardwareCommands, _config: &Config) -> Result< } } -#[cfg(feature = "hardware")] +#[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] fn run_discover() -> Result<()> { let devices = discover::list_usb_devices()?; @@ -138,7 +147,7 @@ fn run_discover() -> Result<()> { Ok(()) } -#[cfg(feature = "hardware")] +#[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] fn run_introspect(path: &str) -> Result<()> { let result = introspect::introspect_device(path)?; @@ -160,7 +169,7 @@ fn run_introspect(path: &str) -> Result<()> { Ok(()) } -#[cfg(feature = "hardware")] +#[cfg(all(feature = "hardware", any(target_os = "linux", target_os = "macos", target_os = "windows")))] fn run_info(chip: &str) -> Result<()> { #[cfg(feature = "probe")] { @@ -192,7 +201,7 @@ fn run_info(chip: &str) -> Result<()> { } } -#[cfg(all(feature = "hardware", feature = "probe"))] +#[cfg(all(feature = "hardware", feature = "probe", any(target_os = "linux", target_os = "macos", target_os = "windows")))] fn info_via_probe(chip: &str) -> anyhow::Result<()> { use probe_rs::config::MemoryRegion; use probe_rs::{Session, SessionConfig};