Skip to content

Latest commit

 

History

History
155 lines (119 loc) · 5.88 KB

File metadata and controls

155 lines (119 loc) · 5.88 KB

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.

# 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).

# 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.
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:

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:

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:
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.