Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support bindgen in recommended usage #2

Merged
merged 10 commits into from Apr 2, 2020
8 changes: 5 additions & 3 deletions Cargo.toml
Expand Up @@ -14,8 +14,10 @@ build = "build.rs"
[dependencies]
libc = "0.2"

[target.'cfg(not(windows))'.build-dependencies]
[target.'cfg(not(all(windows, target_env="msvc")))'.build-dependencies]
pkg-config = "0.3"
bindgen = "0.53.2"

[target.'cfg(windows)'.build-dependencies]
vcpkg = "0.2"
[target.'cfg(all(windows, target_env="msvc"))'.build-dependencies]
vcpkg = "0.2"
bindgen = "0.53.2"
16 changes: 16 additions & 0 deletions README.md
@@ -0,0 +1,16 @@
# `libftdi1-sys`
`libftdi1-sys` is a crate providing Rust bindings to the C library
[`libftdi1`](https://www.intra2net.com/en/developer/libftdi/index.php).

## Prerequisites
The libftdi1 bindings are generated at compile-time, per bindgen's
[recommended usage](https://rust-lang.github.io/rust-bindgen/library-usage.html).

* `libclang` must be installed and visible on your path. If you are using a
`gcc`-toolchain and don't want to install the entirity of LLVM just for
`libclang`,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This phrase looks unfinished.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, and I realized it was after I went to sleep for the night :P.


* `libftdi` version 1.4 (the most recent version as of 2017) is required.

* The Minimum Supported Rust Version (MSRV) is stable `1.42`. However, older
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not strictly correct. You don't use the bindgen rust_target option, so the target by default is "the latest stable Rust version". However, as bindgen seems to almost never do compatible version bumps, this is likely to be true.

Still, this requirement sounds a bit suboptimal. I'll discuss it in a bit more detail in a follow-up comment.

versions may work and simply have not been tested.
29 changes: 24 additions & 5 deletions build.rs
@@ -1,9 +1,28 @@
#[cfg(not(windows))]
fn main() {
pkg_config::find_library("libftdi1").unwrap();
}
use bindgen;
use std::env;
use std::path::PathBuf;

#[cfg(windows)]
fn main() {
#[cfg(not(all(windows, target_env="msvc")))]
pkg_config::Config::new().atleast_version("1.4").probe("libftdi1").unwrap();
#[cfg(all(windows, target_env="msvc"))]
vcpkg::find_package("libftdi1").unwrap();

let bindings = bindgen::Builder::default()
.header("wrapper.h")
.default_enum_style(bindgen::EnumVariation::Rust{ non_exhaustive : true })
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an interesting problem here: according to the recent discussion in rust-lang/rust-bindgen#1554, this #[non_exhaustive] would not help with unknown variants if a newer libftdi1 version returns them (it's still UB to have an enum with a value rustc does not know about). We may want to look into the newtype style of enums, it looks interesting.

.rustfmt_bindings(true)
.whitelist_function("ftdi_.*")
.whitelist_type("ftdi_.*")
.whitelist_type("libusb_.*")
.blacklist_type("timeval")
.blacklist_type("__.*")
.raw_line("pub type timeval = libc::timeval;")
.generate()
.expect("Unable to generate bindings");

let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}