Skip to content
michael.caisse.io michael.caisse.io
c++ cib embedded

CIB Guide

Compile-time Init Build: composing embedded firmware from independent components that the compiler wires together, one library at a time.

compile-time-init-build (cib) is a family of C++ libraries for building firmware from independent components. Each component declares what it provides and what it extends; the compiler collects those declarations and produces the wiring, the ordering, the dispatch tables and the log catalog. What ships is plain calls.

The chapters follow the libraries, starting from the piece everything else plugs into:

  • Nexus is the core: services, components, and the compile-time machinery that joins them.
  • Flow adds ordering, so many components can contribute steps to one sequence.
  • Interrupt describes a system’s interrupts as types and runs flows from ISRs.
  • Message describes wire formats as fields and dispatches incoming data to callbacks.
  • Match is the predicate algebra underneath message dispatch.
  • Logging lets library code log without choosing a backend.
  • Seq is flow’s resumable, reversible sibling for bring-up and tear-down.
  • Lookup builds constant tables whose search strategy is chosen at compile time.

Each chapter stands alone as a reference, with a quick start, the vocabulary, an interactive bench to try the ideas, and a table of pitfalls with the compiler messages they produce.

Chapters

  1. 1 Nexus Components declare what they offer and what they extend. The compiler wires the firmware together — no registration code, no init order to maintain, no dispatch tables.
  2. 2 Flow How independent components add ordered steps to shared flows, and how cib merges them into one dependency graph and sorts it into a plain call sequence at compile time.
  3. 3 Interrupt How to describe a system's interrupts once, as types, and get zero-cost ISR dispatch from interrupt::manager plus runtime enable control from interrupt::dynamic_controller.
  4. 4 Message Describe a wire format once as fields and bits, then read it, write it, match it and dispatch it — with the matching work moved to compile time.
  5. 5 Match Predicates that describe themselves, compose like Boolean expressions, and get simplified before the program ever runs.
  6. 6 Logging How library code logs without choosing a backend, how each call site carries a compile-time environment, and how the binary logger ships IDs instead of strings.
  7. 7 Seq Sequences whose steps can say "not yet, call me again", and which unwind in reverse when you change your mind. Built from the same graph DSL as flow.
  8. 8 Lookup Constant tables whose search strategy is chosen by the compiler from your actual keys — no allocation, no startup cost, and no "not found".