A lightweight Command Line Argument Parser library written in C++20.
Note: the shared name with clap-rs/clap is pure coincidence!
This is a lightweight, type-safe, C++ option parser library, supporting the standard GNU style syntax for options.
Options can be given as:
-a
^
-ab
^^
--long
^
-abc=argument
^^^ ~~~~~~~~
-abc argument
^^^ ~~~~~~~~
-abcargument
^^^~~~~~~~~
--long=argument
^ ~~~~~~~~
--long argument
^ ~~~~~~~~
where ^
indicates an option and ~~~...
an argument. Here, c
takes an argument while a
and b
do not.
Additionally, anything after --
will be parsed as a positional argument.
#include <clap/options.hpp>
Create a clap::Options
instance.
auto options = clap::Options{
"program name",
"description of program",
"version string",
};
Options are set up by passing a binding reference and the relevant metadata.
struct {
bool debug{};
int log_level{3};
struct {
std::string field{"name"};
bool enabled{};
} sort{};
} input{};
options
// bind an option that's a boolean flag
.flag(input.debug, "d,debug", "enable debugging")
// bind an option that requires an int argument
.required(input.log_level, "log-level", "set the log level", "3")
// bind an option that takes an optional string argument
.optional(input.sort.field, input.sort.enabled, "s,sort", "sort by", "name|date");
Options are declared with a long and an optional short option. A description must be provided. Any type can be given as long as it can be parsed with operator>>
. Options taking arguments also require usage text. Options with optional arguments require an additional bool
flag that's set when the option is passed, regardless of the presence of the argument.
To parse the command line (and set all the bound references to parsed incoming arguments):
auto result = options.parse(argc, argv);
The returned result is simply an enum, and can be used to check whether to continue execution and what code to return:
if (clap::should_quit(result)) { return clap::return_code(result); }
Options taking arguments can be bound to std::vector
s if multiple options are expected to be passed. The vector will be filled in order of the occurrence of the option.
auto defines = std::vector<std::string>{};
options.required(defines, "D,define", "Pass a preprocessor define", "VALUE");
Positional arguments are those given without a preceding flag and can be used alongside non-positional arguments. Set up positional arguments in order:
struct {
std::string source{};
std::string destination{};
} args{};
options
.positional(args.source, "src")
.positional(args.destination, "dst");
Sample input:
program a.txt out/b.txt
^~~~^ ^~~~~~~~^
src dst
By default, arguments not matched to any bound option will result in an error. To instead accept them into an ordered vector:
auto paths = std::vector<std::string>{};
options.unmatched(paths, "paths");
These options are added on a call to parse()
, and handled by the library:
--help
--version
- Adding options with duplicate / repeated keys causes undefined behaviour.
- This includes built-in options.
- All references bound to an
Options
object must outlive all calls toparse()
on it.
- CMake 3.23+
- C++20 compiler and standard library
clap
supports the following ways of integration:
- Vendored in a project.
- Recommended: use CMake
FetchContent
. - Alternatively, use git submodules / an archive in the repository and
add_subdirectory(path/to/clap)
.
- Recommended: use CMake
- Installed separately.
- Recommended: use vcpkg and create an overlay-port with the desired version of
clap
(v0.4.2 or newer) in the project. - Alternatively, install
clap
somewhere manually viacmake --install --prefix=<install_path>
and pass-DCMAKE_PREFIX_PATH=<install_path>
at configure time. - Use
find_package(clap CONFIG REQUIRED)
in the project's CMake script.
- Recommended: use vcpkg and create an overlay-port with the desired version of
However the package is sourced / located, use target_link_libraries(your-target [PRIVATE|PUBLIC] clap::clap)
to link. No other steps are needed (eg setting include paths).
Check out the swanky fibonacci number printer example.
Pull/merge requests are welcome.