diff options
-rw-r--r-- | hid/.gitignore | 2 | ||||
-rw-r--r-- | hid/Cargo.toml | 18 | ||||
-rw-r--r-- | hid/examples/list.rs | 24 | ||||
-rw-r--r-- | hid/src/device.rs | 122 | ||||
-rw-r--r-- | hid/src/devices.rs | 51 | ||||
-rw-r--r-- | hid/src/error.rs | 62 | ||||
-rw-r--r-- | hid/src/handle.rs | 224 | ||||
-rw-r--r-- | hid/src/lib.rs | 17 | ||||
-rw-r--r-- | hid/src/manager.rs | 56 | ||||
-rw-r--r-- | hidapi-sys/.gitignore | 2 | ||||
-rw-r--r-- | hidapi-sys/Cargo.toml | 24 | ||||
-rw-r--r-- | hidapi-sys/README.md | 10 | ||||
-rw-r--r-- | hidapi-sys/build.rs | 93 | ||||
-rw-r--r-- | hidapi-sys/src/lib.rs | 68 | ||||
-rw-r--r-- | nitrocli/CHANGELOG.md | 1 | ||||
-rw-r--r-- | nitrocli/Cargo.lock | 40 | ||||
-rw-r--r-- | nitrocli/Cargo.toml | 24 | ||||
-rw-r--r-- | nitrocli/src/error.rs | 2 | ||||
-rw-r--r-- | pkg-config/.gitignore | 4 | ||||
-rw-r--r-- | pkg-config/.travis.yml | 23 | ||||
-rw-r--r-- | pkg-config/CHANGELOG.md | 19 | ||||
-rw-r--r-- | pkg-config/Cargo.toml | 19 | ||||
-rw-r--r-- | pkg-config/LICENSE-APACHE | 201 | ||||
-rw-r--r-- | pkg-config/LICENSE-MIT | 25 | ||||
-rw-r--r-- | pkg-config/README.md | 73 | ||||
-rw-r--r-- | pkg-config/src/lib.rs | 630 | ||||
-rw-r--r-- | pkg-config/tests/escape.pc | 5 | ||||
-rw-r--r-- | pkg-config/tests/foo.pc | 16 | ||||
-rw-r--r-- | pkg-config/tests/framework.pc | 16 | ||||
-rw-r--r-- | pkg-config/tests/test.rs | 118 |
30 files changed, 1 insertions, 1988 deletions
diff --git a/hid/.gitignore b/hid/.gitignore deleted file mode 100644 index a9d37c5..0000000 --- a/hid/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -Cargo.lock diff --git a/hid/Cargo.toml b/hid/Cargo.toml deleted file mode 100644 index 5e608a8..0000000 --- a/hid/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "hid" -version = "0.4.1" - -authors = ["meh. <meh@schizofreni.co>"] -license = "WTFPL" - -description = "Safe hidapi wrapper" -repository = "https://github.com/meh/rust-hid" -keywords = ["hid"] - -[features] -static = ["hidapi-sys/static"] -build = ["static", "hidapi-sys/build"] - -[dependencies] -libc = "0.2.21" -hidapi-sys = "0.1.2" diff --git a/hid/examples/list.rs b/hid/examples/list.rs deleted file mode 100644 index da24bcb..0000000 --- a/hid/examples/list.rs +++ /dev/null @@ -1,24 +0,0 @@ -extern crate hid; - -fn main() { - let hid = hid::init().unwrap(); - - for device in hid.devices() { - print!("{} ", device.path().to_str().unwrap()); - print!("ID {:x}:{:x} ", device.vendor_id(), device.product_id()); - - if let Some(name) = device.manufacturer_string() { - print!("{} ", name); - } - - if let Some(name) = device.product_string() { - print!("{} ", name); - } - - if let Some(name) = device.serial_number() { - print!("{} ", name); - } - - println!(); - } -} diff --git a/hid/src/device.rs b/hid/src/device.rs deleted file mode 100644 index dc718c7..0000000 --- a/hid/src/device.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::marker::PhantomData; -use std::path::Path; -use std::ffi::CStr; - -use sys::*; -use libc::{size_t, wchar_t, wcstombs}; -use handle::Handle; -use error::{self, Error}; - -/// The HID device. -pub struct Device<'a> { - ptr: *const hid_device_info, - - _marker: PhantomData<&'a ()>, -} - -impl<'a> Device<'a> { - #[doc(hidden)] - pub unsafe fn new<'b>(ptr: *const hid_device_info) -> Device<'b> { - Device { - ptr: ptr, - - _marker: PhantomData, - } - } - - /// The path representation. - pub fn path(&self) -> &Path { - unsafe { - Path::new(CStr::from_ptr((*self.ptr).path).to_str().unwrap()) - } - } - - /// The vendor ID. - pub fn vendor_id(&self) -> u16 { - unsafe { - (*self.ptr).vendor_id - } - } - - /// The product ID. - pub fn product_id(&self) -> u16 { - unsafe { - (*self.ptr).product_id - } - } - - /// The serial number. - pub fn serial_number(&self) -> Option<String> { - unsafe { - (*self.ptr).serial_number.as_ref().and_then(|p| to_string(p)) - } - } - - /// The manufacturer string. - pub fn manufacturer_string(&self) -> Option<String> { - unsafe { - (*self.ptr).manufacturer_string.as_ref().and_then(|p| to_string(p)) - } - } - - /// The product string. - pub fn product_string(&self) -> Option<String> { - unsafe { - (*self.ptr).product_string.as_ref().and_then(|p| to_string(p)) - } - } - - /// The release number. - pub fn release_number(&self) -> u16 { - unsafe { - (*self.ptr).release_number - } - } - - /// The usage page. - pub fn usage_page(&self) -> u16 { - unsafe { - (*self.ptr).usage_page - } - } - - /// The usage number. - pub fn usage(&self) -> u16 { - unsafe { - (*self.ptr).usage - } - } - - /// The interface number. - pub fn interface_number(&self) -> isize { - unsafe { - (*self.ptr).interface_number as isize - } - } - - /// Opens the device to use it. - pub fn open(&self) -> error::Result<Handle> { - unsafe { - let handle = hid_open((*self.ptr).vendor_id, (*self.ptr).product_id, (*self.ptr).serial_number); - - if handle.is_null() { - return Err(Error::NotFound); - } - - Ok(Handle::new(handle)) - } - } -} - -#[inline] -unsafe fn to_string(value: *const wchar_t) -> Option<String> { - // USB descriptors are limited to 255 bytes. - let mut buffer = [0u8; 256]; - let length = wcstombs(buffer.as_mut_ptr() as *mut _, value, buffer.len()); - - if length == size_t::max_value() { - return None; - } - - Some(String::from_utf8_lossy(&buffer[0.. length as usize]).into_owned()) -} diff --git a/hid/src/devices.rs b/hid/src/devices.rs deleted file mode 100644 index 002ffa9..0000000 --- a/hid/src/devices.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::marker::PhantomData; - -use sys::*; -use Device; - -/// An iterator over the available devices. -pub struct Devices<'a> { - ptr: *mut hid_device_info, - cur: *mut hid_device_info, - - _marker: PhantomData<&'a ()>, -} - -impl<'a> Devices<'a> { - #[doc(hidden)] - pub unsafe fn new(vendor: Option<u16>, product: Option<u16>) -> Self { - let list = hid_enumerate(vendor.unwrap_or(0), product.unwrap_or(0)); - - Devices { - ptr: list, - cur: list, - - _marker: PhantomData, - } - } -} - -impl<'a> Iterator for Devices<'a> { - type Item = Device<'a>; - - fn next(&mut self) -> Option<Self::Item> { - if self.cur.is_null() { - return None; - } - - unsafe { - let info = Device::new(self.cur); - self.cur = (*self.cur).next; - - Some(info) - } - } -} - -impl<'a> Drop for Devices<'a> { - fn drop(&mut self) { - unsafe { - hid_free_enumeration(self.ptr); - } - } -} diff --git a/hid/src/error.rs b/hid/src/error.rs deleted file mode 100644 index 367f47f..0000000 --- a/hid/src/error.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::ffi::CStr; -use libc::c_int; -use sys::*; -use std::{error, fmt}; - -#[derive(Clone, PartialEq, Eq, Debug)] -pub enum Error { - Initialized, - NotFound, - General, - Write, - Read, - String(String), -} - -pub type Result<T> = ::std::result::Result<T, Error>; - -impl From<c_int> for Error { - fn from(value: c_int) -> Error { - match value { - _ => Error::General - } - } -} - -impl From<*mut hid_device> for Error { - fn from(value: *mut hid_device) -> Error { - unsafe { - Error::String(CStr::from_ptr(hid_error(value) as *const _).to_str().unwrap().to_owned()) - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(error::Error::description(self)) - } -} - -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::Initialized => - "Already initialized.", - - Error::NotFound => - "Device not found.", - - Error::General => - "General error.", - - Error::Write => - "Write error.", - - Error::Read => - "Read error.", - - Error::String(ref err) => - err, - } - } -} diff --git a/hid/src/handle.rs b/hid/src/handle.rs deleted file mode 100644 index d0eb090..0000000 --- a/hid/src/handle.rs +++ /dev/null @@ -1,224 +0,0 @@ -use std::time::Duration; - -use libc::c_int; -use sys::*; -use error::{self, Error}; - -/// A device handle. -pub struct Handle { - ptr: *mut hid_device, -} - -impl Handle { - #[doc(hidden)] - pub unsafe fn new(ptr: *mut hid_device) -> Self { - Handle { - ptr: ptr, - } - } - - #[doc(hidden)] - pub unsafe fn as_ptr(&self) -> *const hid_device { - self.ptr as *const _ - } - - #[doc(hidden)] - pub unsafe fn as_mut_ptr(&mut self) -> *mut hid_device { - self.ptr - } -} - -impl Handle { - /// Set the handle in blocking or non-blocking mode. - pub fn blocking(&mut self, value: bool) -> error::Result<&mut Self> { - unsafe { - match hid_set_nonblocking(self.as_mut_ptr(), if value { 1 } else { 0 }) { - 0 => - Ok(self), - - _ => - Err(Error::General) - } - } - } - - /// The data accessor. - pub fn data(&mut self) -> Data { - unsafe { - Data::new(self) - } - } - - /// The feature accessor. - pub fn feature(&mut self) -> Feature { - unsafe { - Feature::new(self) - } - } -} - -/// The data accessor. -pub struct Data<'a> { - handle: &'a mut Handle, -} - -impl<'a> Data<'a> { - #[doc(hidden)] - pub unsafe fn new(handle: &mut Handle) -> Data { - Data { handle: handle } - } - - /// Write data to the device. - /// - /// The first byte must be the report ID. - pub fn write<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> { - let data = data.as_ref(); - - unsafe { - match hid_write(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) { - -1 => - Err(Error::Write), - - length => - Ok(length as usize) - } - } - } - - /// Write data to the device with the given report ID. - pub fn write_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> { - let data = data.as_ref(); - let mut buffer = vec![0u8; data.len() + 1]; - - buffer[0] = id; - (&mut buffer[1 ..]).copy_from_slice(data); - - self.write(&buffer) - } - - /// Read data from the device. - /// - /// If the device supports reports the first byte will contain the report ID. - /// - /// Returns the amount of read bytes or `None` if there was a timeout. - pub fn read<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<usize>> { - let data = data.as_mut(); - let result = if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { - unsafe { - hid_read(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len()) - } - } - else { - unsafe { - // Timeout is in milliseconds. - hid_read_timeout(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len(), - timeout.as_secs() as c_int * 1_000 + timeout.subsec_nanos() as c_int / 1_000_000) - } - }; - - match result { - -1 => - Err(Error::Read), - - 0 => - Ok(None), - - v => - Ok(Some(v as usize)) - } - } - - /// Read data from the device. - /// - /// Returns the report ID and the amount of read bytes or `None` if there was a timeout. - pub fn read_from<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<(u8, usize)>> { - let data = data.as_mut(); - let mut buffer = Vec::with_capacity(data.len() + 1); - - if let Some(length) = self.read(&mut buffer, timeout)? { - data[0..length - 1].copy_from_slice(&buffer[1..length]); - - Ok(Some((buffer[0], length - 1))) - } - else { - Ok(None) - } - } -} - -/// The feature accessor. -pub struct Feature<'a> { - handle: &'a mut Handle, -} - -impl<'a> Feature<'a> { - #[doc(hidden)] - pub unsafe fn new(handle: &mut Handle) -> Feature { - Feature { handle: handle } - } - - /// Send a feature request. - /// - /// The first byte must be the report ID. - pub fn send<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> { - let data = data.as_ref(); - - unsafe { - match hid_send_feature_report(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) { - -1 => - Err(Error::Write), - - length => - Ok(length as usize) - } - } - } - - /// Send a feature request to the given report ID. - pub fn send_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> { - let data = data.as_ref(); - let mut buffer = Vec::with_capacity(data.len() + 1); - - buffer.push(id); - buffer.extend(data); - - self.send(&buffer).map(|v| v - 1) - } - - /// Get a feature request. - /// - /// The first byte must be the report ID. - pub fn get<T: AsMut<[u8]>>(&mut self, mut data: T) -> error::Result<usize> { - let data = data.as_mut(); - - unsafe { - match hid_get_feature_report(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len()) { - -1 => - Err(Error::Read), - - length => - Ok(length as usize) - } - } - } - - /// Get a feature request from the given report ID. - pub fn get_from<T: AsMut<[u8]>>(&mut self, id: u8, mut data: T) -> error::Result<usize> { - let data = data.as_mut(); - let mut buffer = vec![0u8; data.len() + 1]; - buffer[0] = id; - - let length = self.get(&mut buffer)?; - data[0..length - 1].copy_from_slice(&buffer[1..length]); - - Ok(length - 1) - } -} - -impl Drop for Handle { - fn drop(&mut self) { - unsafe { - hid_close(self.as_mut_ptr()); - } - } -} diff --git a/hid/src/lib.rs b/hid/src/lib.rs deleted file mode 100644 index fb2ccf8..0000000 --- a/hid/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -extern crate hidapi_sys as sys; -extern crate libc; - -mod error; -pub use error::{Error, Result}; - -mod manager; -pub use manager::{Manager, init}; - -mod devices; -pub use devices::Devices; - -mod device; -pub use device::Device; - -pub mod handle; -pub use handle::Handle; diff --git a/hid/src/manager.rs b/hid/src/manager.rs deleted file mode 100644 index 4c2eb23..0000000 --- a/hid/src/manager.rs +++ /dev/null @@ -1,56 +0,0 @@ -use std::sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; - -use sys::*; -use error::{self, Error}; -use devices::Devices; - -static INITIALIZED: AtomicBool = ATOMIC_BOOL_INIT; - -/// The device manager. -pub struct Manager; - -unsafe impl Send for Manager { } - -/// Create the manager. -pub fn init() -> error::Result<Manager> { - if INITIALIZED.load(Ordering::Relaxed) { - return Err(Error::Initialized); - } - - let status = unsafe { hid_init() }; - - if status != 0 { - return Err(Error::from(status)); - } - - INITIALIZED.store(true, Ordering::Relaxed); - - Ok(Manager) -} - -impl Drop for Manager { - fn drop(&mut self) { - let status = unsafe { hid_exit() }; - - if status != 0 { - panic!("hid_exit() failed"); - } - - INITIALIZED.store(false, Ordering::Relaxed); - } -} - -impl Manager { - /// Find the wanted device, `vendor` or `product` are given it will - /// returns only the matches devices. - pub fn find(&self, vendor: Option<u16>, product: Option<u16>) -> Devices { - unsafe { - Devices::new(vendor, product) - } - } - - /// Return all devices. - pub fn devices(&self) -> Devices { - self.find(None, None) - } -} diff --git a/hidapi-sys/.gitignore b/hidapi-sys/.gitignore deleted file mode 100644 index a9d37c5..0000000 --- a/hidapi-sys/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -target -Cargo.lock diff --git a/hidapi-sys/Cargo.toml b/hidapi-sys/Cargo.toml deleted file mode 100644 index 3483b34..0000000 --- a/hidapi-sys/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -name = "hidapi-sys" -version = "0.1.4" -build = "build.rs" -links = "hidapi" - -authors = ["meh. <meh@schizofreni.co>"] -license = "WTFPL" - -description = "FFI bindings to hidapi" -repository = "https://github.com/meh/rust-hidapi-sys" -keywords = ["hid"] -categories = ["external-ffi-bindings", "hardware-support", "os"] - -[features] -static = [] -build = ["static"] - -[dependencies] -libc = "0.2" - -[build-dependencies] -cc = "1.0" -pkg-config = "0.3" diff --git a/hidapi-sys/README.md b/hidapi-sys/README.md deleted file mode 100644 index 89048b1..0000000 --- a/hidapi-sys/README.md +++ /dev/null @@ -1,10 +0,0 @@ -hidapi-sys [![WTFPL](http://img.shields.io/badge/license-WTFPL-blue.svg)](http://www.wtfpl.net/txt/copying) -========== -Bindings for hidapi with support for building sources automatically. - -Requirements ------------- -`gcc` and `pkg-config` are required for building source automatically. - -`git` is required unless `HIDAPI_PATH` is exported to an existing checkout of -hidapi sources. diff --git a/hidapi-sys/build.rs b/hidapi-sys/build.rs deleted file mode 100644 index 4a392c6..0000000 --- a/hidapi-sys/build.rs +++ /dev/null @@ -1,93 +0,0 @@ -extern crate cc; -extern crate pkg_config; - -use std::env; -use std::io; -use std::path::PathBuf; -use std::process::Command; - -fn main() { - if env::var("CARGO_FEATURE_BUILD").is_err() { - return; - } - - fetch().expect("failed to checkout hidapi sources, internet connection and git are needed"); - build().expect("failed to build hidapi sources"); - - println!("cargo:rustc-link-search=native={}", output().to_string_lossy()); -} - -fn output() -> PathBuf { - PathBuf::from(env::var("OUT_DIR").unwrap()) -} - -fn source() -> PathBuf { - if let Ok(path) = env::var("HIDAPI_PATH") { - path.into() - } - else { - output().join("hidapi") - } -} - -fn fetch() -> io::Result<()> { - if env::var("HIDAPI_PATH").is_ok() { - return Ok(()); - } - - Command::new("git") - .current_dir(&output()) - .arg("clone") - .arg("https://github.com/signal11/hidapi.git") - .arg("hidapi") - .status()?; - - Ok(()) -} - -#[cfg(target_os = "linux")] -fn build() -> io::Result<()> { - let mut build = cc::Build::new(); - - build.file(source().join("libusb/hid.c")); - build.include(source().join("hidapi")); - build.static_flag(true); - - for path in pkg_config::find_library("libusb-1.0").unwrap().include_paths { - build.include(path.to_str().unwrap()); - } - - build.compile("libhidapi-libusb.a"); - - Ok(()) -} - -#[cfg(target_os = "macos")] -fn build() -> io::Result<()> { - let mut build = cc::Build::new(); - - build.file(source().join("libusb/hid.c")); - build.include(source().join("hidapi")); - build.static_flag(true); - - for path in pkg_config::find_library("libusb-1.0").unwrap().include_paths { - build.include(path.to_str().unwrap()); - } - - build.compile("libhidapi.a"); - - Ok(()) -} - -#[cfg(target_os = "windows")] -fn build() -> io::Result<()> { - let mut build = cc::Build::new(); - - build.file(source().join("windows/hid.c")); - build.include(source().join("hidapi")); - build.static_flag(true); - - build.compile("libhidapi.a"); - - Ok(()) -} diff --git a/hidapi-sys/src/lib.rs b/hidapi-sys/src/lib.rs deleted file mode 100644 index 656bd47..0000000 --- a/hidapi-sys/src/lib.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] - -extern crate libc; - -use libc::{c_void, c_ushort, wchar_t, c_int, c_uchar, size_t, c_char}; - -pub type hid_device = c_void; - -#[repr(C)] -pub struct hid_device_info { - pub path: *mut c_char, - - pub vendor_id: c_ushort, - pub product_id: c_ushort, - - pub serial_number: *mut wchar_t, - pub release_number: c_ushort, - - pub manufacturer_string: *mut wchar_t, - pub product_string: *mut wchar_t, - - pub usage_page: c_ushort, - pub usage: c_ushort, - - pub interface_number: c_int, - - pub next: *mut hid_device_info, -} - -#[cfg_attr(target_os = "linux", link(name = "udev"))] -extern "C" { } - -#[cfg_attr(target_os = "windows", link(name = "setupapi"))] -extern "C" { } - -#[cfg_attr(all(feature = "static", target_os = "linux"), link(name = "hidapi-libusb", kind = "static"))] -#[cfg_attr(all(not(feature = "static"), target_os = "linux"), link(name = "hidapi-libusb"))] -#[cfg_attr(all(feature = "static", not(target_os = "linux")), link(name = "hidapi", kind = "static"))] -#[cfg_attr(all(not(feature = "static"), not(target_os = "linux")), link(name = "hidapi"))] -extern "C" { - pub fn hid_init() -> c_int; - pub fn hid_exit() -> c_int; - - pub fn hid_enumerate(vendor_id: c_ushort, product_id: c_ushort) -> *mut hid_device_info; - pub fn hid_free_enumeration(devs: *mut hid_device_info); - - pub fn hid_open(vendor_id: c_ushort, product_id: c_ushort, serial_number: *const wchar_t) -> *mut hid_device; - pub fn hid_open_path(path: *const c_char) -> *mut hid_device; - - pub fn hid_write(device: *mut hid_device, data: *const c_uchar, length: size_t) -> c_int; - - pub fn hid_read_timeout(device: *mut hid_device, data: *mut c_uchar, length: size_t, milleseconds: c_int) -> c_int; - pub fn hid_read(device: *mut hid_device, data: *mut c_uchar, length: size_t) -> c_int; - - pub fn hid_set_nonblocking(device: *mut hid_device, nonblock: c_int) -> c_int; - - pub fn hid_send_feature_report(device: *mut hid_device, data: *const c_uchar, length: size_t) -> c_int; - pub fn hid_get_feature_report(device: *mut hid_device, data: *mut c_uchar, length: size_t) -> c_int; - - pub fn hid_close(device: *mut hid_device); - - pub fn hid_get_manufacturer_string(device: *mut hid_device, string: *mut wchar_t, maxlen: size_t) -> c_int; - pub fn hid_get_product_string(device: *mut hid_device, string: *mut wchar_t, maxlen: size_t) -> c_int; - pub fn hid_get_serial_number_string(device: *mut hid_device, string: *mut wchar_t, maxlen: size_t) -> c_int; - pub fn hid_get_indexed_string(device: *mut hid_device, string_index: c_int, string: *mut wchar_t, maxlen: size_t) -> c_int; - - pub fn hid_error(device: *mut hid_device) -> *const wchar_t; -} diff --git a/nitrocli/CHANGELOG.md b/nitrocli/CHANGELOG.md index c8985f3..6ed2a1d 100644 --- a/nitrocli/CHANGELOG.md +++ b/nitrocli/CHANGELOG.md @@ -5,6 +5,7 @@ Unreleased - Added `nitrokey` version `0.2.1` as a direct dependency and `nitrokey-sys` version `3.4.1` as well as `rand` version `0.4.3` as indirect dependencies + - Removed the `hid`, `hidapi-sys` and `pkg-config` dependencies 0.1.3 diff --git a/nitrocli/Cargo.lock b/nitrocli/Cargo.lock index a21d95c..4f6a80e 100644 --- a/nitrocli/Cargo.lock +++ b/nitrocli/Cargo.lock @@ -28,29 +28,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "hid" -version = "0.4.1" -dependencies = [ - "hidapi-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hidapi-sys" -version = "0.1.4" -dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "hidapi-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -replace = "hidapi-sys 0.1.4" - -[[package]] name = "libc" version = "0.2.45" @@ -64,12 +41,7 @@ replace = "libc 0.2.45" name = "nitrocli" version = "0.1.3" dependencies = [ - "cc 1.0.25", - "hid 0.4.1", - "hidapi-sys 0.1.4", - "libc 0.2.45", "nitrokey 0.2.1", - "pkg-config 0.3.14", ] [[package]] @@ -95,16 +67,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" replace = "nitrokey-sys 3.4.1" [[package]] -name = "pkg-config" -version = "0.3.14" - -[[package]] -name = "pkg-config" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -replace = "pkg-config 0.3.14" - -[[package]] name = "rand" version = "0.4.3" dependencies = [ @@ -143,10 +105,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum hidapi-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "dd8a9410aec7ca9f4571ff40c7b1813a28503c2a664a028921fc973073dcd4bf" "checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" "checksum nitrokey-sys 3.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "34794d630d40a093a3f0e31b821b38ee1c16e6909dc42064feff28f4798484f4" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" diff --git a/nitrocli/Cargo.toml b/nitrocli/Cargo.toml index 83e6888..8d1519a 100644 --- a/nitrocli/Cargo.toml +++ b/nitrocli/Cargo.toml @@ -32,38 +32,14 @@ description = """ A command line tool for interacting with the Nitrokey Storage device. """ -[dependencies.cc] -version = "1.0" -path = "../cc" - -[dependencies.hidapi-sys] -version = "0.1" -path = "../hidapi-sys" - -[dependencies.libc] -version = "0.2" -path = "../libc" - -[dependencies.libhid] -version = "0.4" -path = "../hid" -package = "hid" - [dependencies.libnitrokey] version = "0.2.1" path = "../nitrokey" package = "nitrokey" -[dependencies.pkg-config] -version = "0.3" -path = "../pkg-config" [replace] "cc:1.0.25" = { path = "../cc" } -"hidapi-sys:0.1.4" = { path = "../hidapi-sys" } "libc:0.2.45" = { path = "../libc" } -"libhid:0.4.1" = { path = "../hid" } -"libnitrokey:0.2.1" = { path = "../nitrokey" } "nitrokey-sys:3.4.1" = { path = "../nitrokey-sys" } -"pkg-config:0.3.14" = { path = "../pkg-config" } "rand:0.4.3" = { path = "../rand" } diff --git a/nitrocli/src/error.rs b/nitrocli/src/error.rs index 80d9d92..1b7068d 100644 --- a/nitrocli/src/error.rs +++ b/nitrocli/src/error.rs @@ -21,8 +21,6 @@ use std::fmt; use std::io; use std::string; -use libhid; - #[derive(Debug)] pub enum Error { diff --git a/pkg-config/.gitignore b/pkg-config/.gitignore deleted file mode 100644 index d6904d2..0000000 --- a/pkg-config/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/target -/Cargo.lock -.idea -*.iml diff --git a/pkg-config/.travis.yml b/pkg-config/.travis.yml deleted file mode 100644 index f184052..0000000 --- a/pkg-config/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: rust -rust: - - stable - - beta - - nightly -sudo: false -before_script: - - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH -script: - - cargo build --verbose - - cargo test --verbose - - cargo doc --no-deps -after_success: - - travis-cargo --only nightly doc-upload -env: - global: - secure: "D/GKEEBQarjXTZ6NWzwQq39nQ892XJ9m3C9219K/6Us8jyjE5DBhosDPvg6pvRJtTLaghDxuhxqkHunayNL18IOvkNbfMjYsnkP8/yMftQUfRdNub6C1kXAi8guXjPd8rUwW0Oy8Nar61WAwWQgHkXfuSJ2em7u/Xk0tICPSwlA=" - - - -notifications: - email: - on_success: never diff --git a/pkg-config/CHANGELOG.md b/pkg-config/CHANGELOG.md deleted file mode 100644 index 3f56db1..0000000 --- a/pkg-config/CHANGELOG.md +++ /dev/null @@ -1,19 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [0.3.10] - 2018-04-23 - -### Added -- Allow static linking of /usr/ on macOS (#42) -- Add support for parsing `-Wl,` style framework flags (#48) -- Parse defines in `pkg-config` output (#49) -- Rerun on `PKG_CONFIG_PATH` changes (#50) -- Introduce target-scoped variables (#58) -- Respect pkg-config escaping rules used with --cflags and --libs (#61) - -### Changed -- Use `?` instead of `try!()` in the codebase (#63) diff --git a/pkg-config/Cargo.toml b/pkg-config/Cargo.toml deleted file mode 100644 index 6f06af5..0000000 --- a/pkg-config/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] - -name = "pkg-config" -version = "0.3.14" -authors = ["Alex Crichton <alex@alexcrichton.com>"] -license = "MIT/Apache-2.0" -repository = "https://github.com/alexcrichton/pkg-config-rs" -documentation = "https://docs.rs/pkg-config" -description = """ -A library to run the pkg-config system tool at build time in order to be used in -Cargo build scripts. -""" -keywords = ["build-dependencies"] - -[badges] -travis-ci = { repository = "alexcrichton/pkg-config-rs" } - -[dev-dependencies] -lazy_static = "1" diff --git a/pkg-config/LICENSE-APACHE b/pkg-config/LICENSE-APACHE deleted file mode 100644 index 16fe87b..0000000 --- a/pkg-config/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/pkg-config/LICENSE-MIT b/pkg-config/LICENSE-MIT deleted file mode 100644 index 39e0ed6..0000000 --- a/pkg-config/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2014 Alex Crichton - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/pkg-config/README.md b/pkg-config/README.md deleted file mode 100644 index cb9ebd5..0000000 --- a/pkg-config/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# pkg-config-rs - -[![Build Status](https://travis-ci.org/alexcrichton/pkg-config-rs.svg?branch=master)](https://travis-ci.org/alexcrichton/pkg-config-rs) -[![Rust](https://img.shields.io/badge/rust-1.13%2B-blue.svg?maxAge=3600)](https://github.com/alexcrichton/pkg-config-rs/) - -[Documentation](https://docs.rs/pkg-config) - -A simple library meant to be used as a build dependency with Cargo packages in -order to use the system `pkg-config` tool (if available) to determine where a -library is located. - -You can use this crate directly to probe for specific libraries, or use -[metadeps](https://github.com/joshtriplett/metadeps) to declare all your -`pkg-config` dependencies in `Cargo.toml`. - -This library requires Rust 1.13+. - -# Example - -Find the system library named `foo`, with minimum version 1.2.3: - -```rust -extern crate pkg_config; - -fn main() { - pkg_config::Config::new().atleast_version("1.2.3").probe("foo").unwrap(); -} -``` - -Find the system library named `foo`, with no version requirement (not -recommended): - -```rust -extern crate pkg_config; - -fn main() { - pkg_config::probe_library("foo").unwrap(); -} -``` - -# External configuration via target-scoped environment variables - -In cross-compilation context, it is useful to manage separately PKG_CONFIG_PATH -and a few other variables for the `host` and the `target` platform. - -The supported variables are: `PKG_CONFIG_PATH`, `PKG_CONFIG_LIBDIR`, and -`PKG_CONFIG_SYSROOT_DIR`. - -Each of these variables can also be supplied with certain prefixes and suffixes, in the following prioritized order: - -1. `<var>_<target>` - for example, `PKG_CONFIG_PATH_x86_64-unknown-linux-gnu` -2. `<var>_<target_with_underscores>` - for example, `PKG_CONFIG_PATH_x86_64_unknown_linux_gnu` -3. `<build-kind>_<var>` - for example, `HOST_PKG_CONFIG_PATH` or `TARGET_PKG_CONFIG_PATH` -4. `<var>` - a plain `PKG_CONFIG_PATH` - -Also note that `PKG_CONFIG_ALLOW_CROSS` must always be set in cross-compilation context. - -# License - -This project is licensed under either of - - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) - -at your option. - -### Contribution - -Unless you explicitly state otherwise, any contribution intentionally submitted -for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be -dual licensed as above, without any additional terms or conditions. diff --git a/pkg-config/src/lib.rs b/pkg-config/src/lib.rs deleted file mode 100644 index 88dd310..0000000 --- a/pkg-config/src/lib.rs +++ /dev/null @@ -1,630 +0,0 @@ -//! A build dependency for Cargo libraries to find system artifacts through the -//! `pkg-config` utility. -//! -//! This library will shell out to `pkg-config` as part of build scripts and -//! probe the system to determine how to link to a specified library. The -//! `Config` structure serves as a method of configuring how `pkg-config` is -//! invoked in a builder style. -//! -//! A number of environment variables are available to globally configure how -//! this crate will invoke `pkg-config`: -//! -//! * `PKG_CONFIG_ALLOW_CROSS` - if this variable is not set, then `pkg-config` -//! will automatically be disabled for all cross compiles. -//! * `FOO_NO_PKG_CONFIG` - if set, this will disable running `pkg-config` when -//! probing for the library named `foo`. -//! -//! There are also a number of environment variables which can configure how a -//! library is linked to (dynamically vs statically). These variables control -//! whether the `--static` flag is passed. Note that this behavior can be -//! overridden by configuring explicitly on `Config`. The variables are checked -//! in the following order: -//! -//! * `FOO_STATIC` - pass `--static` for the library `foo` -//! * `FOO_DYNAMIC` - do not pass `--static` for the library `foo` -//! * `PKG_CONFIG_ALL_STATIC` - pass `--static` for all libraries -//! * `PKG_CONFIG_ALL_DYNAMIC` - do not pass `--static` for all libraries -//! -//! After running `pkg-config` all appropriate Cargo metadata will be printed on -//! stdout if the search was successful. -//! -//! # Example -//! -//! Find the system library named `foo`, with minimum version 1.2.3: -//! -//! ```no_run -//! extern crate pkg_config; -//! -//! fn main() { -//! pkg_config::Config::new().atleast_version("1.2.3").probe("foo").unwrap(); -//! } -//! ``` -//! -//! Find the system library named `foo`, with no version requirement (not -//! recommended): -//! -//! ```no_run -//! extern crate pkg_config; -//! -//! fn main() { -//! pkg_config::probe_library("foo").unwrap(); -//! } -//! ``` -//! -//! Configure how library `foo` is linked to. -//! -//! ```no_run -//! extern crate pkg_config; -//! -//! fn main() { -//! pkg_config::Config::new().atleast_version("1.2.3").statik(true).probe("foo").unwrap(); -//! } -//! ``` - -#![doc(html_root_url = "https://docs.rs/pkg-config/0.3")] - -#[allow(unused_imports)] // Required for Rust <1.23 -use std::ascii::AsciiExt; -use std::collections::HashMap; -use std::env; -use std::error; -use std::ffi::{OsStr, OsString}; -use std::fmt; -use std::io; -use std::path::{PathBuf, Path}; -use std::process::{Command, Output}; -use std::str; - -pub fn target_supported() -> bool { - let target = env::var("TARGET").unwrap_or_else(|_| String::new()); - let host = env::var("HOST").unwrap_or_else(|_| String::new()); - - // Only use pkg-config in host == target situations by default (allowing an - // override). - (host == target || env::var_os("PKG_CONFIG_ALLOW_CROSS").is_some()) -} - -#[derive(Clone, Default)] -pub struct Config { - statik: Option<bool>, - atleast_version: Option<String>, - extra_args: Vec<OsString>, - cargo_metadata: bool, - env_metadata: bool, - print_system_libs: bool, -} - -#[derive(Debug)] -pub struct Library { - pub libs: Vec<String>, - pub link_paths: Vec<PathBuf>, - pub frameworks: Vec<String>, - pub framework_paths: Vec<PathBuf>, - pub include_paths: Vec<PathBuf>, - pub defines: HashMap<String, Option<String>>, - pub version: String, - _priv: (), -} - -/// Represents all reasons `pkg-config` might not succeed or be run at all. -pub enum Error { - /// Aborted because of `*_NO_PKG_CONFIG` environment variable. - /// - /// Contains the name of the responsible environment variable. - EnvNoPkgConfig(String), - - /// Cross compilation detected. - /// - /// Override with `PKG_CONFIG_ALLOW_CROSS=1`. - CrossCompilation, - - /// Failed to run `pkg-config`. - /// - /// Contains the command and the cause. - Command { command: String, cause: io::Error }, - - /// `pkg-config` did not exit sucessfully. - /// - /// Contains the command and output. - Failure { command: String, output: Output }, - - #[doc(hidden)] - // please don't match on this, we're likely to add more variants over time - __Nonexhaustive, -} - -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::EnvNoPkgConfig(_) => "pkg-config requested to be aborted", - Error::CrossCompilation => { - "pkg-config doesn't handle cross compilation. \ - Use PKG_CONFIG_ALLOW_CROSS=1 to override" - } - Error::Command { .. } => "failed to run pkg-config", - Error::Failure { .. } => "pkg-config did not exit sucessfully", - Error::__Nonexhaustive => panic!(), - } - } - - fn cause(&self) -> Option<&error::Error> { - match *self { - Error::Command { ref cause, .. } => Some(cause), - _ => None, - } - } -} - -// Workaround for temporary lack of impl Debug for Output in stable std -struct OutputDebugger<'a>(&'a Output); - -// Lifted from 1.7 std -impl<'a> fmt::Debug for OutputDebugger<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let stdout_utf8 = str::from_utf8(&self.0.stdout); - let stdout_debug: &fmt::Debug = match stdout_utf8 { - Ok(ref str) => str, - Err(_) => &self.0.stdout - }; - - let stderr_utf8 = str::from_utf8(&self.0.stderr); - let stderr_debug: &fmt::Debug = match stderr_utf8 { - Ok(ref str) => str, - Err(_) => &self.0.stderr - }; - - fmt.debug_struct("Output") - .field("status", &self.0.status) - .field("stdout", stdout_debug) - .field("stderr", stderr_debug) - .finish() - } -} - -// Workaround for temporary lack of impl Debug for Output in stable std, continued -impl fmt::Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - Error::EnvNoPkgConfig(ref name) => { - f.debug_tuple("EnvNoPkgConfig") - .field(name) - .finish() - } - Error::CrossCompilation => write!(f, "CrossCompilation"), - Error::Command { ref command, ref cause } => { - f.debug_struct("Command") - .field("command", command) - .field("cause", cause) - .finish() - } - Error::Failure { ref command, ref output } => { - f.debug_struct("Failure") - .field("command", command) - .field("output", &OutputDebugger(output)) - .finish() - } - Error::__Nonexhaustive => panic!(), - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - Error::EnvNoPkgConfig(ref name) => { - write!(f, "Aborted because {} is set", name) - } - Error::CrossCompilation => { - write!(f, "Cross compilation detected. \ - Use PKG_CONFIG_ALLOW_CROSS=1 to override") - } - Error::Command { ref command, ref cause } => { - write!(f, "Failed to run `{}`: {}", command, cause) - } - Error::Failure { ref command, ref output } => { - let stdout = str::from_utf8(&output.stdout).unwrap(); - let stderr = str::from_utf8(&output.stderr).unwrap(); - write!(f, "`{}` did not exit successfully: {}", command, output.status)?; - if !stdout.is_empty() { - write!(f, "\n--- stdout\n{}", stdout)?; - } - if !stderr.is_empty() { - write!(f, "\n--- stderr\n{}", stderr)?; - } - Ok(()) - } - Error::__Nonexhaustive => panic!(), - } - } -} - -/// Deprecated in favor of the probe_library function -#[doc(hidden)] -pub fn find_library(name: &str) -> Result<Library, String> { - probe_library(name).map_err(|e| e.to_string()) -} - -/// Simple shortcut for using all default options for finding a library. -pub fn probe_library(name: &str) -> Result<Library, Error> { - Config::new().probe(name) -} - -/// Run `pkg-config` to get the value of a variable from a package using -/// --variable. -pub fn get_variable(package: &str, variable: &str) -> Result<String, Error> { - let arg = format!("--variable={}", variable); - let cfg = Config::new(); - let out = run(cfg.command(package, &[&arg]))?; - Ok(str::from_utf8(&out).unwrap().trim_right().to_owned()) -} - -impl Config { - /// Creates a new set of configuration options which are all initially set - /// to "blank". - pub fn new() -> Config { - Config { - statik: None, - atleast_version: None, - extra_args: vec![], - print_system_libs: true, - cargo_metadata: true, - env_metadata: false, - } - } - - /// Indicate whether the `--static` flag should be passed. - /// - /// This will override the inference from environment variables described in - /// the crate documentation. - pub fn statik(&mut self, statik: bool) -> &mut Config { - self.statik = Some(statik); - self - } - - /// Indicate that the library must be at least version `vers`. - pub fn atleast_version(&mut self, vers: &str) -> &mut Config { - self.atleast_version = Some(vers.to_string()); - self - } - - /// Add an argument to pass to pkg-config. - /// - /// It's placed after all of the arguments generated by this library. - pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Config { - self.extra_args.push(arg.as_ref().to_os_string()); - self - } - - /// Define whether metadata should be emitted for cargo allowing it to - /// automatically link the binary. Defaults to `true`. - pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config { - self.cargo_metadata = cargo_metadata; - self - } - - /// Define whether metadata should be emitted for cargo allowing to - /// automatically rebuild when environment variables change. Defaults to - /// `false`. - pub fn env_metadata(&mut self, env_metadata: bool) -> &mut Config { - self.env_metadata = env_metadata; - self - } - - /// Enable or disable the `PKG_CONFIG_ALLOW_SYSTEM_LIBS` environment - /// variable. - /// - /// This env var is enabled by default. - pub fn print_system_libs(&mut self, print: bool) -> &mut Config { - self.print_system_libs = print; - self - } - - /// Deprecated in favor fo the `probe` function - #[doc(hidden)] - pub fn find(&self, name: &str) -> Result<Library, String> { - self.probe(name).map_err(|e| e.to_string()) - } - - /// Run `pkg-config` to find the library `name`. - /// - /// This will use all configuration previously set to specify how - /// `pkg-config` is run. - pub fn probe(&self, name: &str) -> Result<Library, Error> { - let abort_var_name = format!("{}_NO_PKG_CONFIG", envify(name)); - if self.env_var_os(&abort_var_name).is_some() { - return Err(Error::EnvNoPkgConfig(abort_var_name)) - } else if !target_supported() { - return Err(Error::CrossCompilation); - } - - let mut library = Library::new(); - - let output = run(self.command(name, &["--libs", "--cflags"]))?; - library.parse_libs_cflags(name, &output, self); - - let output = run(self.command(name, &["--modversion"]))?; - library.parse_modversion(str::from_utf8(&output).unwrap()); - - Ok(library) - } - - /// Deprecated in favor of the top level `get_variable` function - #[doc(hidden)] - pub fn get_variable(package: &str, variable: &str) -> Result<String, String> { - get_variable(package, variable).map_err(|e| e.to_string()) - } - - fn targetted_env_var(&self, var_base: &str) -> Result<String, env::VarError> { - if let Ok(target) = env::var("TARGET") { - let host = env::var("HOST")?; - let kind = if host == target { "HOST" } else { "TARGET" }; - let target_u = target.replace("-", "_"); - - self.env_var(&format!("{}_{}", var_base, target)) - .or_else(|_| self.env_var(&format!("{}_{}", var_base, target_u))) - .or_else(|_| self.env_var(&format!("{}_{}", kind, var_base))) - .or_else(|_| self.env_var(var_base)) - } else { - self.env_var(var_base) - } - } - - fn env_var(&self, name: &str) -> Result<String, env::VarError> { - if self.env_metadata { - println!("cargo:rerun-if-env-changed={}", name); - } - env::var(name) - } - - fn env_var_os(&self, name: &str) -> Option<OsString> { - if self.env_metadata { - println!("cargo:rerun-if-env-changed={}", name); - } - env::var_os(name) - } - - fn is_static(&self, name: &str) -> bool { - self.statik.unwrap_or_else(|| self.infer_static(name)) - } - - fn command(&self, name: &str, args: &[&str]) -> Command { - let exe = self.env_var("PKG_CONFIG").unwrap_or_else(|_| String::from("pkg-config")); - let mut cmd = Command::new(exe); - if self.is_static(name) { - cmd.arg("--static"); - } - cmd.args(args) - .args(&self.extra_args); - - if let Ok(value) = self.targetted_env_var("PKG_CONFIG_PATH") { - cmd.env("PKG_CONFIG_PATH", value); - } - if let Ok(value) = self.targetted_env_var("PKG_CONFIG_LIBDIR") { - cmd.env("PKG_CONFIG_LIBDIR", value); - } - if let Ok(value) = self.targetted_env_var("PKG_CONFIG_SYSROOT_DIR") { - cmd.env("PKG_CONFIG_SYSROOT_DIR", value); - } - if self.print_system_libs { - cmd.env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1"); - } - if let Some(ref version) = self.atleast_version { - cmd.arg(&format!("{} >= {}", name, version)); - } else { - cmd.arg(name); - } - cmd - } - - fn print_metadata(&self, s: &str) { - if self.cargo_metadata { - println!("cargo:{}", s); - } - } - - fn infer_static(&self, name: &str) -> bool { - let name = envify(name); - if self.env_var_os(&format!("{}_STATIC", name)).is_some() { - true - } else if self.env_var_os(&format!("{}_DYNAMIC", name)).is_some() { - false - } else if self.env_var_os("PKG_CONFIG_ALL_STATIC").is_some() { - true - } else if self.env_var_os("PKG_CONFIG_ALL_DYNAMIC").is_some() { - false - } else { - false - } - } -} - -impl Library { - fn new() -> Library { - Library { - libs: Vec::new(), - link_paths: Vec::new(), - include_paths: Vec::new(), - frameworks: Vec::new(), - framework_paths: Vec::new(), - defines: HashMap::new(), - version: String::new(), - _priv: (), - } - } - - fn parse_libs_cflags(&mut self, name: &str, output: &[u8], config: &Config) { - let mut is_msvc = false; - if let Ok(target) = env::var("TARGET") { - if target.contains("msvc") { - is_msvc = true; - } - } - - let words = split_flags(output); - let parts = words.iter() - .filter(|l| l.len() > 2) - .map(|arg| (&arg[0..2], &arg[2..])) - .collect::<Vec<_>>(); - - let mut dirs = Vec::new(); - let statik = config.is_static(name); - for &(flag, val) in &parts { - match flag { - "-L" => { - let meta = format!("rustc-link-search=native={}", val); - config.print_metadata(&meta); - dirs.push(PathBuf::from(val)); - self.link_paths.push(PathBuf::from(val)); - } - "-F" => { - let meta = format!("rustc-link-search=framework={}", val); - config.print_metadata(&meta); - self.framework_paths.push(PathBuf::from(val)); - } - "-I" => { - self.include_paths.push(PathBuf::from(val)); - } - "-l" => { - // These are provided by the CRT with MSVC - if is_msvc && ["m", "c", "pthread"].contains(&val) { - continue; - } - - if statik && is_static_available(val, &dirs) { - let meta = format!("rustc-link-lib=static={}", val); - config.print_metadata(&meta); - } else { - let meta = format!("rustc-link-lib={}", val); - config.print_metadata(&meta); - } - - self.libs.push(val.to_string()); - } - "-D" => { - let mut iter = val.split("="); - self.defines.insert(iter.next().unwrap().to_owned(), iter.next().map(|s| s.to_owned())); - } - _ => {} - } - } - - let mut iter = words.iter() - .flat_map(|arg| if arg.starts_with("-Wl,") { - arg[4..].split(',').collect() - } else { - vec![arg.as_ref()] - }); - while let Some(part) = iter.next() { - if part != "-framework" { - continue - } - if let Some(lib) = iter.next() { - let meta = format!("rustc-link-lib=framework={}", lib); - config.print_metadata(&meta); - self.frameworks.push(lib.to_string()); - } - } - } - - fn parse_modversion(&mut self, output: &str) { - self.version.push_str(output.trim()); - } -} - -fn envify(name: &str) -> String { - name.chars().map(|c| c.to_ascii_uppercase()).map(|c| { - if c == '-' {'_'} else {c} - }).collect() -} - -/// System libraries should only be linked dynamically -fn is_static_available(name: &str, dirs: &[PathBuf]) -> bool { - let libname = format!("lib{}.a", name); - let system_roots = if cfg!(target_os = "macos") { - vec![Path::new("/Library"), Path::new("/System")] - } else { - vec![Path::new("/usr")] - }; - - dirs.iter().any(|dir| { - !system_roots.iter().any(|sys| dir.starts_with(sys)) && - dir.join(&libname).exists() - }) -} - -fn run(mut cmd: Command) -> Result<Vec<u8>, Error> { - match cmd.output() { - Ok(output) => { - if output.status.success() { - Ok(output.stdout) - } else { - Err(Error::Failure { - command: format!("{:?}", cmd), - output: output, - }) - } - } - Err(cause) => Err(Error::Command { - command: format!("{:?}", cmd), - cause: cause, - }), - } -} - -/// Split output produced by pkg-config --cflags and / or --libs into separate flags. -/// -/// Backslash in output is used to preserve literal meaning of following byte. Different words are -/// separated by unescaped space. Other whitespace characters generally should not occur unescaped -/// at all, apart from the newline at the end of output. For compatibility with what others -/// consumers of pkg-config output would do in this scenario, they are used here for splitting as -/// well. -fn split_flags(output: &[u8]) -> Vec<String> { - let mut word = Vec::new(); - let mut words = Vec::new(); - let mut escaped = false; - - for &b in output { - match b { - _ if escaped => { - escaped = false; - word.push(b); - } - b'\\' => { - escaped = true - } - b'\t' | b'\n' | b'\r' | b' ' => { - if !word.is_empty() { - words.push(String::from_utf8(word).unwrap()); - word = Vec::new(); - } - } - _ => word.push(b), - } - } - - if !word.is_empty() { - words.push(String::from_utf8(word).unwrap()); - } - - words -} - -#[test] -#[cfg(target_os = "macos")] -fn system_library_mac_test() { - assert!(!is_static_available("PluginManager", &[PathBuf::from("/Library/Frameworks")])); - assert!(!is_static_available("python2.7", &[PathBuf::from("/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config")])); - assert!(!is_static_available("ffi_convenience", &[PathBuf::from("/Library/Ruby/Gems/2.0.0/gems/ffi-1.9.10/ext/ffi_c/libffi-x86_64/.libs")])); - - // Homebrew is in /usr/local, and it's not a part of the OS - if Path::new("/usr/local/lib/libpng16.a").exists() { - assert!(is_static_available("png16", &[PathBuf::from("/usr/local/lib")])); - } -} - -#[test] -#[cfg(target_os = "linux")] -fn system_library_linux_test() { - assert!(!is_static_available("util", &[PathBuf::from("/usr/lib/x86_64-linux-gnu")])); - assert!(!is_static_available("dialog", &[PathBuf::from("/usr/lib")])); -} diff --git a/pkg-config/tests/escape.pc b/pkg-config/tests/escape.pc deleted file mode 100644 index 701c4bf..0000000 --- a/pkg-config/tests/escape.pc +++ /dev/null @@ -1,5 +0,0 @@ -Name: Escape -Version: 4.2.0 -Description: Escape utility library -Libs: -Llink\ path\ with\ spaces -Cflags: -Iinclude\ path\ with\ spaces -DA=\"escaped\ string\'\ literal\" -DB=ESCAPED\ IDENTIFIER -DFOX=🦊 diff --git a/pkg-config/tests/foo.pc b/pkg-config/tests/foo.pc deleted file mode 100644 index b1ae3d8..0000000 --- a/pkg-config/tests/foo.pc +++ /dev/null @@ -1,16 +0,0 @@ -prefix=/usr -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include/valgrind -arch=amd64 -os=linux -platform=amd64-linux -valt_load_address=0x38000000 - -Name: Valgrind -Description: A dynamic binary instrumentation framework -Version: 3.10.0.SVN -Requires: -Libs: -L${libdir}/valgrind -lcoregrind-amd64-linux -lvex-amd64-linux -lgcc -Cflags: -I${includedir} - diff --git a/pkg-config/tests/framework.pc b/pkg-config/tests/framework.pc deleted file mode 100644 index fec17f4..0000000 --- a/pkg-config/tests/framework.pc +++ /dev/null @@ -1,16 +0,0 @@ -prefix=/usr -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -includedir=${prefix}/include/valgrind -arch=amd64 -os=linux -platform=amd64-linux -valt_load_address=0x38000000 - -Name: Valgrind -Description: A dynamic binary instrumentation framework -Version: 3.10.0.SVN -Requires: -Libs: -F${libdir} -framework foo -Wl,-framework,bar -Wl,-framework -Wl,baz -Wl,-framework,foobar,-framework,foobaz -Cflags: -I${includedir} - diff --git a/pkg-config/tests/test.rs b/pkg-config/tests/test.rs deleted file mode 100644 index fad0fcf..0000000 --- a/pkg-config/tests/test.rs +++ /dev/null @@ -1,118 +0,0 @@ -extern crate pkg_config; -#[macro_use] -extern crate lazy_static; - -use pkg_config::Error; -use std::env; -use std::sync::Mutex; -use std::path::PathBuf; - -lazy_static! { - static ref LOCK: Mutex<()> = Mutex::new(()); -} - -fn reset() { - for (k, _) in env::vars() { - if k.contains("DYNAMIC") || - k.contains("STATIC") || - k.contains("PKG_CONFIG_ALLOW_CROSS") || - k.contains("FOO_NO_PKG_CONFIG") { - env::remove_var(&k); - } - } - env::remove_var("TARGET"); - env::remove_var("HOST"); - env::set_var("PKG_CONFIG_PATH", &env::current_dir().unwrap().join("tests")); -} - -fn find(name: &str) -> Result<pkg_config::Library, Error> { - pkg_config::probe_library(name) -} - -#[test] -fn cross_disabled() { - let _g = LOCK.lock(); - reset(); - env::set_var("TARGET", "foo"); - env::set_var("HOST", "bar"); - match find("foo") { - Err(Error::CrossCompilation) => {}, - x => panic!("Error::CrossCompilation expected, found `{:?}`", x), - } -} - -#[test] -fn cross_enabled() { - let _g = LOCK.lock(); - reset(); - env::set_var("TARGET", "foo"); - env::set_var("HOST", "bar"); - env::set_var("PKG_CONFIG_ALLOW_CROSS", "1"); - find("foo").unwrap(); -} - -#[test] -fn package_disabled() { - let _g = LOCK.lock(); - reset(); - env::set_var("FOO_NO_PKG_CONFIG", "1"); - match find("foo") { - Err(Error::EnvNoPkgConfig(name)) => { - assert_eq!(name, "FOO_NO_PKG_CONFIG") - } - x => panic!("Error::EnvNoPkgConfig expected, found `{:?}`", x), - } -} - -#[test] -fn output_ok() { - let _g = LOCK.lock(); - reset(); - let lib = find("foo").unwrap(); - assert!(lib.libs.contains(&"gcc".to_string())); - assert!(lib.libs.contains(&"coregrind-amd64-linux".to_string())); - assert!(lib.link_paths.contains(&PathBuf::from("/usr/lib/valgrind"))); -} - -#[test] -fn escapes() { - let _g = LOCK.lock(); - reset(); - let lib = find("escape").unwrap(); - assert!(lib.include_paths.contains(&PathBuf::from("include path with spaces"))); - assert!(lib.link_paths.contains(&PathBuf::from("link path with spaces"))); - assert_eq!(lib.defines.get("A"), - Some(&Some("\"escaped string' literal\"".to_owned()))); - assert_eq!(lib.defines.get("B"), - Some(&Some("ESCAPED IDENTIFIER".to_owned()))); - assert_eq!(lib.defines.get("FOX"), - Some(&Some("🦊".to_owned()))); -} - -#[test] -fn framework() { - let _g = LOCK.lock(); - reset(); - let lib = find("framework").unwrap(); - assert!(lib.frameworks.contains(&"foo".to_string())); - assert!(lib.frameworks.contains(&"bar".to_string())); - assert!(lib.frameworks.contains(&"baz".to_string())); - assert!(lib.frameworks.contains(&"foobar".to_string())); - assert!(lib.frameworks.contains(&"foobaz".to_string())); - assert!(lib.framework_paths.contains(&PathBuf::from("/usr/lib"))); -} - -#[test] -fn get_variable() { - let _g = LOCK.lock(); - reset(); - let prefix = pkg_config::get_variable("foo", "prefix").unwrap(); - assert_eq!(prefix, "/usr"); -} - -#[test] -fn version() { - let _g = LOCK.lock(); - reset(); - assert_eq!(&find("foo").unwrap().version[..], "3.10.0.SVN"); -} |