### Configure bindgen to use prettyplease formatter Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/code-formatting.md This example shows how to instruct bindgen to use the 'prettyplease' crate for formatting generated Rust code. This method is advantageous as it can be used in environments without a full Rust toolchain installed. ```rust use bindgen::Builder; fn main() { let bindings = Builder::default() .header("path/to/input.h") .formatter(bindgen::Formatter::Prettyplease) .generate() .expect("Could not generate bindings"); bindings .write_to_file("path/to/output.rs") .expect("Could not write bindings"); } ``` -------------------------------- ### Installing doctoc Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md This command installs the `doctoc` Node.js package globally. `doctoc` is used to automatically update the table of contents in the `CHANGELOG.md` file during the release process. ```sh npm install doctoc ``` -------------------------------- ### Complete build.rs Example for Rust Bindgen Integration Source: https://context7.com/rust-lang/rust-bindgen/llms.txt A comprehensive `build.rs` example demonstrating a typical configuration for integrating bindgen into a Rust project. It includes setting up library search paths, linking libraries, invalidating the build cache, configuring clang arguments, using `CargoCallbacks`, specifying allowlists and blocklists, customizing enum and trait derivation, and disabling layout tests in release builds. ```rust use bindgen::Builder; use std::env; use std::path::PathBuf; fn main() { // Tell cargo to look for shared libraries in the specified directory println!("cargo:rustc-link-search=/usr/local/lib"); // Tell cargo to link the library println!("cargo:rustc-link-lib=mylib"); // Tell cargo to invalidate the build cache if the wrapper changes println!("cargo:rerun-if-changed=wrapper.h"); let bindings = Builder::default() // The input header file .header("wrapper.h") // Clang arguments .clang_arg("-I/usr/local/include") // Use CargoCallbacks to re-run when included headers change .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Allowlist only what we need .allowlist_function("mylib_.*") .allowlist_type("mylib_.*") .allowlist_var("MYLIB_.*") // Blocklist internal symbols .blocklist_function("__mylib_internal.*") // Configure enum handling .default_enum_style(bindgen::EnumVariation::Rust { non_exhaustive: true }) .bitfield_enum("mylib_flags_t") // Configure trait derivation .derive_default(true) .derive_debug(true) .derive_partialeq(true) .derive_eq(true) // Disable layout tests in release builds .layout_tests(cfg!(debug_assertions)) // Generate the bindings .generate() .expect("Unable to generate bindings"); // Write the bindings to the $OUT_DIR/bindings.rs file let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); } ``` -------------------------------- ### Install Clang on Windows using MinGW-w64 Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs Clang for the MinGW-w64 environment on Windows using the pacman package manager. This is an alternative to the official LLVM installer. ```bash pacman -S mingw64/mingw-w64-x86_64-clang ``` -------------------------------- ### Install Python 3 using apt Source: https://github.com/rust-lang/rust-bindgen/blob/main/bindgen-tests/tests/quickchecking/README.md Installs Python 3 on Debian-based systems using the apt package manager. This is a prerequisite for running bindgen property tests. ```shell sudo apt install python3 ``` -------------------------------- ### Install Python 3 using brew Source: https://github.com/rust-lang/rust-bindgen/blob/main/bindgen-tests/tests/quickchecking/README.md Installs Python 3 on macOS systems using the Homebrew package manager. This is a prerequisite for running bindgen property tests. ```shell brew install python3 ``` -------------------------------- ### Install LLVM on OpenBSD Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs LLVM, which includes Clang, on OpenBSD using the pkg_add utility. This command requires root privileges. ```bash # pkg_add llvm ``` -------------------------------- ### Install Clang on Windows using winget Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs LLVM, which includes Clang, on Windows using the winget package manager. Ensure you have winget installed and configured. ```powershell winget install LLVM.LLVM ``` -------------------------------- ### Getting Help for predicate.py Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md This command displays the help message for the `predicate.py` script, listing all available flags and their descriptions. This is useful for understanding the full capabilities of the script for fuzzing and debugging. ```sh path/to/rust-bindgen/csmith-fuzzing/predicate.py --help ``` -------------------------------- ### Rust Bindgen Bitfield Initialization Example Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/using-bitfields.md Shows how to create a new bitfield instance in Rust using the static constructor generated by Bindgen. This requires `derive_default` to be enabled in the Bindgen builder. ```rust let bfield = StructWithBitfields{ _bitfield_1: StructWithBitfields::new_bitfield_1(0,0,0), ..Default::default() }; unsafe { print_bitfield(bfield) }; ``` -------------------------------- ### Install Clang on Arch Linux Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs the Clang compiler on Arch Linux using the pacman package manager. This command requires root privileges. ```bash # pacman -S clang ``` -------------------------------- ### Rust Bindgen Bitfield Interaction Example Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/using-bitfields.md Demonstrates how to use the getter and setter functions generated by Bindgen for interacting with C bitfields. It shows setting individual bitfields and printing their values. ```rust let mut bfield = unsafe { create_bitfield() }; bfield.set_a(1); println!("a set to {}", bfield.a()); bfield.set_b(1); println!("b set to {}", bfield.b()); bfield.set_c(3); println!("c set to {}", bfield.c()); unsafe { print_bitfield(bfield) }; ``` -------------------------------- ### Install clang-devel on Fedora Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs the clang-devel package on Fedora Linux, which includes the necessary Clang development files. This command requires root privileges. ```bash # dnf install clang-devel ``` -------------------------------- ### Install Clang on macOS using MacPorts Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs Clang on macOS using the MacPorts package manager. This is an alternative to Homebrew for managing software on macOS. ```bash $ port install clang ``` -------------------------------- ### Generate Rust FFI Bindings with bindgen in build.rs Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/tutorial-3.md This Rust code snippet demonstrates how to use `bindgen` within a `build.rs` file to generate FFI bindings. It configures Cargo to link against the `bz2` shared library and specifies the input header file (`wrapper.h`). The generated bindings are written to `$OUT_DIR/bindings.rs`. Dependencies include the `bindgen` crate. ```rust use std::env; use std::path::PathBuf; fn main() { // Tell cargo to look for shared libraries in the specified directory println!("cargo:rustc-link-search=/path/to/lib"); // Tell cargo to tell rustc to link the system bzip2 // shared library. println!("cargo:rustc-link-lib=bz2"); // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for // the resulting bindings. let bindings = bindgen::Builder::default() // The input header we would like to generate // bindings for. .header("wrapper.h") // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. .expect("Unable to generate bindings"); // Write the bindings to the $OUT_DIR/bindings.rs file. let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); } ``` -------------------------------- ### Generate Bindings for Custom Target with bindgen CLI Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/faq.md This command-line example shows how to generate bindings for a custom target like 'armv7a-none-eabi' using the bindgen tool. It requires specifying the input headers and passing the target argument through clang. ```bash $ bindgen -- --target=armv7a-none-eabi ``` -------------------------------- ### C++ Inline Function Example Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/faq.md This C++ code demonstrates inline functions defined directly within a class and separately defined inline functions. It serves as an example for understanding bindgen's behavior with inline functions. ```c++ class Dooder { public: // Function defined inline in the class. int example_one() { return 1; } // `inline` function whose definition is supplied later in the header, or in // another header. inline bool example_two(); }; inline bool Dooder::example_two() { return true; } ``` -------------------------------- ### Install LLVM on macOS using Homebrew Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs LLVM, which provides Clang, on macOS using the Homebrew package manager. This is a common method for macOS development environments. ```bash $ brew install llvm ``` -------------------------------- ### Generate Rust FFI Bindings from C Header (bindgen) Source: https://github.com/rust-lang/rust-bindgen/blob/main/README.md This example demonstrates how bindgen transforms a C struct and function definition into equivalent Rust FFI code. It shows the generated Rust representation of the 'Doggo' struct and the 'eleven_out_of_ten_majestic_af' function signature, enabling interaction with C libraries from Rust. ```c typedef struct Doggo { int many; char wow; } Doggo; void eleven_out_of_ten_majestic_af(Doggo* pupper); ``` ```rust /* automatically generated by rust-bindgen 0.99.9 */ #[repr(C)] pub struct Doggo { pub many: ::std::os::raw::c_int, pub wow: ::std::os::raw::c_char, } extern "C" { pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo); } ``` -------------------------------- ### Test Single Header Generation and Compilation (Shell) Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md Executes a script to generate bindings for a single header file, compile them, and run layout tests. Requires graphviz to be installed. Supports fuzzy searching for header files. ```shell ./bindgen-tests/tests/test-one.sh going ``` -------------------------------- ### Customize Bindgen with Custom Parse Callbacks Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Implements `ParseCallbacks` to customize binding generation dynamically. This example shows how to modify integer macro types, add derive attributes, rename items, and track included files for rebuilds. ```rust use bindgen::{Builder, callbacks::{ParseCallbacks, DeriveInfo, ItemInfo, IntKind}}; #[derive(Debug)] struct MyCallbacks; impl ParseCallbacks for MyCallbacks { // Customize integer type for macro constants fn int_macro(&self, name: &str, _value: i64) -> Option { if name.starts_with("SIZE_") { Some(IntKind::USize) } else { None } } // Add custom derive attributes to types fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec { if info.name.ends_with("Config") { vec!["serde::Serialize".into(), "serde::Deserialize".into()] } else { vec![] } } // Rename generated items fn item_name(&self, item: ItemInfo<'_>) -> Option { if item.name.starts_with("my_lib_") { Some(item.name.trim_start_matches("my_lib_").to_string()) } else { None } } // Track included files for cargo rebuild fn include_file(&self, filename: &str) { println!("cargo:rerun-if-changed={}", filename); } } fn main() { let bindings = Builder::default() .header("mylib.h") .parse_callbacks(Box::new(MyCallbacks)) .generate() .expect("Unable to generate bindings"); bindings.write_to_file("bindings.rs").unwrap(); } ``` -------------------------------- ### Rust Bindgen Bitfield Overflow Example Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/using-bitfields.md Illustrates the behavior of Bindgen-generated bitfield setters when an overflow occurs, mirroring C/C++ behavior where the value wraps around or is set to 0. ```rust let mut bfield = unsafe { create_bitfield() }; bfield.set_a(1); bfield.set_b(1); bfield.set_c(12); println!("c set to {} due to overflow", bfield.c()); unsafe { print_bitfield(bfield) }; ``` -------------------------------- ### Include Generated Bindings in Rust Code Source: https://context7.com/rust-lang/rust-bindgen/llms.txt This snippet demonstrates how to include the `bindings.rs` file generated by bindgen into your Rust project. It also shows how to create safe Rust wrappers around the unsafe FFI functions and provides an example of a basic test. ```rust // src/lib.rs // Include the generated bindings #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); // Provide a safe Rust wrapper pub struct MyLib; impl MyLib { pub fn new() -> Result { let result = unsafe { mylib_init() }; if result == 0 { Ok(MyLib) } else { Err("Failed to initialize mylib") } } pub fn process(&self, data: &[u8]) -> Vec { let mut output = vec![0u8; data.len() * 2]; unsafe { mylib_process( data.as_ptr(), data.len(), output.as_mut_ptr(), output.len() ); } output } } impl Drop for MyLib { fn drop(&mut self) { unsafe { mylib_cleanup(); } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_binding_layout() { // Layout tests are automatically generated by bindgen // They verify struct sizes and alignments match C } } ``` -------------------------------- ### C Header File for Library Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/non-system-libraries.md Declares the `hello` function, making it available for use by other C files and for header parsing by bindgen. ```c int hello(); ``` -------------------------------- ### Build and Test Bindings with Cargo (Bash) Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/tutorial-4.md These commands show how to compile your Rust project with the newly included bindings using `cargo build` and then run tests to verify the correctness of the generated FFI struct layouts, sizes, and alignments. Successful execution indicates that the bindings are compatible with your Rust environment. ```bash $ cargo build Compiling bindgen-tutorial-bzip2-sys v0.1.0 Finished debug [unoptimized + debuginfo] target(s) in 62.8 secs ``` ```bash $ cargo test Compiling bindgen-tutorial-bzip2-sys v0.1.0 Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs Running target/debug/deps/bzip2_sys-10413fc2af207810 running 14 tests test bindgen_test_layout___darwin_pthread_handler_rec ... ok test bindgen_test_layout___sFILE ... ok test bindgen_test_layout___sbuf ... ok test bindgen_test_layout__bindgen_ty_1 ... ok test bindgen_test_layout__bindgen_ty_2 ... ok test bindgen_test_layout__opaque_pthread_attr_t ... ok test bindgen_test_layout__opaque_pthread_cond_t ... ok test bindgen_test_layout__opaque_pthread_mutex_t ... ok test bindgen_test_layout__opaque_pthread_condattr_t ... ok test bindgen_test_layout__opaque_pthread_mutexattr_t ... ok test bindgen_test_layout__opaque_pthread_once_t ... ok test bindgen_test_layout__opaque_pthread_rwlock_t ... ok test bindgen_test_layout__opaque_pthread_rwlockattr_t ... ok test bindgen_test_layout__opaque_pthread_t ... ok test result: ok. 14 passed; 0 failed; 0 ignored; 0 measured Doc-tests bindgen-tutorial-bzip2-sys running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ``` -------------------------------- ### C Code for Library Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/non-system-libraries.md Defines a simple C function `hello` that returns an integer. This serves as the library for which Rust bindings will be generated. ```c int hello() { return 42; } ``` -------------------------------- ### Install libclang-dev on Debian-based Linux Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/requirements.md Installs the libclang-dev package on Debian-based Linux distributions, providing the necessary Clang libraries for bindgen. This command requires root privileges. ```bash # apt install libclang-dev ``` -------------------------------- ### Run bindgen quickchecking tests Source: https://github.com/rust-lang/rust-bindgen/blob/main/bindgen-tests/tests/quickchecking/README.md Executes the quickchecking binary for bindgen property tests. This command generates and tests fuzzed C headers. Additional configuration options can be accessed via the '-h' flag. ```shell cargo run --bin=quickchecking -- -h ``` -------------------------------- ### Enable System Header Documentation in bindgen Library (Rust) Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/faq.md This Rust code snippet shows how to instruct bindgen to generate documentation for system headers. By calling `builder.clang_arg("-fretain-comments-from-system-headers")`, bindgen will attempt to retain and include comments from system headers, which are typically omitted by libclang. ```rust builder.clang_arg("-fretain-comments-from-system-headers") ``` -------------------------------- ### Rust build.rs Script for Compiling C and Generating Bindings Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/non-system-libraries.md This Rust script compiles a C source file into a static library and then uses `rust-bindgen` to generate Rust bindings for the C header. It handles path canonicalization, compiler and archiver commands, and writing the generated bindings to the output directory. ```rust use std::env; use std::path::PathBuf; fn main() { // This is the directory where the `c` library is located. let libdir_path = PathBuf::from("hello") // Canonicalize the path as `rustc-link-search` requires an absolute // path. .canonicalize() .expect("cannot canonicalize path"); // This is the path to the `c` headers file. let headers_path = libdir_path.join("hello.h"); let headers_path_str = headers_path.to_str().expect("Path is not a valid string"); // This is the path to the intermediate object file for our library. let obj_path = libdir_path.join("hello.o"); // This is the path to the static library file. let lib_path = libdir_path.join("libhello.a"); // Tell cargo to look for shared libraries in the specified directory println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap()); // Tell cargo to tell rustc to link our `hello` library. Cargo will // automatically know it must look for a `libhello.a` file. println!("cargo:rustc-link-lib=hello"); // Run `clang` to compile the `hello.c` file into a `hello.o` object file. // Unwrap if it is not possible to spawn the process. if !std::process::Command::new("clang") .arg("-c") .arg("-o") .arg(&obj_path) .arg(libdir_path.join("hello.c")) .output() .expect("could not spawn `clang`") .status .success() { // Panic if the command was not successful. panic!("could not compile object file"); } // Run `ar` to generate the `libhello.a` file from the `hello.o` file. // Unwrap if it is not possible to spawn the process. if !std::process::Command::new("ar") .arg("rcs") .arg(lib_path) .arg(obj_path) .output() .expect("could not spawn `ar`") .status .success() { // Panic if the command was not successful. panic!("could not emit library file"); } // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for // the resulting bindings. let bindings = bindgen::Builder::default() // The input header we would like to generate // bindings for. .header(headers_path_str) // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. .expect("Unable to generate bindings"); // Write the bindings to the $OUT_DIR/bindings.rs file. let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs"); bindings .write_to_file(out_path) .expect("Couldn't write bindings!"); } ``` -------------------------------- ### Include Generated Bindings in Rust (Rust) Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/tutorial-4.md This snippet demonstrates how to use the `include!` macro in `src/lib.rs` to incorporate generated FFI bindings. It also includes pragmas to suppress common warnings related to non-standard naming conventions in C libraries. This method is essential for making C functions and types available in your Rust code. ```rust #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); ``` -------------------------------- ### Specify libclang Path for bindgen Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md Sets the LIBCLANG_PATH environment variable to help bindgen locate a specific version of libclang when multiple versions are installed. This is useful for resolving build issues related to libclang detection. ```sh export LIBCLANG_PATH=path/to/clang-9.0/lib ``` -------------------------------- ### Hide Element with rustbindgen Annotation (C++) Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/blocklisting.md Example of using the `///
` annotation in C++ comments to prevent a class or other element from being included in Rust bindings generated by bindgen. ```cpp ///
class Foo { // ... }; ``` -------------------------------- ### Pass Clang Arguments for Compiler Options Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Demonstrates how to pass arguments directly to Clang for configuring include paths, defining preprocessor macros, setting the target architecture, and specifying a sysroot. Arguments can be passed individually or as a slice. ```rust use bindgen::Builder; fn main() { let bindings = Builder::default() .header("mylib.h") // Add include search paths .clang_arg("-I/usr/local/include") .clang_arg("-I./vendor/include") // Define preprocessor macros .clang_arg("-DFEATURE_ENABLED=1") .clang_arg("-DVERSION=100") // Set the target architecture .clang_arg("--target=x86_64-unknown-linux-gnu") // Use a specific sysroot .clang_arg("--sysroot=/path/to/sysroot") // Multiple arguments at once .clang_args(["-x", "c++", "-std=c++17"]) // Retain comments from system headers for documentation .clang_arg("-fretain-comments-from-system-headers") .generate() .expect("Unable to generate bindings"); bindings.write_to_file("bindings.rs").unwrap(); } // Environment variable alternative: // BINDGEN_EXTRA_CLANG_ARGS="--sysroot=/path/to/sysroot -I/extra/include" ``` -------------------------------- ### Generate Rust FFI Bindings with bindgen CLI (Bash) Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Illustrates using the bindgen command-line interface to generate Rust FFI bindings. It covers basic usage, generating bindings with specific options like allowlisting and disabling layout tests, targeting custom architectures, processing C++ headers, and viewing help information. ```bash # Install bindgen CLI car go install bindgen-cli # Generate bindings from a header file bindgen input.h -o bindings.rs # Generate bindings with specific options bindgen input.h \ --allowlist-function "my_function.*" \ --allowlist-type "MyStruct" \ --no-layout-tests \ -o bindings.rs # Generate bindings for a custom target bindgen input.h -o bindings.rs -- --target=armv7a-none-eabi # Process C++ headers bindgen input.hpp -o bindings.rs -- -x c++ -std=c++14 # Show all available options bindgen --help ``` -------------------------------- ### Initializing Rust Structs with Default Padding Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/faq.md This Rust code illustrates how to initialize a struct, potentially containing bindgen-generated padding fields, by leveraging the `Default` trait. The `..Default::default()` syntax ensures that any padding fields are correctly initialized. ```rust SRC_DATA { field_a: "foo", field_b: "bar", ..Default::default() } ``` -------------------------------- ### Run bindgen with Nightly rustfmt via CLI Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/code-formatting.md This command demonstrates how to execute the bindgen CLI application using a nightly release of rustfmt. This is useful for enabling unstable rustfmt features like normalizing doc attributes. ```bash rustup run nightly bindgen [ARGS] ``` -------------------------------- ### Generate Rust FFI Bindings with Builder API (Rust) Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Demonstrates using the bindgen Builder API in a build.rs script to programmatically generate Rust FFI bindings from a C/C++ header file. It configures the builder, specifies the header, and writes the generated bindings to the output directory. ```rust use bindgen::Builder; use std::path::PathBuf; use std::env; fn main() { // Create a builder with the input header let bindings = Builder::default() // Specify the input header file .header("wrapper.h") // Tell cargo to invalidate the built crate when headers change .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) // Generate the bindings .generate() .expect("Unable to generate bindings"); // Write the bindings to $OUT_DIR/bindings.rs let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); } ``` -------------------------------- ### Initializing Objective-C Classes in Rust Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/objc.md To initialize an Objective-C class like `Foo` from Rust, you typically use a pattern involving `alloc` and an initializer method. The syntax `Foo(Foo::alloc().initWithStuff())` demonstrates allocating an instance and then calling an initialization method, which is common for Objective-C object creation. ```rust let label = UILabel(UILabel::alloc().init()); // Or for a more complex initializer: // let label = UILabel(UILabel::alloc().initWithFrame(CGRect::zero())); ``` -------------------------------- ### C++ Constructor vs. Rust `new` Method Semantics Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/cpp.md This snippet illustrates the difference in value semantics between a C++ constructor and the Rust `MyClass::new` method generated by bindgen. It shows the idiomatic Rust way to call the constructor directly when C++ value semantics are critical. ```rust let instance = std::mem::MaybeUninit::::uninit(); MyClass_MyClass(instance.as_mut_ptr()); instance.assume_init_mut().method(); ``` -------------------------------- ### Configure bindgen to use Nightly rustfmt via Library API Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/code-formatting.md This Rust code snippet shows how to programmatically configure bindgen to use a specific rustfmt executable, such as a nightly release. It involves finding the path to the nightly rustfmt using `rustup` and passing it to the `Builder::with_rustfmt` method. ```rust use bindgen::Builder; use std::process::Command; fn main() { let output = Command::new("rustup") .args(["which", "rustfmt", "--toolchain", "nightly"]) .output() .expect("Could not spawn `rustup` command"); assert!( output.status.success(), "Unsuccessful status code when running `rustup`: {output:?}", ); let rustfmt_path = String::from_utf8(output.stdout).expect("The `rustfmt` path is not valid `utf-8`"); let bindings = Builder::default() .header("path/to/input.h") .with_rustfmt(rustfmt_path) .generate() .expect("Could not generate bindings"); bindings .write_to_file("path/to/output.rs") .expect("Could not write bindings"); } ``` -------------------------------- ### Include Header in C for Bindgen Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/tutorial-2.md This C code snippet demonstrates how to include a header file (`bzlib.h`) within a `wrapper.h` file. This is a common practice in Rust bindgen to consolidate declarations from multiple C/C++ headers into a single entry point for generating bindings. ```c #include ``` -------------------------------- ### Blocklist File using bindgen::Builder (Rust) Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/blocklisting.md Shows how to blocklist all items from a specific file path using the `bindgen::Builder` in Rust. This is useful for excluding definitions from system headers or other included files. ```rust use bindgen::Builder; fn main() { let builder = Builder::default() .blocklist_file("/path/to/some/header.h"); // ... rest of the builder configuration and generation } ``` -------------------------------- ### Build bindgen Library and Executable Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md Compiles the bindgen library and its command-line executable. This is a standard Cargo build command. ```sh cargo build ``` -------------------------------- ### Multi-line C/C++ Annotation for bindgen Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/customizing-generated-bindings.md This snippet shows the usage of a multi-line C/C++ comment containing a `rustbindgen` annotation. Similar to single-line comments, this allows for customization of bindgen's output. It's useful for more verbose annotations or when working with existing multi-line comment blocks. No external dependencies are needed. ```c /** *
*/ ``` -------------------------------- ### Control Bindings with Allowlisting (Rust) Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Shows how to use the `allowlist_` methods in bindgen's Builder API to precisely control which C/C++ types, functions, and variables are included in the generated Rust FFI bindings. This is crucial for managing dependencies, especially with C++ STL headers. ```rust use bindgen::Builder; fn main() { let bindings = Builder::default() .header("mylib.h") // Only generate bindings for specific functions .allowlist_function("my_init") .allowlist_function("my_process") .allowlist_function("my_cleanup") // Only generate bindings for specific types .allowlist_type("MyConfig") .allowlist_type("MyResult") // Only generate bindings for specific variables .allowlist_var("MY_VERSION") // Allowlist everything from a specific file .allowlist_file(".*/mylib\.h") // Allowlist any item matching a pattern (type, function, or var) .allowlist_item("my_.*") // Disable recursive allowlisting if needed // (by default, types used by allowlisted items are also included) .allowlist_recursively(false) .generate() .expect("Unable to generate bindings"); bindings.write_to_file("bindings.rs").unwrap(); } ``` -------------------------------- ### Control Bindings with Blocklisting (Rust) Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Demonstrates using the `blocklist_` methods in bindgen's Builder API to exclude specific C/C++ types, functions, variables, or entire files from the generated Rust FFI bindings, while still allowing them to be referenced if necessary. This is useful for managing system headers or internal implementation details. ```rust use bindgen::Builder; fn main() { let bindings = Builder::default() .header("mylib.h") // Blocklist specific types (they won't be generated but can be referenced) .blocklist_type("InternalStruct") // Blocklist specific functions .blocklist_function("internal_.*") // Blocklist specific variables .blocklist_var("DEBUG_.*") // Blocklist entire files (useful for system headers) .blocklist_file(".*/bits/.*") .blocklist_file(".*/sys/.*") // Blocklist any item by name .blocklist_item("__.*") .generate() .expect("Unable to generate bindings"); bindings.write_to_file("bindings.rs").unwrap(); } ``` -------------------------------- ### Executing Cargo Tests for Rust Bindgen Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/tutorial-5.md This bash script demonstrates how to run cargo tests for the bindgen-tutorial-bzip2-sys project. It shows the compilation process, test execution, and the final test results, indicating success. ```bash $ cargo test Compiling bindgen-tutorial-bzip2-sys v0.1.0 Finished debug [unoptimized + debuginfo] target(s) in 0.54 secs Running target/debug/deps/bindgen_tutorial_bzip2_sys-1c5626bbc4401c3a running 15 tests test bindgen_test_layout___darwin_pthread_handler_rec ... ok test bindgen_test_layout___sFILE ... ok test bindgen_test_layout___sbuf ... ok test bindgen_test_layout__bindgen_ty_1 ... ok test bindgen_test_layout__bindgen_ty_2 ... ok test bindgen_test_layout__opaque_pthread_attr_t ... ok test bindgen_test_layout__opaque_pthread_cond_t ... ok test bindgen_test_layout__opaque_pthread_condattr_t ... ok test bindgen_test_layout__opaque_pthread_mutex_t ... ok test bindgen_test_layout__opaque_pthread_mutexattr_t ... ok test bindgen_test_layout__opaque_pthread_once_t ... ok test bindgen_test_layout__opaque_pthread_rwlock_t ... ok test bindgen_test_layout__opaque_pthread_rwlockattr_t ... ok test bindgen_test_layout__opaque_pthread_t ... ok block 1: crc = 0x47bfca17, combined CRC = 0x47bfca17, size = 2857 bucket sorting ... depth 1 has 2849 unresolved strings depth 2 has 2702 unresolved strings depth 4 has 1508 unresolved strings depth 8 has 538 unresolved strings depth 16 has 148 unresolved strings depth 32 has 0 unresolved strings reconstructing block ... 2857 in block, 2221 after MTF & 1-2 coding, 61+2 syms in use initial group 5, [0 .. 1], has 570 syms (25.7%) initial group 4, [2 .. 2], has 256 syms (11.5%) initial group 3, [3 .. 6], has 554 syms (24.9%) initial group 2, [7 .. 12], has 372 syms (16.7%) initial group 1, [13 .. 62], has 469 syms (21.1%) pass 1: size is 2743, grp uses are 13 6 15 0 11 pass 2: size is 1216, grp uses are 13 7 15 0 10 pass 3: size is 1214, grp uses are 13 8 14 0 10 pass 4: size is 1213, grp uses are 13 9 13 0 10 bytes: mapping 19, selectors 17, code lengths 79, codes 1213 final combined CRC = 0x47bfca17 [1: huff+mtf rt+rld {0x47bfca17, 0x47bfca17}] combined CRCs: stored = 0x47bfca17, computed = 0x47bfca17 test tests::round_trip_compression_decompression ... ok test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured Doc-tests bindgen-tutorial-bzip2-sys running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured ``` -------------------------------- ### Generate Rust Wrapper for C++ Class Constructor Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/cpp.md This snippet shows the Rust code generated by bindgen for a C++ class constructor. It includes the struct definition, extern C functions for the constructor and methods, and an implementation block with a `new` method. The `new` method is a Rust substitute for the C++ constructor. ```rust #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct MyClass { pub _address: u8, } extern "C" { #[link_name = "\u{1}_ZN7MyClass6methodEv"] pub fn MyClass_method(this: *mut MyClass); } extern "C" { #[link_name = "\u{1}_ZN7MyClassC1Ev"] pub fn MyClass_MyClass(this: *mut MyClass); } impl MyClass { #[inline] pub unsafe fn method(&mut self) { MyClass_method(self) } #[inline] pub unsafe fn new() -> Self { let mut __bindgen_tmp = ::std::mem::MaybeUninit::uninit(); MyClass_MyClass(__bindgen_tmp.as_mut_ptr()); __bindgen_tmp.assume_init() } } ``` -------------------------------- ### Compile New Test Bindings (Shell) Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md After adding a new header and its expected bindings, this command compiles the new bindings and runs their layout tests within the expectations directory. ```shell cd bindgen-tests/tests/expectations cargo test new_test_header ``` -------------------------------- ### Configure Code Formatting for Bindgen Output Source: https://context7.com/rust-lang/rust-bindgen/llms.txt Controls how the generated Rust code is formatted using bindgen. You can choose between `rustfmt` (default), `prettyplease`, or disabling formatting entirely. It also allows specifying a custom `rustfmt` configuration file, disabling the header comment, and prepending custom lines to the generated file. Additionally, it shows how to configure for `no_std` environments. ```rust use bindgen::{Builder, Formatter}; fn main() { let bindings = Builder::default() .header("mylib.h") // Use rustfmt (default) .formatter(Formatter::Rustfmt) // Or use prettyplease (requires "prettyplease" feature) // .formatter(Formatter::Prettyplease) // Or disable formatting entirely // .formatter(Formatter::None) // Specify a custom rustfmt configuration file .rustfmt_configuration_file(Some("/path/to/rustfmt.toml".into())) // Disable the version comment in generated code .disable_header_comment() // Prepend custom lines to the generated file .raw_line("#![allow(non_upper_case_globals)]") .raw_line("#![allow(non_camel_case_types)]") .raw_line("#![allow(non_snake_case)]") .raw_line("#![allow(dead_code)]") // Generate code for no_std environments .use_core() .ctypes_prefix("crate::ctypes") .generate() .expect("Unable to generate bindings"); bindings.write_to_file("bindings.rs").unwrap(); } ``` -------------------------------- ### Initializing cargo-dist Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md This command initializes the `cargo-dist` configuration within a project. `cargo-dist` is used to automate the creation of release artifacts, such as tarballs for bindgen CLI executables. ```sh cargo dist init ``` -------------------------------- ### Executing Cargo Release Source: https://github.com/rust-lang/rust-bindgen/blob/main/CONTRIBUTING.md This command initiates the release process using `cargo release`. It bumps the version (patch or minor), updates the changelog, tags the commit, and pushes to GitHub. The `--no-publish` flag defers the actual crate publishing until after CI checks pass. ```sh cargo release [patch|minor] --no-publish --execute ``` -------------------------------- ### Generate Rust FFI Bindings from C Header Source: https://github.com/rust-lang/rust-bindgen/blob/main/book/src/introduction.md This snippet demonstrates how rust-bindgen processes a C header file to generate equivalent Rust FFI bindings. It shows the input C struct and function declaration, and the resulting Rust code for the struct and the extern function. ```c typedef struct CoolStruct { int x; int y; } CoolStruct; void cool_function(int i, char c, CoolStruct* cs); ``` ```rust /* automatically generated by rust-bindgen 0.99.9 */ #[repr(C)] pub struct CoolStruct { pub x: ::std::os::raw::c_int, pub y: ::std::os::raw::c_int, } extern "C" { pub fn cool_function(i: ::std::os::raw::c_int, c: ::std::os::raw::c_char, cs: *mut CoolStruct); } ```