Getting started (C ABI)
This page shows how to include, link, and version libair-base.so from a
C program. For the error model see Error model; for memory
ownership see Memory ownership.
1. Include the header
A single committed, authoritative header:
#include "air_base.h"
The header is generated from the Rust code by cbindgen and committed to the
repository (crates/air-base-capi/include/air_base.h). It carries a “DO NOT EDIT BY
HAND” warning: it is a contract artifact, not a file to tweak. All per-symbol docs
(ownership clauses, thread-safety, return values) already live there as ///
comments; Doxygen renders them to HTML + man pages.
It is #pragma once and C++-compatible (extern "C" guards): usable as-is from a
.c or a .cpp.
2. Link the library
The air-base-capi crate produces a cdylib named libair_base.so (build
artifact), linked with -lair_base:
# From the repo root, after building the cdylib:
cargo build -p air-base-capi # → target/debug/libair_base.so
cc my_program.c \
-I crates/air-base-capi/include \
-L target/debug -lair_base \
-Wl,-rpath,target/debug \
-o my_program
-I …/include: so#include "air_base.h"is found.-L … -lair_base:-lair_baseresolveslibair_base.soat link time.-Wl,-rpath,…: so the loader finds the lib at runtime withoutLD_LIBRARY_PATH(handy in development; in production the lib is installed in a standard directory and carries the sonamelibair-base.so).
Naming note. The build artifact is
libair_base.so(underscore, ⇒-lair_base). The intended installed soname islibair-base.so(hyphen), the project’s public form. Both name the same library; don’t mix the two when linking (use-lair_baseagainst the build tree).
3. Versioning & ABI (ADR-012)
This ABI is a stable contract, guaranteed for 10 years:
- Enum discriminants (
AirStatus,AirLogLevel) are explicit and committed:AIR_STATUS_OK == 0today will stay so. You can hard-wire these values with confidence. - The committed header is diffed in CI: no ABI drift can slip through silently
(
air-abi-check/air-symvertooling). An incompatible change would require a new major soname version. - Buffer sizes are header constants (
AIR_UUID_HYPHENATED_LEN,AIR_ID128_HEX_LEN): always use the constant, never a literal, to stay correct if the format ever changes.
4. Available surface (T1 → T3)
| Domain | Functions | Note |
|---|---|---|
| Identifiers | air_uuid_new_v7/v4, air_uuid_to_hyphenated, air_uuid_parse, air_id128_machine_id, air_id128_to_hex, air_monotonic_id_next | POD + caller buffers |
| Status | air_status_message | static string (do not free) |
| Logging | air_log_open/close, air_log_emit, air_log_lost_count, air_log_fields_new/free/add/add_bytes | opaque handles (+1 on return) |
| Time | air_instant_now, air_instant_elapsed, air_instant_duration_since, air_duration_from_secs/millis/nanos, air_duration_as_secs_f64 | POD, reentrant |
Next step
Before writing any “real” line, read the two pages that govern the correctness of your code:
- Error model — how to check every call.
- Memory ownership & lifecycle — what to free, and with which function.
Version française : Mise en route.