CLI11 is a command line parser for C++11 and beyond that provides a rich feature set with a simple and intuitive interface.
# CLI11 Agent Guide
Header-only C++11 command line parser library. CMake is the primary build
system; Meson and Bazel are also supported.
## Quick Build & Test
Use presets. The `dev` workflow is the fastest for iteration; use `default`
before a push to verify the primary header-only mode.
```bash
# Fast iteration (precompiled lib, no examples, ccache; configure + build + test)
cmake --workflow dev
# Full header-only build, matches CI (configure + build + test)
cmake --workflow default
# Or step by step
cmake --preset dev
cmake --build --preset dev
ctest --preset dev
```
The `dev` preset uses `ccache`; install it (`brew install ccache`) or override
with `cmake --preset dev -DCMAKE_CXX_COMPILER_LAUNCHER=`.
## Running a Single Test
Tests are individual Catch2 executables in `build-dev/tests/` (`dev` preset) or
`build/tests/` (`default` preset).
```bash
# Run one test executable directly
./build-dev/tests/AppTest
# Or via CTest with a regex
ctest --preset dev -R AppTest
```
## Key CMake Options
| Option | Default | Purpose |
| -------------------------- | ----------------------- | --------------------------------------- |
| `CLI11_BUILD_TESTS` | `ON` (if top-level) | Build Catch2 test suite |
| `CLI11_BUILD_EXAMPLES` | `ON` (if top-level) | Build `examples/` |
| `CLI11_BUILD_DOCS` | `ON` (if Doxygen found) | Build Doxygen docs |
| `CLI11_SINGLE_FILE` | `OFF` | Generate single `CLI11.hpp` header |
| `CLI11_PRECOMPILED` | `OFF` | Build static lib instead of header-only |
| `CLI11_WARNINGS_AS_ERRORS` | `OFF` | Turn warnings into errors |
| `CLI11_SANITIZERS` | `OFF` | Enable ASan/TSan/UBSan |
| `CLI11_BOOST` | `OFF` | Enable Boost.Optional tests |
| `CLI11_CUDA_TESTS` | `OFF` | Compile tests with NVCC |
`CLI11_SINGLE_FILE` and `CLI11_PRECOMPILED` are mutually exclusive.
## Presets
- `default` — Debug, Ninja, `CLI11_WARNINGS_AS_ERRORS=ON`, export compile
commands.
- `dev` — Inherits `default`, adds `CLI11_PRECOMPILED=ON`,
`CLI11_BUILD_EXAMPLES=OFF`, and `ccache`. An edit to `impl/*_inl.hpp` only
rebuilds the static library, not every test.
- `tidy` — Inherits `default`, adds `clang-tidy` with warnings-as-errors. Uses
precompiled mode, so each `impl/*_inl.hpp` header is analyzed once (in
`src/Precompile.cpp`) instead of in every test and example.
- `iwyu` — Inherits `default`, runs `include-what-you-use`. Also precompiled,
with tests and examples off, so `src/Precompile.cpp` is the only translation
unit and each header is reported once.
```bash
cmake --preset tidy
cmake --build --preset tidy
```
## Include-what-you-use
`brew install include-what-you-use`, then `cmake --preset iwyu` and
`cmake --build --preset iwyu`. The build always succeeds and IWYU writes its
advice to stderr. Nothing enforces it, so read the report and apply what is
correct, with these exceptions:
- Only act on a removal that both standard libraries agree on; take an addition
from either. macOS asks to remove the `<iterator>` includes that Linux needs.
- Keep both `<filesystem>` includes. `Macros.hpp` needs it before the
`__cpp_lib_filesystem` check, and `Validators.hpp` guards its one with
`#if CLI11_HAS_FILESYSTEM`.
- Ignore the "should add" lines for `CLI/CLI.hpp` (an artifact of the private
pragma in each header), `<version>`, `<AvailabilityInternal.h>`, and `<math>`.
`scripts/iwyu.imp` maps the detail headers a standard library asks for to the
C++ header CLI11 should use; read the comment at its top before you add an
entry. It covers both standard libraries, so check Linux after a change:
```bash
docker run --rm -v "$PWD:/src:ro" debian:trixie sh -c '
apt-get update -qq && apt-get install -y -qq iwyu cmake ninja-build g++ &&
cp -r /src /work && rm -rf /work/build* && cd /work &&
cmake --preset iwyu >/dev/null && cmake --build --preset iwyu'
```
## Single Header Generation
Requires Python. Enable with `CLI11_SINGLE_FILE=ON`:
```bash
cmake -S . -B build -DCLI11_SINGLE_FILE=ON
cmake --build build --target CLI11-generate-single-file
# Output: build/single-include/CLI11.hpp
```
Script: `scripts/MakeSingleHeader.py`.
## Library Structure
- `include/CLI/` — Public headers. The umbrella header is `CLI.hpp`.
- `include/CLI/impl/` — `_inl.hpp` implementation headers included by the main
headers.
- `src/` — `.cpp` files used **only** when `CLI11_PRECOMPILED=ON`.
- `single-include/` — CMake rules for the single-header build.
- `tests/` — Catch2 tests. `main.cpp` + `catch.hpp` provide the test runner.
- `tests/data/` — Test data files copied to the build dir automatically.
- `examples/` — Standalone example programs.
- `book/` — Extra documentation/examples built only when top-level.
## Testing Notes
- Catch2 is auto-downloaded (v2.13.10 header) if not found on the system. Both
Catch2 v2 and v3 are supported.
- Some tests launch helper applications (`ensure_utf8`, `ensure_utf8_twice`)
built from `tests/applications/`.
- `FuzzFailTest` requires C++17.
- `WindowsTest` is only built on Windows.
- `DeprecatedTest` compiles with `-Wno-deprecated-declarations`.
- `TimerTest` is in `CLI11_MULTIONLY_TESTS` (exercises multi-threading).
## Code Style & Linting
Pre-commit hooks are configured in `.pre-commit-config.yaml`:
- `clang-format` for C++/C/CUDA
- `cmake-format` for CMake
- `black` for Python
- `prettier` for YAML/Markdown/JSON/etc.
- `codespell` for typos
- `markdownlint-cli2`
- Custom checks: disallow a few common mistakes Run locally:
```bash
prek -a
```
## Version Source of Truth
The version string is read from `include/CLI/Version.hpp` at configure time. Do
not edit project version in `CMakeLists.txt`.