Skip to content

Commit

Permalink
Merge pull request #16 from tuna-f1sh/udev-ci
Browse files Browse the repository at this point in the history
Add udev_hwdb feature and fix cross build with feature enabled
  • Loading branch information
tuna-f1sh committed Nov 22, 2023
2 parents d671571 + d6961d0 commit ee92043
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 52 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
fail-fast: false
matrix:
job:
# - { os: ubuntu-latest, target: aarch64-unknown-linux-gnu, use-cross: true }
- { os: ubuntu-latest, target: x86_64-pc-windows-gnu, use-cross: true }
- { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, use-cross: false }
- { os: macos-latest, target: universal-apple-darwin, use-cross: false }
- { os: ubuntu-latest, target: aarch64-unknown-linux-gnu, use-cross: true, feature-flags: "--all-features" }
- { os: ubuntu-latest, target: x86_64-pc-windows-gnu, use-cross: true, feature-flags: "--all-features" }
- { os: ubuntu-latest, target: x86_64-unknown-linux-gnu, use-cross: false, feature-flags: "--all-features" }
- { os: macos-latest, target: universal-apple-darwin, use-cross: false, feature-flags: "--all-features" }
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
Expand Down Expand Up @@ -90,14 +90,14 @@ jobs:
run: |
case ${{ matrix.job.target }} in
universal-apple-*)
cargo build --locked --release --all-features --target=aarch64-apple-darwin
cargo build --locked --release --all-features --target=x86_64-apple-darwin
cargo build --locked --release ${{ matrix.job.feature-flags }} --target=aarch64-apple-darwin
cargo build --locked --release ${{ matrix.job.feature-flags }} --target=x86_64-apple-darwin
mkdir -p target/universal-apple-darwin/release
# merge into universal
lipo -create -output target/universal-apple-darwin/release/cyme target/aarch64-apple-darwin/release/cyme target/x86_64-apple-darwin/release/cyme
;;
*)
${{ env.CARGO_CMD }} build --locked --release --all-features --target=${{ matrix.job.target }}
${{ env.CARGO_CMD }} build --locked --release ${{ matrix.job.feature-flags }} --target=${{ matrix.job.target }}
;;
esac
Expand Down
7 changes: 3 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 15 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ clap = { version = "4.0.22", features = ["derive", "wrap_help"] }
colored = "2.0.0"
itertools = "0.10.5"
lazy_static = "1.4.0"
rusb = { git = "https://github.com/tuna-f1sh/rusb.git", version = "0.9.1", optional = true }
rusb = { version = "0.9.1", optional = true }
log = "0.4.17"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.87"
Expand All @@ -32,25 +32,30 @@ terminal_size = "0.2.5"
strum = "0.24.1"
strum_macros = "0.24.3"

[patch.crates-io]
libudev-sys = { git = "https://github.com/Emilgardis/libudev-sys/", branch = "fix-cross-compilation" }
rusb = { git = "https://github.com/a1ien/rusb.git" }

[dev-dependencies]
diff = "0.1"
assert-json-diff = "2.0.2"

[target.x86_64-unknown-linux-gnu.dependencies]
udev = { version = "^0.8.0", optional = true, features = ["hwdb"] }
rusb = { git = "https://github.com/tuna-f1sh/rusb.git", version = "0.9.1" }
udev = { version = "^0.8.0", optional = true }
rusb = "0.9.1"

[target.arm-unknown-linux-gnueabihf.dependencies]
udev = { version = "^0.8.0", optional = true, features = ["hwdb"] }
rusb = { git = "https://github.com/tuna-f1sh/rusb.git", version = "0.9.1" }
udev = { version = "^0.8.0", optional = true }
rusb = "0.9.1"

[target.aarch64-unknown-linux-gnu.dependencies]
udev = { version = "^0.8.0", optional = true, features = ["hwdb"] }
rusb = { git = "https://github.com/tuna-f1sh/rusb.git", version = "0.9.1" }
udev = { version = "^0.8.0", optional = true }
rusb = "0.9.1"

[features]
libusb = ["dep:rusb"]
udev = ["dep:udev"]
udev_hwdb = ["udev/hwdb"]
usb_test = []
cli_generate = ["dep:clap_complete", "dep:clap_mangen"] # for generating man and completions
default = ["libusb"]
Expand All @@ -65,6 +70,9 @@ strip = true
panic = "abort"
codegen-units = 1 # quicker binary, slower build

# [package.metadata.cross.build]
# pre-build = ["dpkg --add-architecture $CROSS_DEB_ARCH && apt-get update && apt-get install --assume-yes libusb-1.0-0-dev:$CROSS_DEB_ARCH libudev-dev:$CROSS_DEB_ARCH"]

[package.metadata.cross.target.arm-unknown-linux-gnueabihf]
pre-build = ["dpkg --add-architecture armhf && apt-get update && apt-get install --assume-yes libusb-1.0-0-dev:armhf libudev-dev:armhf"]

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ The name comes from the technical term for the type of blossom on a Apple tree:
## Requirements

