Home

Awesome

C++ utilities

Useful C++ classes and routines such as argument parser, IO and conversion utilities.

Features

The library contains helpers for:

Besides, the library provides a few useful algorithms and data structures:

API/ABI stability

The following counts for c++utilities and my other libraries unless stated otherwise:

Build instructions

These build instructions apply to c++utilities but also to my other projects using it.

Requirements

Build-only dependencies

Runtime dependencies

How to build

Generic example using Ninja:

cmake -G Ninja \
      -S "path/to/source/directory" \
      -B "path/to/build/directory" \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX="/final/install/location"
# build the binaries
cmake --build "path/to/build/directory"
# format source files (optional, must be enabled via CLANG_FORMAT_ENABLED)
cmake --build "path/to/build/directory" --target tidy
# build and run tests (optional)
cmake --build "path/to/build/directory" --target check
# build and run tests measuring test coverage (optional, must be enabled via CLANG_SOURCE_BASED_COVERAGE_ENABLED)
cmake --build "path/to/build/directory" --target coverage
# build API documentation (optional)
cmake --build "path/to/build/directory" --target apidoc
# install binaries, headers and additional files
DESTDIR="/temporary/install/location" \
  cmake --install "path/to/build/directory"

This example is rather generic. For a development build I recommended using CMakePresets as documented in the "CMake presets" section below. It also contains more concrete instructions for building on Windows.

General notes

Windows-specific notes

MacOS-specific notes

Development builds

During development I find it useful to build all required projects (for instance c++utilities, qtutilities, tagparser and tageditor) as one big project.

This can be easily achieved by using CMake's add_subdirectory() function. For project files see the repository subdirs. For an example, see build instructions for Syncthing Tray or build instructions for Tag Editor. The subdirs repository also contains the script sync-all.sh to clone all possibly relevant repositories and keep them up-to-date later on.

For a debug build, use -DCMAKE_BUILD_TYPE=Debug. To tweak various settings (e.g. warnings) for development, use -DENABLE_DEVEL_DEFAULTS=ON.

CMake presets

There are some generic presets available but also some specific to certain Arch Linux packaging found in the AUR and my PKGBUILDs repository.

Use cmake --list-presets to list all presets. All cmake commands need to be executed within the source directory. Builds will be created within a sub-directory of the path specified via the environment variable BUILD_DIR.

The most useful presets for development are likely devel, devel-qt6 and debug. Note that the devel preset (and all presets inheriting from it) use ccache which therefore needs to be installed.

Here is a simple example to build with the devel-qt6 preset:

export BUILD_DIR=$HOME/builds                    # set build directory via environment variable
cmake --preset devel-qt6                         # configure build
cmake --build --preset devel-qt6 -- -v           # conduct build
cmake --build --preset devel-qt6 --target check  # run tests
cmake --build --preset devel-qt6 --target tidy   # apply formatting

Note that these presets are supposed to cover all of my projects (so some of them aren't really making a difference when just building c++utilities itself). To use presets in other projects, simply symlink the file CMakePresets.json into the source directory of those projects. This is also done by the "subdirs" projects mentioned in the previous section.

After invoking the configuration via the command-line, you can also open the project in Qt Creator and import it as an existing build (instead of adding a new build configuration).

Remarks for building on Windows

To create a development build on Windows, it is most straight forward to use the devel-qt6 preset in a MSYS2 mingw64 shell. To create a debug build (e.g. to debug with GDB) use the debug-qt6 preset. Set the BUILD_DIR environment variable to specify the directory to store build artefacts.

Run the following commands to build one of my applications and its c++utilities/qtutilities dependencies in one go (in this example Syncthing Tray):

# install dependencies; you may strip down this list depending on the application and features to enable
pacman -Syu git perl-YAML mingw-w64-x86_64-gcc mingw-w64-x86_64-ccache mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-cppunit mingw-w64-x86_64-qt6-base mingw-w64-x86_64-qt6-declarative mingw-w64-x86_64-qt6-tools mingw-w64-x86_64-qt6-svg mingw-w64-x86_64-clang-tools-extra mingw-w64-x86_64-doxygen mingw-w64-x86_64-ffmpeg mingw-w64-x86_64-go mingw-w64-x86_64-libarchive

# clone repositories as mentioned under "Building this straight" in the application's README file
cd /path/to/store/sources
...
git clone ...
...

# configure and invoke the build
cd subdirs/syncthingtray
cmake --preset devel-qt6
cmake --build "$BUILD_DIR/syncthingtray/devel-qt6" devel-qt6 -- -v

Run the following commands to build libraries individually (in this example tagparser) and installing them in some directory (in this example $BUILD_DIR/install) for use in another project:

# install dependencies
pacman -Syu git mingw-w64-x86_64-gcc mingw-w64-x86_64-ccache mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-cppunit

# clone relevant repositories, e.g. here just tagparser and its dependency c++utilities
cd /path/to/store/sources
git config core.symlinks true
git clone https://github.com/Martchus/cpp-utilities.git c++utilities
git clone https://github.com/Martchus/tagparser.git

# configure and invoke the build and installation of the projects individually
cmake --preset devel-qt6 -S c++utilities -DCMAKE_INSTALL_PREFIX="$BUILD_DIR/install"
cmake --build "$BUILD_DIR/c++utilities/devel-qt6" --target install -- -v
ln -rs c++utilities/CMakePresets.json tagparser/CMakePresets.json
cmake --preset devel-qt6 -S tagparser -DCMAKE_INSTALL_PREFIX="$BUILD_DIR/install"
cmake --build "$BUILD_DIR/tagparser/devel-qt6" --target install -- -v

Note that:

Building with MSVC

To build with MSVC you can use the win-x64-msvc-static preset. This preset (and all presets inheriting from it) need various additional environment variables to be set and you need to install dependencies from various sources:

When building with MSVC, do not use any of the MSYS2 shells. The environment of those shells leads to build problems. You can however use CMake and Ninja from MSYS2's mingw-w64 packaging (instead of the CMake version from Qt's installer). Then you need to specify the Ninja executable manually so the CMake invocation would become something like this:

`& "$Env:MSYS2_ROOT\mingw64\bin\cmake.exe" --preset win-x64-msvc-static -DCMAKE_MAKE_PROGRAM="$Env:MSYS2_ROOT\mingw64\bin\ninja.exe" .

To run the resulting binaries, you'll need to make sure the Qt libraries are in the search path, e.g. using $Env:PATH = "$Env:QT_ROOT\bin".

Note that you don't need to install all Visual Studio has to offer. A customized installation with just C++ core features, MSVC x86/x64 build tools, Windows SDK and vpkg should be enough. In Qt's online installer you can also uncheck everything except the MSVC build of Qt itself.

If the compilation of the resource file doesn't work you can use -DWINDOWS_RESOURCES_ENABLED=OFF to continue the build regardless.

Remarks about special presets

The presets starting with arch- are for use under Arch Linux. Do not use them unless you know what you are doing. When creating a normal build under Arch Linux it is recommended to still use e.g. devel-qt6.

Use the presets starting with arch-*-w64-mingw32 to cross-compile for Windows using mingw-w64 packages. Use the presets starting with arch-static-compat-devel to create a self-contained executable that is also usable under older GNU/Linux distributions using static-compat packages (see PKGBUILDs for details about it).

Packaging

The mentioned repositories contain packages for c++utilities itself but also for my other projects. However, the README files of my other projects contain a more exhaustive list.

Arch Linux package

The repository PKGBUILDs contains files for building Arch Linux packages of the latest release and the Git master.

PKGBUILDs to cross compile for Android, Windows (using mingw-w64) and for MacOS X (using osxcross) are included as well.

RPM packages for openSUSE and Fedora

RPM *.spec files can be found at openSUSE Build Servide. Packages are available for several architectures.

There is also a sub project containing the builds from the Git master branch.

Gentoo

Checkout Case_Of's overlay or perfect7gentleman's overlay.

Copyright notice and license

Copyright © 2015-2024 Marius Kittler

All code is licensed under GPL-2-or-later.