# Building libakerror The ordinary build is an out-of-tree CMake build, described in [the README](../README.md#installation). This file covers what the build generates for you, what it links against, and the configure options that change either of those. ## Configure options | Option | Default | What it does | | ------ | ------- | ------------ | | `AKERR_THREADS` | `auto` | Threading backend: `auto`, `pthread`, or `none`. `auto` takes POSIX threads and **fails the configure** if it cannot find them. See [Building single threaded](thread-safety.md#building-single-threaded). **Must be `none` when `AKERR_USE_STDLIB` is `OFF`** — the pthread backend calls into libc, and the configure fails otherwise. | | `AKERR_USE_STDLIB` | `ON` | Link against the C standard library. See [Dependencies](#dependencies) for what you must supply instead when this is `OFF`. | | `AKERR_RUNTIME_HEADER` | *(empty)* | **Mandatory when `AKERR_USE_STDLIB` is `OFF`.** Header providing `exit`, `memset`, `snprintf`, `strcmp`, `strlen` and `strncpy`; the generated header `#error`s at compile time if it is unset. Defaults to a thin, libc-backed convenience header (`cmake/akerr_default_runtime.h`) so this repository's own `OFF` build and test suite work without a real freestanding runtime — a genuinely freestanding consumer should override it with their own header. | | `AKERR_MAX_ERROR_FNAME_LENGTH` | `4096` | Bytes reserved for the `fname`/`function` fields of `akerr_ErrorContext`. Defaults to `PATH_MAX` on Linux/glibc, which keeps `sizeof(akerr_ErrorContext)` and the soname unchanged; changing it is an ABI break. | | `AKERR_LAST_ERRNO_VALUE_FALLBACK` | `133` | `AKERR_LAST_ERRNO_VALUE` to stamp when `AKERR_USE_STDLIB` is `OFF`, since that configuration cannot shell out to `errno --list`. Defaults to 133 (Linux's `EHWPOISON`). | | `AKERR_STATUS_NAME_SLOTS` | `4096` | Slots in the status-name table; 75% of it is usable. | | `AKERR_MAX_RESERVED_STATUS_RANGES` | `64` | How many status ranges may be reserved in one process. | | `AKERR_SANITIZE` | *(empty)* | Sanitizer list applied to the library and the tests, e.g. `thread` or `address,undefined`. | | `AKERR_COVERAGE` | `OFF` | Instrument the library with gcov counters. | **Behavior change (2.0.2):** pool exhaustion inside `ENSURE_ERROR_READY` (every context-producing macro goes through it) used to call `exit(1)` directly. It now calls `akerr_exit(AKERR_EXIT_STATUS_UNREPRESENTABLE)`, so a process that runs out of pool slots exits **125** instead of **1**. See [UPGRADING.md](../UPGRADING.md). The two capacity options are applied `PRIVATE`: the tables live entirely in `src/error.c`, so raising them never changes anything a consumer can see. See [UPGRADING.md](../UPGRADING.md) for what happens when you exhaust them. ## Templating and autogenerated code The build process relies upon `scripts/generrno.sh` which performs the following: 1. When `AKERR_USE_STDLIB` is `ON`: executes `errno --list` and gathers up the output. When it is `OFF`, this is skipped entirely (`errno --list` needs moreutils and ``, neither freestanding-safe) and `AKERR_LAST_ERRNO_VALUE` is taken from the `AKERR_LAST_ERRNO_VALUE_FALLBACK` cache variable instead. 1. Templates `include/akerror.tmpl.h` into `include/akerror.h` to set `AKERR_LAST_ERRNO_VALUE`, `AKERR_THREAD_SAFE`, and `AKERR_MAX_ERROR_FNAME_LENGTH`. 2. Generates `src/errno.c`, which contains a function called by `akerr_init` that initializes all of the status names for the previously defined values of `errno`. Under `AKERR_USE_STDLIB=OFF` this file is a stub, and CMake does not compile it into the library at all — `akerr_init_errno()` is never called in that configuration. Neither generated output is meant to be edited. Change the template or the generator. ## Dependencies This library depends upon `stdlib`, and upon POSIX threads unless it is built with `-DAKERR_THREADS=none` (see [Thread safety](thread-safety.md)). If you don't want to link against stdlib, build with `-DAKERR_USE_STDLIB=OFF` (which requires `-DAKERR_THREADS=none` — see the options table above) and supply a header, via the `AKERR_RUNTIME_HEADER` cache variable, that provides: - `memset` function - `strncpy` function - `strlen` function - `strcmp` function - `snprintf` function - `exit` function - `bool` type - `NULL` type - `size_t` type - `INT_MAX` constant `` and `` — which give you `bool`/`NULL`/`size_t` — are included unconditionally by the public header regardless of `AKERR_USE_STDLIB`, since both are freestanding-safe. `AKERR_RUNTIME_HEADER` is mandatory in this configuration: the generated header `#error`s at compile time if it is unset. ... then you can compile it thusly: ``` cmake -S . -B build -DAKERR_USE_STDLIB=OFF -DAKERR_THREADS=none \ -DAKERR_RUNTIME_HEADER=/path/to/your/runtime.h cmake --build build cmake --install build ``` If you omit `-DAKERR_RUNTIME_HEADER`, the build falls back to a convenience header backed by the host's own libc (see the options table above), so the `OFF` configuration still builds and its test suite still runs on an ordinary hosted machine — useful for exercising the freestanding code paths without a real freestanding runtime, but not what an actually freestanding consumer wants. Supply your own header to get the real thing.