Skip to content

Ookii.CommandLine enables command line argument parsing for C++ applications. It allows you to easily define arguments, parse the command line, and generate usage help.

License

SvenGroot/Ookii.CommandLine.Cpp

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Ookii.CommandLine for C++ NuGet

Ookii.CommandLine for C++ is a header-only library that enables comprehensive command line argument parsing for C++ applications. It allows you to easily define strongly-typed required, optional, positional and named arguments, parse the command line, and generate usage help which can be shown to the user. It is cross-platform and has been tested with several compilers (see requirements).

Ookii.CommandLine for C++ is a port of Ookii.CommandLine for .Net, providing the same argument parsing semantics, but using an API that is suitable for C++. It has feature parity with Ookii.CommandLine for .Net 2.4, with the exception of dictionary arguments.

Overview

Ookii.CommandLine is a library that helps you to parse command line arguments for your applications. It allows you to easily define a set of accepted arguments and their types, and then parse the command line supplied to your application for those arguments, converting the value of those arguments from a string to their specified type. In addition, it allows you to generate usage help from the arguments that you defined, which you can display to the user.

Ookii.CommandLine can be used with any kind of C++ application, whether console or GUI. Although a limited subset of functionality—particularly related around generating usage help text—is geared primarily towards console applications that are invoked from the command line, the main command line parsing functionality is usable in any application that needs to process command line arguments.

To define a set of command line arguments, first you create variables that will hold their values. Then, you use the ookii::parser_builder class to construct an ookii::command_line_parser to parse those arguments, specifying things such as the argument names, whether or not an argument is required, and descriptions used to customize the usage help, among other options.

