Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Anatomy of a generated header

Every header cheadergen writes follows the same fixed section order. This page walks through that order top-to-bottom and points at the cheadergen.toml options that influence each section.

Knowing the structure helps when reading a generated header and if you’re trying to customise the output.

Options like preamble, [header.<name>].include_guard, and [package.<name>] live in cheadergen.toml. See Global configuration for how the file is discovered and loaded; this page focuses on which section each option affects.

The sections, in order

#SectionConfigured by
1Preamble (verbatim text)preamble
2Include guard or #pragma once[header.<name>].include_guard, pragma_once
3Autogen warningautogen_warning
4Standard <...> includesno_includes, usize_is_size_t (adds <stddef.h>)
5User includesincludes
6Dependency-crate #includespartitioned mode only (automatic)
7After-includes (verbatim text)after_includes
8CHEADERGEN_ALIGNED(n) macroemitted automatically if any type has #[repr(C, align(N))]
9Type definitions (structs, unions, enums, typedefs) and their associated constantsdocumentation, documentation_style, documentation_length, style, sort_by, [package.<name>] types, usize_is_size_t
10Free const items as #define macros[constant].sort_by, constants opt-in flags
11extern "C" { … } open bracecpp_compat (C-only)
12static declarations[static].sort_by
13Function declarations[fn].sort_by
14extern "C" close bracecpp_compat
15Include guard closeinclude_guard
16Trailer (verbatim text)trailer

Where this lives in the code. The emission order is defined in cheadergen_cli/src/codegen.rs (generate_c_header). If a discrepancy ever creeps in between this page and the source, the source wins — please open an issue.

A worked example

Given this Rust crate:

#![allow(unused)]
fn main() {
#[repr(C)]
pub struct Foo {}

impl Foo {
    #[cheadergen::config(export)]
    pub const U8: u8 = 1;
    #[cheadergen::config(export)]
    pub const GREETING: &str = "hello world";
}

#[unsafe(no_mangle)]
pub extern "C" fn root(x: Foo) {}
}

cheadergen generate -l c -o include produces:

/* [3] WARNING: this file was auto-generated by cheadergen from `demo`. Do not edit it manually. */

/* [4] Standard includes */
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

/* [9] Type definition, with its associated constants attached */
typedef struct {

} Foo;
#define Foo_U8 1
#define Foo_GREETING "hello world"

/* [13] Function declaration */
void root(Foo x);

(The bracketed numbers correspond to the section table above; cheadergen itself doesn’t emit them.)

Notes on individual sections

Preamble & trailer (1, 16)

Verbatim text. Useful for license blocks, project-wide banners, or compiler pragmas that aren’t part of cheadergen’s vocabulary. Both are simple string-substitution, cheadergen does not parse what you put in them.

Include guard vs #pragma once (2, 15)

If [header.<name>].include_guard = "FOO_H" is set, you get an #ifndef/#define/#endif triple wrapping the file. If pragma_once = true is set, you get #pragma once. The two are independent, you can use both or neither.

Autogen warning (3)

By default cheadergen synthesizes a warning that names the crate the header came from (workspace-relative path for workspace members, name@version otherwise). Set autogen_warning = "" to suppress it entirely; set it to a string to override the default.

Standard includes (4)

cheadergen always emits <stdarg.h>, <stdbool.h>, <stdint.h>, and <stdlib.h> unless you set no_includes = true. <stddef.h> is added only when any item in the header was lowered with usize_is_size_t = true (because that flag introduces size_t and ptrdiff_t).

Dependency includes (6)

In partitioned mode the dependency crate that defines a referenced type gets its own header file, and the consuming header gets a matching #include "dep.h". You don’t need to configure this manually in cheadergen.toml, cheadergen computes the set of includes based on actual type usage.

Type definitions (9)

The heart of the header. Each #[repr(C)] struct/enum/union (or anything forced in via #[cheadergen::config(export)]) becomes a definition here. Associated consts attached to a type are emitted immediately after the type they belong to as #defines.

A topological sort guarantees that by-value type dependencies are defined before their users; for ties, sort_by controls the secondary order.

The extern "C" block (11, 14)

C++ consumers need an extern "C" block to disable name mangling. cheadergen emits one around functions and statics when the cpp_compat option (or --cpp-compat CLI flag) is set on a C header.

Per-header configuration

Sections 1–16 can all be tuned globally or per individual output header via the [header.<name>] section in cheadergen.toml. CLI flags (such as --cpp-compat, --bundle) trump both. The full override priority is documented in the config reference.