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.