// **************************************************************************
// Copyright (c) 2015 Roland Ruckerbauer All Rights Reserved.
//
// This file is part of hidapi_rust.
//
// hidapi_rust is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// hidapi_rust is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with hidapi_rust. If not, see .
// *************************************************************************
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() {
// First check the features enabled for the crate.
// Only one linux backend should be enabled at a time.
let avail_backends: [(&'static str, Box); 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(|| {
// The udev crate takes care of finding its library
}),
),
];
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.");
}
// Build it!
(backends.next().unwrap().1)();
}
//#[cfg(all(feature = "shared-libusb", not(feature = "shared-hidraw")))]
//fn compile_linux() {
//
//}
//
//#[cfg(all(feature = "shared-hidraw"))]
//fn compile_linux() {
//
//}
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() {
// First check the features enabled for the crate.
// Only one illumos backend should be enabled at a time.
let avail_backends: [(&'static str, Box); 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.");
}
// Build it!
(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") {
// https://doc.rust-lang.org/reference/linkage.html#static-and-dynamic-c-runtimes
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")
}