Command line parsing is done in a way that is similar to that used by PowerShell. Each argument has a name, and can be supplied by name on the command line. An argument can also be positional, in which case it can be supplied without the name. Arguments can be required or optional, and there is support for switch arguments (which don't need a value but are either present or not) and arguments with multiple values. Various aspects of the parsing, such as the argument name prefix (typically a - or a /), can be customized.

For example, the following code defines four arguments: a required positional argument, an optional positional argument, a named argument, and a switch argument:

std::string required_argument;
int optional_argument;
float named_argument;
bool switch_argument;

// argv[0] is used for the application name.
auto parser = ookii::parser_builder{argv[0]}
    .add_argument(required_argument, "Required").required().positional()
    .add_argument(optional_argument, "Optional").positional()
    .add_argument(named_argument, "Named")
    .add_argument(switch_argument, "Switch")
    .build();

The application using these arguments would have the following usage syntax (this kind of usage help can be generated by Ookii.CommandLine, and can be customized to include argument descriptions):

Usage: MyApplication.exe [-Required] <string> [[-Optional] <int>] [-Named <float>] [-Switch]

An example invocation of this application, specifying all the arguments, would look like this:

./MyApplication foo 42 -Switch -Named 5.6

Ookii.CommandLine also provides scripts that can generate the above code using a specially annotated struct or class. For example, the below generates the same arguments as above:

// [arguments]
struct arguments
{
    // [argument, required, positional]
    std::string required;
    // [argument, positional]
    int optional;
    // [argument]
    float named;
    // [argument: Switch]
    bool switch_argument;

    OOKII_DECLARE_PARSE_METHOD(arguments);
};

In addition, Ookii.CommandLine can be used to create command line utilities that have multiple subcommands, each with their own arguments (these are called shell commands in Ookii.CommandLine).

Requirements

Ookii.CommandLine for C++ requires the following:

  • A compiler supporting C++20 (tested with Visual C++ 2022, g++ 11, and Clang 141).
  • A standard C++ library supporting the <format> header, or;
    • libfmt if <format> is not available.
  • line_wrapping_ostream, used to generate usage help, relies on dynamic_cast and will require RTTI to be enabled to function correctly.

Ookii.CommandLine for C++ should support any operating system (tested on Windows and Linux). If you want to make sure your platform is supported, you can run the tests.

To use Ookii.CommandLine in your project, the easiest way is to use CMake. If you use Visual Studio, you can also use the NuGet package.

Alternatively, you can clone this repository to get the header files and add the "include" folder to your include path. Since Ookii.CommandLine is entirely implemented in the headers, there are no linking requirements.

Although Ookii.CommandLine is split out into several header files, you typically want to include the following:

#include <ookii/command_line.h>

This gets you all the core functionality, except for shell commands, for which you should include <ookii/shell_command.h> instead.

Building and running tests and samples

Building the tests and samples requires the following:

To build the included tests and samples, clone the repository to a local directory, create a folder to hold the build output, and run CMake to configure the project:

mkdir build
cd build
cmake ..
cmake --build .

Certain tests are known to be broken on tested versions of Clang, and will cause the build to fail. Use cmake .. -DOOKIICL_BROKEN_STD_RANGES=1 to disable these tests.

There are three scripts provided to aid building on Linux: scripts/build.sh, which builds using your default compiler; scripts/build_clang.sh, which forces the use of Clang and also adds the -DOOKIICL_BROKEN_STD_RANGES=1 parameter; and scripts/build_docs.sh, which builds the documentation (requires doxygen and dot).

Running tests

The unit tests require the existence of the nl_NL.UTF-8 locale. If this locale does not exist, you will see one test failure. In Linux, you can generate this locale using the following command:

sudo locale-gen nl_NL.UTF-8

To run the tests, use the following command:

ctest --output-on-failure

If everything passes, your environment is supported. If you want to see more detailed output, you can run the unittests binary directly.

You can also use scripts/build.sh test and scripts/build_clang.sh test to build and run the tests.

Running samples

After building, you will find several samples in the output. There are essentially two samples: one for regular command line parsing, and one to demonstrate shell commands. Each sample comes in two variants, with identical functionality: one that manually builds the arguments, and one that uses the code-generation scripts.

Invoke each sample from the command line, and see their output. The parser sample doesn't do anything other than echo the arguments you provide back, and the shell command sample provides simple functionality for reading and writing a file. All will only print usage help (generated by this library) when invoked without arguments.

CMake usage

To use Ookii.CommandLine in your own project, the easiest option is to include it using CMake.

Ookii.CommandLine provides a Config file for CMake. After installing the library, you can use:

find_package(Ookii.CommandLine CONFIG)

This will add a library called Ookii.CommandLine::OOKIICL, which you can use with target_link_libraries.

You can also use FetchContent to easily incorporate Ookii.CommandLine:

cmake_minimum_required(3.15)

include(FetchContent)

# C++ 20 or later is required for Ookii.CommandLine
set(CMAKE_CXX_STANDARD 20)

FetchContent_Declare(OOKIICL
    GIT_REPOSITORY "https:://github.com/SvenGroot/Ookii.CommandLine.Cpp"
    GIT_TAG "v1.0")

FetchContent_MakeAvailable(OOKIICL)

# Add the header only library to a project.
add_executable(foo)
target_link_libraries(foo PRIVATE Ookii.CommandLine::OOKIICL)

Wide character support

On Windows, you probably want to treat your arguments as wide characters (wchar_t), since that is the native character type used by Windows. For instance, that is the case if you're using the int wmain() entry point, or the CommandLineToArgvW function if you're using WinMain.

The entire Ookii.CommandLine library is implemented using templates which allow the selection of the character type, so they can support both char and wchar_t. The std::command_line_parser class is actually a typedef for std::basic_command_line_parser<char>, and there is a similar typedef std::wcommand_line_parser that translates to std::basic_command_line_parser<wchar_t>.

The same is true of std::parser_builder, std::usage_options, std::shell_command, std::shell_command_manager, and std::shell_command_usage_options which all have wide character versions starting with w.

If you wish to test out Unicode support on Windows, you can compile the unit tests for Unicode by passing -DOOKIICL_UNICODE=1 to CMake. This has no effect on platforms other than Windows, and only applies to the unit tests; no special define is needed for the library itself to use Unicode, except for the <ookii/command_line_generated.h> header (used in conjunction with the code-generation scripts), which requires the _UNICODE define.

Due to limitations of some of the libraries used (in particular, <format>), character types other than char and wchar_t are not supported.

Conditional compilation options

Use the following macros to control the behavior of Ookii.CommandLine, either using #define or the appropriate compiler switch.

Macro Description
_UNICODE If defined, certain templates will default to wchar_t for the character type. The <ookii/command_line_generated.h> header (used in conjunction with the code-generation scripts), uses wchar_t for its declarations. Use on Windows to support Unicode arguments.
OOKII_CONSOLE_DEFINITION See OOKII_CONSOLE_NOT_INLINE.
OOKII_CONSOLE_NOT_INLINE Do not provide an inline definition of platform-specific console functionality. This avoids the need to include platform headers such as <windows.h> in every file that uses the <ookii/command_line.h> header. You must have exactly one C++ file where both OOKII_CONSOLE_NOT_INLINE and OOKII_CONSOLE_DEFINITION are defined prior to including <ookii/console_helper.h>, to provide a definition to the linker. See the unit tests project for an example how to do this. Implies OOKII_NO_PLATFORM_HEADERS unless OOKII_CONSOLE_DEFINITION is defined.
OOKII_FORCE_LIBFMT Use the libfmt library even if the <format> header is available.
OOKII_NO_PLATFORM_HEADERS Do not include platform headers such as <windows.h>. Use this if you have already included them manually with different settings than the <ookii/console_helper.h> header uses. If you want to avoid including them at all, use OOKII_CONSOLE_NOT_INLINE.

More information

Please check out the following to get started:

Footnotes

  1. With the tested versions of Clang, you cannot call the command_line_parser::arguments() method or the shell_command_manager::commands() method, or the build will fail. This is due to broken support for the <ranges> library. This should not affect most users of Ookii.CommandLine.

About

Ookii.CommandLine enables command line argument parsing for C++ applications. It allows you to easily define arguments, parse the command line, and generate usage help.

Resources

License

Stars

Watchers

Forks

Packages

No packages published