### Install and Use cbindgen CLI Source: https://context7.com/mozilla/cbindgen/llms.txt Install cbindgen using Cargo and invoke it from the command line. Use the `--config` flag for custom configurations or if `cbindgen.toml` is not in the crate root. The `--verify` flag checks if an existing header is up-to-date. ```bash cargo install --force cbindgen ``` ```bash cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h ``` ```bash cbindgen --config cbindgen.toml --crate my_rust_library --lang c --output my_header.h ``` ```bash cbindgen --config cbindgen.toml --crate my_rust_library --lang cython --output my_bindings.pyx ``` ```bash cbindgen src/lib.rs --lang c --output bindings.h ``` ```bash cbindgen --config cbindgen.toml --crate my_lib --output my_header.h --verify ``` ```bash cbindgen --crate my_lib --output my_header.h --depfile my_header.h.d ``` ```bash cbindgen --crate my_lib --output my_header.h --symfile my_lib.sym ``` ```bash cbindgen -vv --crate my_lib --output my_header.h ``` ```bash cbindgen -d --crate my_lib --output my_header.h ``` -------------------------------- ### Install cbindgen using Cargo Source: https://github.com/mozilla/cbindgen/blob/main/README.md Installs the latest version of cbindgen using the Cargo package manager. The --force flag ensures it updates even if already installed. ```text cargo install --force cbindgen ``` -------------------------------- ### Install cbindgen using Homebrew Source: https://github.com/mozilla/cbindgen/blob/main/README.md Installs cbindgen using the Homebrew package manager on macOS or Linux. ```text brew install cbindgen ``` -------------------------------- ### Rust to C Type Mappings and Struct Examples Source: https://context7.com/mozilla/cbindgen/llms.txt Illustrates the default mappings for Rust primitive and std types to C equivalents. Shows how Rust structs with `#[repr(C)]` are translated into C structs, including handling of pointers, lengths, and evaporated types like PhantomData. ```rust // Rust → C mapping (selected subset) // bool → bool // u8 → uint8_t // u16 → uint16_t // u32 → uint32_t // u64 → uint64_t // usize → uintptr_t (or size_t if usize_is_size_t = true) // i8 → int8_t // i16 → int16_t // i32 → int32_t // i64 → int64_t // isize → intptr_t (or ptrdiff_t if usize_is_size_t = true) // f32 → float // f64 → double // char → uint32_t // VaList → va_list // // libc types: // c_void → void // c_char → char // c_int → int // c_long → long // c_ulong → unsigned long // // Transparent wrappers (unwrapped to inner type): // MaybeUninit, ManuallyDrop, Pin → T // // Pointers: // &T, *const T, Option<&T> → const T* // &mut T, *mut T, Option<&mut T> → T* // fn(A) -> B → B (*)(A) // // Evaporated (zero-sized, field-only): // PhantomData, PhantomPinned, () → (removed from output) // Example Rust structs and their C output: #[repr(C)] pub struct Buffer { pub data: *mut u8, pub len: usize, pub _marker: std::marker::PhantomData<()>, // evaporated } // → typedef struct { uint8_t *data; uintptr_t len; } Buffer; #[repr(C)] pub struct Callback { pub func: Option i32>, } // → typedef struct { int32_t (*func)(int32_t); } Callback; ``` -------------------------------- ### CLI Usage: Generate a C++ header from a Rust crate Source: https://context7.com/mozilla/cbindgen/llms.txt Install cbindgen via Cargo and invoke it pointing at your crate directory. The `--config` flag is optional if a `cbindgen.toml` exists in the crate root. ```APIDOC ## CLI Usage: Generate a C++ header from a Rust crate ### Description Install cbindgen via Cargo and invoke it pointing at your crate directory. The `--config` flag is optional if a `cbindgen.toml` exists in the crate root. ### Commands - **Install cbindgen** ```bash cargo install --force cbindgen ``` - **Generate a C++ header (default)** ```bash cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h ``` - **Generate a C header** ```bash cbindgen --config cbindgen.toml --crate my_rust_library --lang c --output my_header.h ``` - **Generate Cython bindings** ```bash cbindgen --config cbindgen.toml --crate my_rust_library --lang cython --output my_bindings.pyx ``` - **Generate from a single source file** ```bash cbindgen src/lib.rs --lang c --output bindings.h ``` - **Verify that an existing header is up-to-date (exits with code 2 if changed)** ```bash cbindgen --config cbindgen.toml --crate my_lib --output my_header.h --verify ``` - **Generate a depfile alongside the header (useful for build systems like CMake/Ninja)** ```bash cbindgen --crate my_lib --output my_header.h --depfile my_header.h.d ``` - **Generate a linker symbol file listing all exported dynamic symbols** ```bash cbindgen --crate my_lib --output my_header.h --symfile my_lib.sym ``` - **Verbose output** ```bash cbindgen -vv --crate my_lib --output my_header.h ``` - **Parse all dependencies when generating** ```bash cbindgen -d --crate my_lib --output my_header.h ``` ``` -------------------------------- ### Struct Annotation for Operator Attributes Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Use `eq-attributes` to emit custom attributes before auto-generated comparison operators for structs. This allows for annotating operators, for example, with `[[nodiscard]]`. ```rust /// cbindgen:eq-attributes=MY_ATTRIBUTES #[repr(C)] pub struct Foo { .. } ``` ```c++ MY_ATTRIBUTES bool operator==(const Foo& other) const { ... } ``` -------------------------------- ### Library API: `cbindgen::generate_with_config` Source: https://context7.com/mozilla/cbindgen/llms.txt Use `generate_with_config()` when you need to construct the configuration programmatically without a `cbindgen.toml` file on disk. ```APIDOC ## Library API: `cbindgen::generate_with_config` ### Description Use `generate_with_config()` when you need to construct the configuration programmatically without a `cbindgen.toml` file on disk. ### Usage ```rust // build.rs use cbindgen::{Config, Language}; fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let mut config = Config::default(); config.language = Language::C; config.include_guard = Some("MY_LIB_BINDINGS_H".to_string()); cbindgen::generate_with_config(&crate_dir, config) .expect("Unable to generate bindings") .write_to_file("include/bindings.h"); } ``` ``` -------------------------------- ### Library API: `cbindgen::generate` Source: https://context7.com/mozilla/cbindgen/llms.txt The top-level `generate()` function is the simplest way to integrate cbindgen into a `build.rs`. It automatically looks for a `cbindgen.toml` in the crate root; if none is found, it uses default settings. ```APIDOC ## Library API: `cbindgen::generate` ### Description The top-level `generate()` function is the simplest way to integrate cbindgen into a `build.rs`. It automatically looks for a `cbindgen.toml` in the crate root; if none is found, it uses default settings. ### Usage ```rust // build.rs fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); cbindgen::generate(&crate_dir) .expect("Unable to generate bindings") .write_to_file("include/bindings.h"); } ``` ### Cargo.toml Configuration ```toml [build-dependencies] cbindgen = "0.29" ``` ``` -------------------------------- ### Bindings::write and Bindings::write_to_file Source: https://context7.com/mozilla/cbindgen/llms.txt Output the generated bindings to a file or any `std::io::Write` target. This allows flexibility in where the header files are saved or processed. ```APIDOC ## Library API: `Bindings::write` and `Bindings::write_to_file` ### Description Output generated bindings to a file or any `Write` target. ### Methods - `Bindings::write_to_file(path: &str)`: Writes the bindings to a file at the specified path. Returns `true` if the file contents were changed. - `Bindings::write(writer: &mut dyn io::Write)`: Writes the bindings to any object implementing `std::io::Write`, such as `stdout` or an in-memory buffer. ### Request Example ```rust use cbindgen::Builder; use std::io; fn main() { let bindings = Builder::new() .with_crate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) .generate() .expect("Unable to generate bindings"); // Write to a specific file; returns true if file contents changed let changed = bindings.write_to_file("include/bindings.h"); println!("File changed: {changed}"); // Or write to stdout bindings.write(io::stdout()); // Or write to an in-memory buffer let mut buf: Vec = Vec::new(); bindings.write(&mut buf); let header_text = String::from_utf8(buf).unwrap(); println!("{header_text}"); } ``` ``` -------------------------------- ### CMakeLists.txt for Single Crate Test Source: https://github.com/mozilla/cbindgen/blob/main/tests/depfile/single_crate_config/CMakeLists.txt This CMakeLists.txt file sets up a project to test cbindgen's depfile output with a single crate. It includes a common test script and defines a cbindgen command. ```cmake cmake_minimum_required(VERSION 3.21.0) project(depfile_test LANGUAGES C DESCRIPTION "A CMake Project to test the --depfile output from cbindgen" ) include(../cbindgen_test.cmake) add_cbindgen_command(gen_bindings "${CMAKE_CURRENT_BINARY_DIR}/single_crate.h" --config "${CMAKE_CURRENT_SOURCE_DIR}/config.toml" ) ``` -------------------------------- ### TOML Configuration for Header and Trailer Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Customize the generated binding file by adding custom text at the beginning using `header` and at the end using `trailer` in `cbindgen.toml`. This is useful for including licenses or other boilerplate. ```toml # An optional string of text to output at the beginning of the generated file # default: doesn't emit anything header = "/* Text to put at the beginning of the generated file. Probably a license. */" # An optional string of text to output at the end of the generated file # default: doesn't emit anything trailer = "/* Text to put at the end of the generated file */" ``` -------------------------------- ### Configuring `cbindgen.toml` for header generation Source: https://context7.com/mozilla/cbindgen/llms.txt The `cbindgen.toml` file in the crate root controls output language, C++ compatibility, include guards, header text, namespaces, and standard includes. It also allows for code style customization and specific export/rename rules. ```toml # cbindgen.toml # Output language: "C", "C++", or "Cython" language = "C" # Add extern "C" guards when language = "C" for C++ consumers cpp_compat = true # Include guard and pragma once include_guard = "MY_LIB_BINDINGS_H" pragma_once = true # Prepended / appended text header = "/* Copyright (c) MyCompany. MPL 2.0 */" autogen_warning = "/* Auto-generated by cbindgen. Do NOT edit. */" include_version = true # C++ namespace wrapping (ignored for C output) namespace = "mylib" # Standard headers (suppressed if no_includes = true) sys_includes = ["stdint", "stdbool"] includes = ["platform_defs.h"] after_includes = "#define MY_LIB_VERSION 2" # Code style braces = "SameLine" line_length = 100 tab_width = 2 documentation = true documentation_style = "doxy" # Declaration style: "both" = typedef struct Foo { } Foo; style = "both" [export] prefix = "MY_" include = ["OrphanedStruct"] exclude = ["PrivateType"] [export.rename] "RustTypeName" = "c_type_name" [export.body] "MyStruct" = """ void someMethod() const; """ [fn] prefix = "MY_API" rename_args = "CamelCase" must_use = "MY_MUST_USE" [struct] rename_fields = "CamelCase" derive_constructor = true derive_eq = true [enum] rename_variants = "ScreamingSnakeCase" prefix_with_name = true enum_class = true [const] allow_static_const = true allow_constexpr = true [macro_expansion] bitflags = true # expand bitflags! macros [parse] parse_deps = true include = ["my_dep_crate"] exclude = ["libc"] [parse.expand] crates = ["my_macro_crate"] all_features = false default_features = true [defines] "target_os = windows" = "DEFINE_WINDOWS" "feature = serde" = "DEFINE_SERDE" [ptr] non_null_attribute = "_Nonnull" ``` -------------------------------- ### Generate C++ Header with cbindgen Source: https://github.com/mozilla/cbindgen/blob/main/README.md Generates a C++ header file from a Rust crate. Requires a configuration file (e.g., cbindgen.toml) and specifies the input crate and output file. ```text cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h ``` -------------------------------- ### Generate Bindings from Individual Rust Source Files Source: https://context7.com/mozilla/cbindgen/llms.txt Use `with_src()` to generate bindings from a single `.rs` file when not using a Cargo crate. This is useful for simpler scenarios or when integrating with build systems that don't rely on Cargo. ```rust // build.rs use cbindgen::{Builder, Language}; fn main() { Builder::new() .with_src("src/api.rs") .with_language(Language::C) .with_include_guard("API_H") .generate() .expect("Unable to generate bindings") .write_to_file("include/api.h"); } ``` -------------------------------- ### Write Linker Symbol File for Dynamic Linking Source: https://context7.com/mozilla/cbindgen/llms.txt The `generate_symfile()` method produces a file listing all exported dynamic symbols (functions and statics). This file can be passed to the linker to create a shared library that exposes only the intended public API. ```rust // build.rs fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let bindings = cbindgen::generate(&crate_dir).unwrap(); bindings.write_to_file("include/bindings.h"); bindings.generate_symfile("link/my_lib.sym"); // my_lib.sym contents: // { // my_exported_function; // MY_GLOBAL_STATIC; // }; } ``` -------------------------------- ### Generate Cython Bindings with cbindgen CLI Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Generates Cython bindings from a Rust crate using the cbindgen command-line tool. The --lang cython flag specifies Cython output. ```text cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h --lang cython ``` -------------------------------- ### Emit Make-compatible Depfile for Incremental Builds Source: https://context7.com/mozilla/cbindgen/llms.txt Use `generate_depfile()` to create a Makefile-format dependency file. This lists all Rust source files and `cbindgen.toml` used for header generation, enabling incremental build systems like CMake and Ninja to trigger re-generation only when inputs change. ```rust // build.rs fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); cbindgen::generate(&crate_dir) .expect("Unable to generate bindings") .write_to_file("include/bindings.h"); // must be called first to create the file // Assumes bindings has already been generated; call generate() once, write, then depfile let bindings = cbindgen::generate(&crate_dir).unwrap(); bindings.write_to_file("include/bindings.h"); bindings.generate_depfile("include/bindings.h", "include/bindings.h.d"); // Output (include/bindings.h.d) looks like: // include/bindings.h: \ // /path/to/src/lib.rs \ // /path/to/cbindgen.toml } ``` -------------------------------- ### Generate bindings with explicit Config Source: https://context7.com/mozilla/cbindgen/llms.txt Use `generate_with_config()` in `build.rs` to programmatically define the configuration without a `cbindgen.toml` file. This allows setting options like the target language and include guard directly in the code. ```rust use cbindgen::{Config, Language}; fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let mut config = Config::default(); config.language = Language::C; config.include_guard = Some("MY_LIB_BINDINGS_H".to_string()); cbindgen::generate_with_config(&crate_dir, config) .expect("Unable to generate bindings") .write_to_file("include/bindings.h"); } ``` -------------------------------- ### Generate C Header with cbindgen Source: https://github.com/mozilla/cbindgen/blob/main/README.md Generates a C header file from a Rust crate. This is achieved by adding the --lang c switch to the standard cbindgen command. ```text cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h --lang c ``` -------------------------------- ### Builder::with_src Source: https://context7.com/mozilla/cbindgen/llms.txt Generate bindings from individual Rust source files without needing a Cargo project. This is useful for simpler cases or when integrating with build systems that don't use Cargo. ```APIDOC ## Library API: `Builder::with_src` ### Description Generate bindings from individual Rust source files (no Cargo). ### Method `Builder::with_src(path: &str)` ### Parameters - **path** (string): The path to the Rust source file (e.g., `"src/api.rs"`). ### Request Example ```rust // build.rs use cbindgen::{Builder, Language}; fn main() { Builder::new() .with_src("src/api.rs") .with_language(Language::C) .with_include_guard("API_H") .generate() .expect("Unable to generate bindings") .write_to_file("include/api.h"); } ``` ``` -------------------------------- ### Bindings::generate_symfile Source: https://context7.com/mozilla/cbindgen/llms.txt Write a linker symbol file for dynamic linking or plugin systems. This file lists all exported dynamic symbols, allowing the linker to create a shared library with a controlled public API. ```APIDOC ## Library API: `Bindings::generate_symfile` ### Description Write a linker symbol file for dynamic linking / plugin systems. ### Method `Bindings::generate_symfile(symfile_path: &str)` ### Parameters - **symfile_path** (string): The path where the symbol file will be written. ### Request Example ```rust // build.rs fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let bindings = cbindgen::generate(&crate_dir).unwrap(); bindings.write_to_file("include/bindings.h"); bindings.generate_symfile("link/my_lib.sym"); // my_lib.sym contents: // { // my_exported_function; // MY_GLOBAL_STATIC; // }; } ``` ``` -------------------------------- ### Bindings::generate_depfile Source: https://context7.com/mozilla/cbindgen/llms.txt Emit a Make-compatible depfile for incremental build systems. This file lists all source files and configuration files used, enabling build systems to re-generate bindings only when necessary. ```APIDOC ## Library API: `Bindings::generate_depfile` ### Description Emit a Make-compatible depfile for incremental build systems. ### Method `Bindings::generate_depfile(output_path: &str, depfile_path: &str)` ### Parameters - **output_path** (string): The path to the generated header file (used to determine dependencies). - **depfile_path** (string): The path where the depfile will be written. ### Request Example ```rust // build.rs fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); // Ensure the header is generated first to establish its path for the depfile let bindings = cbindgen::generate(&crate_dir).unwrap(); bindings.write_to_file("include/bindings.h"); // Generate the depfile bindings.generate_depfile("include/bindings.h", "include/bindings.h.d"); // Output (include/bindings.h.d) looks like: // include/bindings.h: \ // /path/to/src/lib.rs \ // /path/to/cbindgen.toml } ``` ``` -------------------------------- ### CMakeLists.txt for Single Crate Default Config Test Source: https://github.com/mozilla/cbindgen/blob/main/tests/depfile/single_crate_default_config/CMakeLists.txt Configures a CMake project to test cbindgen's dependency file output for a single crate. It includes a common CMake script for cbindgen tests and adds a command to generate bindings. ```cmake cmake_minimum_required(VERSION 3.21.0) project(depfile_test LANGUAGES C DESCRIPTION "A CMake Project to test the --depfile output from cbindgen" ) include(../cbindgen_test.cmake) add_cbindgen_command(gen_bindings "${CMAKE_CURRENT_BINARY_DIR}/single_crate.h" ) ``` -------------------------------- ### Fluent Builder for Fine-Grained Binding Generation Source: https://context7.com/mozilla/cbindgen/llms.txt Use the Builder API to construct and customize a cbindgen run entirely in code. Every method returns `Self` for chaining. Configure language, include guards, namespaces, style, and more. ```rust // build.rs use cbindgen::{Builder, Language, Style}; use std::env; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let result = Builder::new() .with_crate(&crate_dir) .with_language(Language::C) .with_include_guard("MY_LIBRARY_H") .with_pragma_once(true) .with_autogen_warning("/* Auto-generated by cbindgen. Do not modify. */") .with_include_version(true) .with_namespace("ffi") .with_header("/* Copyright MyCompany */") .with_tab_width(4) .with_line_length(120) .with_style(Style::Both) .with_cpp_compat(true) // wrap C functions in extern "C" for C++ callers .with_parse_deps(true) // also parse types from dependencies .with_parse_exclude(&["libc"]) // but not libc .with_parse_expand(&["euclid"]) // macro-expand this crate first .with_item_prefix("MY_") // prefix all exported symbols .exclude_item("InternalType") // suppress specific items .rename_item("RustName", "c_name") // rename an item in the output .with_documentation(true) .generate() .expect("Unable to generate bindings"); // Write header; returns true if file contents changed let changed = result.write_to_file("include/my_library.h"); println!("cargo:rerun-if-changed=src/lib.rs"); if changed { println!("Header was updated."); } } ``` -------------------------------- ### Integrate cbindgen into build.rs Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Uses cbindgen as a library within a build.rs script to generate header bindings. It configures the builder with the crate directory and writes the output to a file. ```rust extern crate cbindgen; use std::env; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); cbindgen::Builder::new() .with_crate(crate_dir) .generate() .expect("Unable to generate bindings") .write_to_file("bindings.h"); } ``` -------------------------------- ### Auto-generate bindings in build.rs Source: https://context7.com/mozilla/cbindgen/llms.txt Integrate cbindgen into your `build.rs` script using the `generate()` function. It automatically detects `cbindgen.toml` in the crate root or uses default settings. Ensure `cbindgen` is added as a build dependency in `Cargo.toml`. ```rust use cbindgen; fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); cbindgen::generate(&crate_dir) .expect("Unable to generate bindings") .write_to_file("include/bindings.h"); } ``` ```toml [build-dependencies] cbindgen = "0.29" ``` -------------------------------- ### Build Script with unstable_ir Feature Source: https://context7.com/mozilla/cbindgen/llms.txt This build script demonstrates how to use the `unstable_ir` feature to generate bindings and inspect exported symbol names before writing the header file. Ensure `unstable_ir` is enabled in `Cargo.toml`. ```rust // build.rs (with unstable_ir enabled) use cbindgen::{Builder, Language}; fn main() { let crate_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let bindings = Builder::new() .with_crate(&crate_dir) .with_language(Language::C) .generate() .expect("Unable to generate bindings"); // Inspect exported function names before writing for name in bindings.dynamic_symbols_names() { println!("Exported symbol: {name}"); } bindings.write_to_file("include/bindings.h"); } ``` -------------------------------- ### Output Generated Bindings to a File or Write Target Source: https://context7.com/mozilla/cbindgen/llms.txt The `Bindings` object returned by `Builder::generate()` can be written to a specific file path using `write_to_file()` or to any `std::io::Write` sink, such as stdout or an in-memory buffer. ```rust use cbindgen::Builder; use std::io; fn main() { let bindings = Builder::new() .with_crate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) .generate() .expect("Unable to generate bindings"); // Write to a specific file; returns true if file contents changed let changed = bindings.write_to_file("include/bindings.h"); println!("File changed: {changed}"); // Or write to stdout bindings.write(io::stdout()); // Or write to an in-memory buffer let mut buf: Vec = Vec::new(); bindings.write(&mut buf); let header_text = String::from_utf8(buf).unwrap(); println!("{header_text}"); } ``` -------------------------------- ### TOML Configuration for Include Guard Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Prevent multiple inclusions of header files by defining an `include_guard` in `cbindgen.toml`. You can also enable `#pragma once` with the `pragma_once` option. ```toml # An optional name to use as an include guard # default: doesn't emit an include guard include_guard = "mozilla_wr_bindings_h" # Whether to add a `#pragma once` guard # default: doesn't emit a `#pragma once` pragma_once = true ``` -------------------------------- ### Exporting Rust items with `#[no_mangle]` and `#[repr(C)]` Source: https://context7.com/mozilla/cbindgen/llms.txt Use `#[no_mangle]` for functions and statics, and `#[repr(C)]` for types to ensure stable memory layout for C compatibility. Items marked with `/// cbindgen:ignore` or within modules marked similarly are skipped. ```rust // src/lib.rs /// A 2D point with f32 coordinates. ///cbindgen:field-names=[x, y] ///cbindgen:derive-eq #[repr(C)] pub struct Point(pub f32, pub f32); /// Status codes returned by library functions. #[repr(u8)] pub enum Status { Ok = 0, Error = 1, NotFound = 2, } /// cbindgen:ignore mod internal_helpers {} // not scanned /// cbindgen:no-export #[repr(C)] pub struct InternalHandle { pub id: u64 } // known to cbindgen but not emitted #[no_mangle] pub extern "C" fn point_distance(a: Point, b: Point) -> f64 { let dx = (b.0 - a.0) as f64; let dy = (b.1 - a.1) as f64; (dx * dx + dy * dy).sqrt() } #[no_mangle] pub extern "C" fn get_version() -> *const std::os::raw::c_char { b"1.0.0\0".as_ptr() as *const _ } pub const MAX_POINTS: u32 = 1024; // Generated C++ header excerpt: // // struct Point { // float x; // float y; // bool operator==(const Point& other) const { ... } // }; // // enum class Status : uint8_t { Ok = 0, Error = 1, NotFound = 2 }; // // static const uint32_t MAX_POINTS = 1024; // // double point_distance(Point a, float b); // const char *get_version(); ``` -------------------------------- ### Add cbindgen as a build dependency Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Specifies cbindgen as a build dependency in Cargo.toml, required for using it within a build.rs script. ```toml [build-dependencies] cbindgen = "0.24.0" ``` -------------------------------- ### TOML Configuration for Output Language Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Specify the target output language for bindings using the `language` option in `cbindgen.toml`. Supported languages include C, C++, and Cython. ```toml # The language to output bindings in # # possible values: "C", "C++", "Cython" # # default: "C++" language = "C" ``` -------------------------------- ### Swift Name Generation Configuration Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Configure `cbindgen` to generate Swift-specific attributes like `swift_name` by setting the `swift_name_macro` option in `cbindgen.toml`. This helps in creating more idiomatic Swift APIs. ```toml # The Swift name macro to use # possible values: "NS_SWIFT_NAME", "CF_SWIFT_NAME" # default: "NS_SWIFT_NAME" s swift_name_macro = "NS_SWIFT_NAME" ``` -------------------------------- ### Builder API for Fine-grained Binding Generation Source: https://context7.com/mozilla/cbindgen/llms.txt The `Builder` is the core API for constructing and customizing a cbindgen run entirely in code. Every method returns `Self` for chaining, allowing for a fluent interface to configure binding generation. ```APIDOC ## Builder API ### Description The `Builder` is the core API for constructing and customizing a cbindgen run entirely in code. Every method returns `Self` for chaining. ### Usage Example ```rust // build.rs use cbindgen::{Builder, Language, Style}; use std::env; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let result = Builder::new() .with_crate(&crate_dir) .with_language(Language::C) .with_include_guard("MY_LIBRARY_H") .with_pragma_once(true) .with_autogen_warning("/* Auto-generated by cbindgen. Do not modify. */") .with_include_version(true) .with_namespace("ffi") .with_header("/* Copyright MyCompany */") .with_tab_width(4) .with_line_length(120) .with_style(Style::Both) .with_cpp_compat(true) // wrap C functions in extern "C" for C++ callers .with_parse_deps(true) // also parse types from dependencies .with_parse_exclude(&["libc"]) .with_parse_expand(&["euclid"]) // macro-expand this crate first .with_item_prefix("MY_") // prefix all exported symbols .exclude_item("InternalType") // suppress specific items .rename_item("RustName", "c_name") // rename an item in the output .with_documentation(true) .generate() .expect("Unable to generate bindings"); // Write header; returns true if file contents changed let changed = result.write_to_file("include/my_library.h"); println!("cargo:rerun-if-changed=src/lib.rs"); if changed { println!("Header was updated."); } } ``` ### Available Methods - `Builder::new()`: Creates a new builder instance. - `Builder::with_crate(path)`: Configures the builder to generate bindings from a Cargo crate at the specified path. - `Builder::with_src(path)`: Configures the builder to generate bindings from a single Rust source file. - `Builder::with_language(language)`: Sets the target language for the bindings (e.g., `Language::C`, `Language::Rust`). - `Builder::with_include_guard(guard)`: Sets the include guard for C/C++ headers. - `Builder::with_pragma_once(enable)`: Enables or disables `#pragma once`. - `Builder::with_autogen_warning(warning)`: Sets a warning message to be included at the top of the generated file. - `Builder::with_include_version(enable)`: Includes the crate version in the generated header. - `Builder::with_namespace(namespace)`: Sets a C++ namespace for the bindings. - `Builder::with_header(header)`: Adds a custom header comment to the generated file. - `Builder::with_tab_width(width)`: Sets the tab width for indentation. - `Builder::with_line_length(length)`: Sets the maximum line length for the generated code. - `Builder::with_style(style)`: Sets the code style for the bindings (e.g., `Style::Both`). - `Builder::with_cpp_compat(enable)`: Enables C++ compatibility by wrapping C functions in `extern "C"`. - `Builder::with_parse_deps(enable)`: Enables parsing of types from dependencies. - `Builder::with_parse_exclude(items)`: Excludes specified items from parsing. - `Builder::with_parse_expand(items)`: Macro-expands specified items before parsing. - `Builder::with_item_prefix(prefix)`: Adds a prefix to all exported symbols. - `Builder::exclude_item(item)`: Suppresses specific items from being exported. - `Builder::rename_item(rust_name, c_name)`: Renames a specific item in the output bindings. - `Builder::with_documentation(enable)`: Includes documentation comments in the generated bindings. - `Builder::generate()`: Generates the bindings and returns a `Bindings` object. ``` -------------------------------- ### Add cbindgen Command Source: https://github.com/mozilla/cbindgen/blob/main/tests/depfile/single_crate/CMakeLists.txt This snippet adds a custom CMake command to generate bindings using cbindgen. It specifies the output header file path. ```cmake add_cbindgen_command(gen_bindings "${CMAKE_CURRENT_BINARY_DIR}/single_crate.h" ) ``` -------------------------------- ### Inline annotations for item-specific configuration Source: https://context7.com/mozilla/cbindgen/llms.txt Use inline doc comments prefixed with `cbindgen:` to override global `cbindgen.toml` settings for individual Rust items. This allows for fine-grained control over field names, derives, function argument renaming, and pointer-to-array conversions. ```rust /// cbindgen:field-names=[width, height] ///cbindgen:derive-constructor ///cbindgen:derive-eq ///cbindgen:eq-attributes=[[nodiscard]] #[repr(C)] pub struct Size(pub f32, pub f32); // Generates: // struct Size { float width; float height; // Size(float width, float height) : width(width), height(height) {} // [[nodiscard]] bool operator==(const Size& o) const { ... } // }; /// cbindgen:enum-trailing-values=[_Count] /// cbindgen:add-sentinel #[repr(u8)] pub enum Direction { North, South, East, West } // Generates a sentinel variant _Count at the end (never pass back to Rust!) /// cbindgen:rename-all=ScreamingSnakeCase /// cbindgen:prefix=DIR_ #[no_mangle] pub extern "C" fn compute_direction(input_angle: f32) -> Direction { todo!() } // Function args renamed: input_angle => INPUT_ANGLE /// cbindgen:ptrs-as-arrays=[[data; count]] #[no_mangle] pub extern "C" fn process_buffer(data: *const u8, count: usize) -> i32 { todo!() } // data: *const u8 becomes: const uint8_t data[count] /// cbindgen:ignore pub mod internal {} // entire module skipped /// cbindgen:no-export #[repr(C)] pub struct OpaqueRef { _private: u64 } // Known to cbindgen for type resolution, but not emitted in the header ``` -------------------------------- ### Enable unstable_ir Feature in Cargo.toml Source: https://context7.com/mozilla/cbindgen/llms.txt To use the `unstable_ir` feature for accessing cbindgen's internal representation, add the feature flag to the `cbindgen` dependency in your `Cargo.toml` file. Pinning to a specific version is recommended as the IR is not stable. ```toml # Cargo.toml [build-dependencies] cbindgen = { version = "=0.29.2", features = ["unstable_ir"] } ``` -------------------------------- ### Function Annotation for Pointers as Arrays Source: https://github.com/mozilla/cbindgen/blob/main/docs.md The `ptrs-as-arrays` annotation allows you to represent pointer arguments of a function as arrays. You can specify the array length or leave it empty for an unsized array. ```rust /// ptrs-as-arrays=[[ptr_name1; array_length1], [ptr_name2; array_length2], ...] ``` -------------------------------- ### Struct Field Renaming and Eq Derivation with Annotations Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Use inline annotations to rename struct fields and opt into deriving the `PartialEq` trait. Ensure strings in annotations do not contain '=', ',', '[', or ']'. ```rust /// cbindgen:field-names=[x, y] /// cbindgen:derive-eq #[repr(C)] pub struct Point(pub f32, pub f32); ``` -------------------------------- ### Handle cbindgen Parse Errors in build.rs Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Modifies the build.rs script to ignore specific cbindgen parse errors, preventing the build from failing. Other errors are still propagated. ```rust // ... .generate() .map_or_else( |error| match error { cbindgen::Error::ParseSyntaxError { .. } => {} // Ignore parse errors e => panic!(?:{:?}), // Panic on other errors }, |bindings| { bindings.write_to_file("target/include/bindings.h"); }, ); } ``` -------------------------------- ### Ignoring Modules with Annotations Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Manually ignore specific modules from being scanned by cbindgen using the `ignore` annotation. This prevents cbindgen from processing the annotated item. ```rust pub mod my_interesting_mod; /// cbindgen:ignore pub mod my_uninteresting_mod; // This won't be scanned by cbindgen. ``` -------------------------------- ### Suppressing Item Export with No-Export Annotation Source: https://github.com/mozilla/cbindgen/blob/main/docs.md Use the `no-export` annotation to prevent an item from being emitted in the header while still allowing cbindgen to be aware of it. This is useful for suppressing errors or for emitting types defined in other headers. ```rust /// cbindgen:no-export #[repr(C)] pub struct Foo { .. }; // This won't be emitted by cbindgen in the header #[repr(C)] fn bar() -> Foo { .. } // Will be emitted as `struct foo bar();` ``` -------------------------------- ### Enum Annotation for Trailing Values Source: https://github.com/mozilla/cbindgen/blob/main/docs.md The `enum-trailing-values` annotation adds specified fieldless enum variants to the end of an enum definition. Be aware that using these added variants in Rust can lead to undefined behavior. ```rust /// enum-trailing-values=[variant1, variant2, ...] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.