extern crate cc;
extern crate pkg_config;
use std::env;
fn main() {
let target = env::var("TARGET").unwrap();
println!("cargo:rustc-check-cfg=cfg(hidapi)");
println!("cargo:rustc-check-cfg=cfg(libusb)");
if target.contains("linux") {
compile_linux();
} else if target.contains("windows") {
compile_windows();
} else if target.contains("darwin") {
compile_macos();
} else if target.contains("freebsd") {
compile_freebsd();
} else if target.contains("openbsd") {
compile_openbsd();
} else if target.contains("illumos") {
compile_illumos();
} else {
panic!("Unsupported target os for hidapi-rs");
}
}
fn compile_linux() {
let avail_backends: [(&'static str, Box<dyn Fn()>); 5] = [
(
"LINUX_STATIC_HIDRAW",
Box::new(|| {
let mut config = cc::Build::new();
println!("cargo:rerun-if-changed=etc/hidapi/linux/hid.c");
config
.file("etc/hidapi/linux/hid.c")
.include("etc/hidapi/hidapi");
pkg_config::probe_library("libudev").expect("Unable to find libudev");
config.compile("libhidapi.a");
println!("cargo:rustc-cfg=hidapi");
}),
),
(
"LINUX_STATIC_LIBUSB",
Box::new(|| {
let mut config = cc::Build::new();
println!("cargo:rerun-if-changed=etc/hidapi/linux/hid.c");
config
.file("etc/hidapi/libusb/hid.c")
.include("etc/hidapi/hidapi");
let lib =
pkg_config::find_library("libusb-1.0").expect("Unable to find libusb-1.0");
for path in lib.include_paths {
config.include(
path.to_str()
.expect("Failed to convert include path to str"),
);
}
config.compile("libhidapi.a");
println!("cargo:rustc-cfg=libusb");
println!("cargo:rustc-cfg=hidapi");
}),
),
(
"LINUX_SHARED_HIDRAW",
Box::new(|| {
pkg_config::probe_library("hidapi-hidraw").expect("Unable to find hidapi-hidraw");
println!("cargo:rustc-cfg=hidapi");
}),
),
(
"LINUX_SHARED_LIBUSB",
Box::new(|| {
pkg_config::probe_library("libusb-1.0").expect("Unable to find libusb-1.0");
pkg_config::probe_library("hidapi-libusb").expect("Unable to find hidapi-libusb");
println!("cargo:rustc-cfg=libusb");
println!("cargo:rustc-cfg=hidapi");
}),
),
(
"LINUX_NATIVE",
Box::new(|| {
}),
),
];
let mut backends = avail_backends
.iter()
.filter(|f| env::var(format!("CARGO_FEATURE_{}", f.0)).is_ok());
if backends.clone().count() != 1 {
panic!("Exactly one linux hidapi backend must be selected.");
}
(backends.next().unwrap().1)();
}
fn compile_freebsd() {
pkg_config::probe_library("hidapi").expect("Unable to find hidapi");
println!("cargo:rustc-cfg=libusb");
println!("cargo:rustc-cfg=hidapi");
}
fn compile_openbsd() {
pkg_config::probe_library("hidapi-libusb").expect("Unable to find hidapi");
println!("cargo:rustc-cfg=libusb");
println!("cargo:rustc-cfg=hidapi");
}
fn compile_illumos() {
let avail_backends: [(&'static str, Box<dyn Fn()>); 2] = [
(
"ILLUMOS_STATIC_LIBUSB",
Box::new(|| {
let mut config = cc::Build::new();
config
.file("etc/hidapi/libusb/hid.c")
.include("etc/hidapi/hidapi");
let lib =
pkg_config::find_library("libusb-1.0").expect("Unable to find libusb-1.0");
for path in lib.include_paths {
config.include(
path.to_str()
.expect("Failed to convert include path to str"),
);
}
config.compile("libhidapi.a");
}),
),
(
"ILLUMOS_SHARED_LIBUSB",
Box::new(|| {
pkg_config::probe_library("hidapi-libusb").expect("Unable to find hidapi-libusb");
}),
),
];
let mut backends = avail_backends
.iter()
.filter(|f| env::var(format!("CARGO_FEATURE_{}", f.0)).is_ok());
if backends.clone().count() != 1 {
panic!("Exactly one illumos hidapi backend must be selected.");
}
(backends.next().unwrap().1)();
println!("cargo:rustc-cfg=libusb");
println!("cargo:rustc-cfg=hidapi");
}
fn compile_windows() {
#[cfg(not(feature = "windows-native"))]
{
let linkage = env::var("CARGO_CFG_TARGET_FEATURE").unwrap_or_default();
let mut cc = cc::Build::new();
cc.file("etc/hidapi/windows/hid.c")
.include("etc/hidapi/hidapi");
if linkage.contains("crt-static") {
cc.static_crt(true);
}
cc.compile("libhidapi.a");
println!("cargo:rustc-link-lib=setupapi");
println!("cargo:rustc-cfg=hidapi");
}
}
fn compile_macos() {
cc::Build::new()
.file("etc/hidapi/mac/hid.c")
.include("etc/hidapi/hidapi")
.compile("libhidapi.a");
println!("cargo:rustc-cfg=hidapi");
println!("cargo:rustc-link-lib=framework=IOKit");
println!("cargo:rustc-link-lib=framework=CoreFoundation");
println!("cargo:rustc-link-lib=framework=AppKit")
}