* Linux/Windows and pre-compiled targets require [libusb 1.0.0](https://libusb.info): `brew install libusb`, `sudo apt install libusb-1.0-0-dev` or one's package manager of choice.
* Linux pre-compiled and `--features udev` requires 'libudev-dev': `sudo apt install libudev-dev` or one's package manager of choice.
* Linux pre-compiled and `--features udev`/`--features udev_hwdb` requires 'libudev-dev': `sudo apt install libudev-dev` or one's package manager of choice.

For pre-compiled binaries, see the [releases](https://github.com/tuna-f1sh/cyme/releases).

Expand All @@ -68,7 +68,9 @@ More package managers to come/package distribution, please feel free to create a

## Linux udev

To obtain device and interface drivers being used on Linux like `lsusb`, one must install 'libudev-dev' via a package manager and the `--features udev` feature when building. Only supported on Linux targets.
To obtain device and interface drivers being used on Linux like `lsusb`, one must install 'libudev-dev' via a package manager and the `--features udev` feature when building. To lookup USB IDs from the udev hwdb as well (like `lsusb`) use `--features udev_hwdb`. Without hwdb, `cyme` will use the 'usb-ids' crate, which is the same source as the hwdb binary data but the bundled hwdb may differ due to customisations or last update ('usb-ids' will be most up to date).

Only supported on Linux targets.

## Alias `lsusb`

Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ pub mod icon;
pub mod lsusb;
pub mod system_profiler;
pub mod types;
#[cfg(target_os = "linux")]
#[cfg(feature = "udev")]
#[cfg(all(target_os = "linux", feature = "udev"))]
pub mod udev;
pub mod usb;

Expand Down
10 changes: 6 additions & 4 deletions src/lsusb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,15 +830,17 @@ pub mod names {
}

/// Wrapper around [`crate::udev::hwdb_get`] so that it can be 'used' without feature
///
/// Returns `Err` not `None` if feature is not enabled so that with unwrap_or hwdb can still return `None` if no match in db
#[allow(unused_variables)]
fn hwdb_get(modalias: &str, key: &'static str) -> Result<Option<String>, Error> {
#[cfg(all(target_os = "linux", feature = "udev"))]
return crate::udev::hwdb_get(modalias, key);
#[cfg(all(target_os = "linux", feature = "udev_hwdb"))]
return crate::udev::hwdb::get(modalias, key);

#[cfg(not(all(target_os = "linux", feature = "udev")))]
#[cfg(not(all(target_os = "linux", feature = "udev_hwdb")))]
return Err(Error::new(
ErrorKind::Unsupported,
"hwdb_get requires 'udev' feature",
"hwdb_get requires 'udev_hwdb' feature",
));
}
}
Expand Down
59 changes: 33 additions & 26 deletions src/udev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,34 +124,41 @@ pub fn get_udev_attribute<T: AsRef<std::ffi::OsStr> + std::fmt::Display>(
.map(|s| s.to_str().unwrap_or("").to_string()))
}

/// Lookup an entry in the udev hwdb given the `modalias` and `key`.
/// udev hwdb lookup functions
///
/// Should act like https://github.com/gregkh/usbutils/blob/master/names.c#L115
///
/// ```
/// use cyme::udev::hwdb_get;
///
/// let modalias = "usb:v1D6Bp0001";
/// let vendor = hwdb_get(&modalias, "ID_VENDOR_FROM_DATABASE").unwrap();
///
/// assert_eq!(vendor, Some("Linux Foundation".into()));
///
/// let modalias = "usb:v*p*d*dc03dsc01dp01*";
/// let vendor = hwdb_get(&modalias, "ID_USB_PROTOCOL_FROM_DATABASE").unwrap();
///
/// assert_eq!(vendor, Some("Keyboard".into()));
/// ```
pub fn hwdb_get(modalias: &str, key: &'static str) -> Result<Option<String>, Error> {
let hwdb = udevlib::Hwdb::new().map_err(|e| {
Error::new(
ErrorKind::Udev,
&format!("Failed to get hwdb: Error({})", e),
)
})?;
/// Protected by the `udev_hwdb` feature because 'libudev-sys' excludes hwdb ffi bindings if native udev does not support hwdb
#[cfg(feature = "udev_hwdb")]
pub mod hwdb {
use super::*;
/// Lookup an entry in the udev hwdb given the `modalias` and `key`.
///
/// Should act like https://github.com/gregkh/usbutils/blob/master/names.c#L115
///
/// ```
/// use cyme::udev;
///
/// let modalias = "usb:v1D6Bp0001";
/// let vendor = hwdb::get(&modalias, "ID_VENDOR_FROM_DATABASE").unwrap();
///
/// assert_eq!(vendor, Some("Linux Foundation".into()));
///
/// let modalias = "usb:v*p*d*dc03dsc01dp01*";
/// let vendor = hwdb::get(&modalias, "ID_USB_PROTOCOL_FROM_DATABASE").unwrap();
///
/// assert_eq!(vendor, Some("Keyboard".into()));
/// ```
pub fn get(modalias: &str, key: &'static str) -> Result<Option<String>, Error> {
let hwdb = udevlib::Hwdb::new().map_err(|e| {
Error::new(
ErrorKind::Udev,
&format!("Failed to get hwdb: Error({})", e),
)
})?;

Ok(hwdb
.query_one(&modalias.to_string(), &key.to_string())
.map(|s| s.to_str().unwrap_or("").to_string()))
Ok(hwdb
.query_one(&modalias.to_string(), &key.to_string())
.map(|s| s.to_str().unwrap_or("").to_string()))
}
}

#[cfg(test)]
Expand Down

0 comments on commit ee92043

Please sign in to comment.