Skip to main content

Getting Started

CLI20 is a header-only C++20 CLI parser that treats your command line as a typed schema, not a mutable runtime parser object. Define your interface once as a plain struct and let the library handle parsing, validation, and help generation.

Requirements​

  • C++20-capable compiler (GCC 12+, Clang 14+, MSVC 19.34+)
  • CMake 3.21+ (optional, for CMake-based projects)

Installation​

Option 1 — Copy the headers​

Copy the include/ directory into your project and add it to your include path:

add_library(cli20 INTERFACE)
target_include_directories(cli20 INTERFACE path/to/cli20/include)
target_compile_features(cli20 INTERFACE cxx_std_20)

Option 3 — CMake find_package (installed)​

If you have installed CLI20 via CMake, link the exported target:

find_package(cli20 CONFIG REQUIRED)

add_executable(my_app main.cc)
target_link_libraries(my_app PRIVATE cli20::cli20)

Option 2 — Single header​

If you prefer a single-file drop-in, download cli20.hh from the latest release and copy it anywhere on your include path:

add_library(cli20 INTERFACE)
target_include_directories(cli20 INTERFACE path/to/single_header)
target_compile_features(cli20 INTERFACE cxx_std_20)
#include "cli20.hh" // instead of cli/argument.hh + cli/parser.hh

The single header is auto-generated from the source — do not edit it directly.

Option 3 — CMake find_package​

If you have installed CLI20 via CMake, link the exported target:

find_package(cli20 CONFIG REQUIRED)

add_executable(my_app main.cc)
target_link_libraries(my_app PRIVATE cli20::cli20)

Option 4 — CMake FetchContent​

Fetch directly from the repository at configure time:

include(FetchContent)

FetchContent_Declare(
cli20
GIT_REPOSITORY https://github.com/CLI20-dev/cli20.git
GIT_TAG main
)
FetchContent_MakeAvailable(cli20)

add_executable(my_app main.cc)
target_link_libraries(my_app PRIVATE cli20::cli20)

Your first program​

#include <iostream>

#include "cli/argument.hh"
#include "cli/parser.hh"

struct Args {
cli::Flag<"verbose", 'v'> verbose{{.help = "Enable verbose output"}};
cli::StringOption<"output", 'o'> output{{.help = "Output file path"}};
cli::Positional<std::string> input{{.help = "Input file", .presence = cli::required}};
cli::Help<> help;
};

auto main(int argc, char* argv[]) -> int {
const auto args = cli::parse_or_exit<Args>(argc, argv);

if (args.verbose.value()) {
std::cout << "verbose mode on\n";
}

if (args.output) {
std::cout << "output: " << *args.output << '\n';
}

std::cout << "input: " << *args.input << '\n';
return 0;
}

Run it:

./my_app --verbose -o result.txt source.txt
# verbose mode on
# output: result.txt
# input: source.txt

Get help for free:

./my_app --help

Browse the Examples page when you want a concrete starting point for a specific use case, or continue to the Tutorial to learn the API feature-by-feature.