How to Install fmtlib in C++ Projects: Complete Setup Guide

You can install fmtlib via system package managers (apt, Homebrew, vcpkg, Conan), integrate it with CMake FetchContent, or build from source using the provided CMake targets that support both compiled library and header-only modes.

fmtlib (also known as {fmt}) is a fast, type-safe C++ formatting library hosted at fmtlib/fmt that implements the C++20 std::format API. The library provides three primary installation strategies detailed in doc/get-started.md: package manager installation, CMake FetchContent integration, and building from source using the top-level CMakeLists.txt.

Installation Methods for fmtlib

Using System Package Managers

The fastest way to install fmtlib depends on your platform. According to the official documentation in doc/get-started.md, use the following commands for your environment:

  • Debian/Ubuntu: sudo apt install libfmt-dev
  • macOS: brew install fmt
  • Conda: conda install -c conda-forge fmt
  • vcpkg: vcpkg install fmt
  • Conan: conan install -r conancenter --requires="fmt/[*]" --build=missing

These commands install the library system-wide, making the CMake targets available globally via find_package(fmt).

CMake FetchContent Integration

For projects already using CMake, FetchContent downloads fmtlib at configure time without requiring system installation. Add the following to your CMakeLists.txt:

include(FetchContent)
FetchContent_Declare(
  fmt
  GIT_REPOSITORY https://github.com/fmtlib/fmt.git
  GIT_TAG 10.2.1  # Specify desired version

)
FetchContent_MakeAvailable(fmt)

target_link_libraries(your_target PRIVATE fmt::fmt)

This approach locks the fmtlib version to your project and avoids system dependency management.

Building and Installing from Source

To compile fmtlib manually, clone the repository and use the standard CMake workflow defined in the root CMakeLists.txt:

git clone https://github.com/fmtlib/fmt.git
cd fmt
mkdir build && cd build
cmake ..                     # Add -DFMT_TEST=ON to build tests

make
sudo make install            # Optional: install system-wide

Key CMake options include BUILD_SHARED_LIBS (to build shared vs. static libraries), CMAKE_POSITION_INDEPENDENT_CODE (for position-independent code), and FMT_TEST (to enable the test suite).

CMake Targets and Integration Modes

The root CMakeLists.txt defines three distinct CMake targets that determine how fmtlib integrates with your project:

  • fmt::fmt: The standard compiled library (static or shared depending on BUILD_SHARED_LIBS). Links against the implementation in src/format.cc.
  • fmt::fmt-header-only: Header-only variant that processes include/fmt/format-inl.h directly at each translation unit without requiring a separate compilation step.
  • fmt::fmt-module: C++20 module interface enabled with the -DFMT_MODULE=ON CMake option.

When using fmt::fmt, the linker resolves symbols against the compiled object code from src/format.cc, significantly reducing compilation times in large projects compared to the header-only approach.

Header-Only vs. Compiled Library

fmtlib supports dual architectures. The header-only mode requires no linking step and includes the implementation via include/fmt/format-inl.h, making it ideal for small projects or environments where building a separate library is impractical.

The compiled library mode (the default) processes src/format.cc once into a binary artifact that multiple translation units share. This is the recommended approach for production codebases as it minimizes compile times.

To use header-only mode without CMake targets, define the macro before including headers:

#define FMT_HEADER_ONLY
#include <fmt/format.h>

Usage Examples After Installation

Verify your fmtlib installation with a minimal program using include/fmt/core.h for basic printing:

#include <fmt/core.h>

int main() {
    fmt::print("Hello, {}!\n", "world");
    return 0;
}

For advanced string formatting with positional arguments, use include/fmt/format.h:

#include <fmt/format.h>

int main() {
    std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
    // s contains: "I'd rather be happy than right."
}

To format standard containers, include the ranges header located at include/fmt/ranges.h:

#include <vector>
#include <fmt/ranges.h>

int main() {
    std::vector<int> v = {1, 2, 3};
    fmt::print("{}\n", v);  // Output: [1, 2, 3]
}

For C++20 modules (requires CMake -DFMT_MODULE=ON):

import fmt;

int main() {
    fmt::print("Hello from a module!\n");
}

Summary

  • Install fmtlib using system package managers like apt, brew, vcpkg, or conda for immediate system-wide availability.
  • Use CMake FetchContent to automatically download fmtlib at configure time without external dependencies.
  • Build from source using the standard CMake workflow in the repository root when you need custom build configurations or specific compiler flags.
  • Link against fmt::fmt for production builds to leverage pre-compiled code from src/format.cc, or use fmt::fmt-header-only for simpler integration without library linking.
  • Include include/fmt/core.h for basic printing, include/fmt/format.h for full formatting capabilities, and include/fmt/ranges.h for container serialization support.

Frequently Asked Questions

What is the difference between fmt::fmt and fmt::fmt-header-only?

The fmt::fmt target links against the compiled library built from src/format.cc, which minimizes compile times by processing the implementation once. The fmt::fmt-header-only target includes the implementation directly from include/fmt/format-inl.h at every translation unit, eliminating the need for linking but increasing compilation overhead in larger projects.

Can I use fmtlib without CMake?

Yes. While CMake is the recommended build system, you can install fmtlib via package managers or copy the headers from include/fmt/ into your project. For true header-only usage, define FMT_HEADER_ONLY before including the headers and ensure include/fmt/format-inl.h is accessible to the compiler.

How do I enable C++20 modules support in fmtlib?

Enable the module target by configuring CMake with -DFMT_MODULE=ON, then link against fmt::fmt-module instead of fmt::fmt. This exposes the library as a C++20 module that you can import using import fmt; rather than traditional #include directives.

Where are the core fmtlib header files located?

The primary headers reside in include/fmt/ within the repository: core.h provides basic printing functions like fmt::print(), format.h contains the main fmt::format() API, and format-inl.h holds the header-only implementation details referenced by the compiled library.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →