Installing

For most users, a package manager is the simplest path. Build from source when you want the latest branch, need local patches, or prefer to embed Quill directly in your own project.

Package Managers

Package Manager

Installation Command

vcpkg

vcpkg install quill

Conan

conan install quill

Homebrew

brew install quill

Meson WrapDB

meson wrap install quill

Conda

conda install -c conda-forge quill

Bzlmod

bazel_dep(name = "quill", version = "x.y.z")

xmake

xrepo install quill

CMake-Integration

Building and Installing from Source

Use this path when you want a normal install that can later be found with find_package().

git clone https://github.com/odygrd/quill.git
cd quill
mkdir cmake_build
cd cmake_build
cmake ..
make install

Note

To install into a custom directory, configure CMake with -DCMAKE_INSTALL_PREFIX=/quill/install-dir/.

Then use the installed library from a CMake project, you can locate it directly with find_package()

Embedded Project Directory Structure

my_project/
├── CMakeLists.txt
├── main.cpp

Embedded Project CMakeLists.txt

# Set only if needed - quill was installed under a custom non-standard directory
set(CMAKE_PREFIX_PATH /test_quill/usr/local/)

find_package(quill REQUIRED)

# Linking your project against quill
add_executable(example main.cpp)
target_link_libraries(example PRIVATE quill::quill)

Embedding in Your Project

Use this path when you vendor Quill directly into your source tree and include it with add_subdirectory().

Directory Structure

my_project/
├── quill/            (source folder)
├── CMakeLists.txt
├── main.cpp

CMakeLists.txt

add_subdirectory(quill)
add_executable(my_project main.cpp)
target_link_libraries(my_project PRIVATE quill::quill)

Using the Bundled Formatter

Targets that only need formatting can use the bundled formatter without inheriting Quill’s logging compile options, definitions, or link dependencies.

With CMake, quill::fmtquill is available after find_package(quill REQUIRED) or add_subdirectory(quill):

find_package(quill REQUIRED)
target_link_libraries(my_project PRIVATE quill::fmtquill)

With Meson, use the installed fmtquill pkg-config dependency or fall back to the Quill subproject:

fmtquill_dep = dependency('fmtquill', fallback : ['quill', 'fmtquill_dep'])
executable('my_project', 'main.cpp', dependencies : [fmtquill_dep])

With Bazel, add @quill//:fmtquill to the target’s deps.

Include quill/bundled/fmt/format.h and use fmtquill::format or specialize fmtquill::formatter. These header-only dependencies use Quill’s bundled, patched fmt in the fmtquill namespace; its version follows the Quill release.

Using the C++20 Module

Quill provides an experimental C++20 named module interface (src/quill.cc). It is opt-in; normal header-only use continues to require only C++17.

With CMake 3.28 or newer and a compiler and generator supporting C++20 modules, set CMAKE_CXX_STANDARD=20 and QUILL_BUILD_MODULE=ON when adding Quill through add_subdirectory or FetchContent. Link against quill::quill_module:

target_link_libraries(my_project PRIVATE quill::quill_module)

The module target is currently available from the source build, not from an installed find_package(quill) package.

With Bazel 9 or newer, the declared rules_cc 0.2.22 dependency, and a toolchain supporting C++20 modules, add @quill//:quill_module to the target’s deps. Enable C++20 for the whole build and pass --experimental_cpp_modules (for Clang, use --cxxopt=-std=c++20 --experimental_cpp_modules):

cc_binary(
    name = "my_project",
    srcs = ["main.cpp"],
    features = ["cpp_modules", "prefer_pic_for_opt_binaries"],
    deps = ["@quill//:quill_module"],
)

The selected Clang toolchain must also provide a matching clang-scan-deps beside the compiler executable. On Ubuntu 24.04, install clang-18 and clang-tools-18, and set CC=/usr/lib/llvm-18/bin/clang and CXX=/usr/lib/llvm-18/bin/clang++.

The module target is excluded from wildcard builds. Older Bazel versions can still use @quill//:quill and @quill//:fmtquill without enabling modules.

prefer_pic_for_opt_binaries keeps module producers and consumers in PIC mode, avoiding conflicting module metadata outputs in optimized builds with rules_cc 0.2.22.

The CMake and Bazel module targets define QUILL_USE_MODULE automatically for consumers. Modules do not export macros, so include quill/LogMacros.h after importing Quill when using logging macros. The guarded definition in this example also supports custom module builds:

// GCC/libstdc++ needs these declarations before the module import.
#include <new>
#include <typeinfo>
#include <utility>

import quill;

#ifndef QUILL_USE_MODULE
  #define QUILL_USE_MODULE
#endif
#include "quill/LogMacros.h"

int main()
{
  quill::Backend::start();

  auto console_sink = quill::Frontend::create_or_get_sink<quill::ConsoleSink>("module_docs_sink");
  quill::Logger* logger =
    quill::Frontend::create_or_get_logger("module_docs_logger", std::move(console_sink));

  LOG_INFO(logger, "Logging through the Quill module: {}", 42);
  logger->flush_log();
  quill::Backend::stop();
}

Mixing Module Imports and Headers

Use Quill’s module or its declaration headers consistently throughout an application, including the libraries that use Quill. Mixing the two approaches is unsupported and can create distinct Quill types and separate logger registries and backend state.

The module target depends on the header target for build requirements. This dependency is expected and does not itself create separate Quill state. The macro headers quill/LogMacros.h and quill/HelperMacros.h can be included after importing Quill when QUILL_USE_MODULE is defined.

Next Steps

  • Quick Start for a minimal working example.

  • Guides for sinks, formatters, and advanced configuration.

  • Recipes for common tasks and code examples.