From 70838a13890e1dec4dd2c5620f6e8dbbe6a5365a Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 19 Sep 2024 11:36:42 +0200 Subject: [PATCH] v4l2-sys: Replace FreeBSD **host-only** include path override with docs With `cfg!()` on `target_os` this include path is unconditionally used if the _host_ OS is FreeBSD, even if the target OS is different (and its cross-compilation headers are installed elsewhere on the system). The accurate target OS, regardless of what the build script is _running on_ is stored in `CARGO_CFG_TARGET_OS`. Since it is unlikely that the FreeBSD headers reside in `/usr/ local/include` when the *target* is FreeBSD while the host may be something completely different, remove the workaround and document how the user can set up arbitrary include directories for their target using `BINDGEN_EXTRA_CLANG_ARGS` (or the triple-specific variant) by documenting this environment variable in the main `README`. It is common for developers to maintain such a configuration in their home directory's `~/.cargo/ config.toml` for the various architectures that they cross-compile to (together with related variables for the linker and `cc-rs`). --- README.md | 18 ++++++++++++++++++ v4l2-sys/build.rs | 15 +-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 5c8206e..25f9359 100644 --- a/README.md +++ b/README.md @@ -94,3 +94,21 @@ fn main() { ``` Have a look at the provided `examples` for more sample applications. + +### Building and cross-compiling + +When building on targets like FreeBSD, or cross-compiling for different targets entirely (as identified by their _targe triple_), bindgen may not know where to find the headers if they are located in a nonstandard directory like `/usr/local/include`, resulting in an error similar to `wrapper.h:1:10: fatal error: 'linux/videodev2.h' file not found`. In this case, provide the system include directory with the `-I` flag using the [target-specific environment variable][bindgen-env] (note that `-` is typically subtituted with `_` to help shells like `bash` parse it successfully): + +```console +$ BINDGEN_EXTRA_CLANG_ARGS_x86_64_unknown_freebsd="-I/usr/local/include" cargo build --target x86_64-unknown-freebsd +``` + +It is also possible to set this environment variable for Rust inside [`.cargo/config.toml`][cargo-config] in your project directory or user home directory: + +```toml +[env] +BINDGEN_EXTRA_CLANG_ARGS_x86_64-unknown-freebsd = "-I/usr/local/include" +``` + +[bindgen-env]: https://github.com/rust-lang/rust-bindgen/blob/main/README.md#environment-variables +[cargo-config]: https://doc.rust-lang.org/cargo/reference/config.html diff --git a/v4l2-sys/build.rs b/v4l2-sys/build.rs index 8f09e8b..932a324 100644 --- a/v4l2-sys/build.rs +++ b/v4l2-sys/build.rs @@ -1,24 +1,11 @@ extern crate bindgen; use std::env; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; fn main() { - let extra_include_paths = if cfg!(target_os = "freebsd") { - assert!( - Path::new("/usr/local/include/linux/videodev2.h").exists(), - "Video4Linux `videodev2.h` UAPI header is required to generate bindings \ - against `libv4l2` and the header file is missing.\n\ - Consider installing `multimedia/v4l_compat` FreeBSD package." - ); - vec!["-I/usr/local/include"] - } else { - vec![] - }; - let bindings = bindgen::Builder::default() .header("wrapper.h") - .clang_args(extra_include_paths) .generate() .expect("Failed to generate bindings");