Build System Requirements for fmtlib: CMake, Compilers, and C++ Standards

To build fmtlib, you need CMake 3.12 or newer and a C++ compiler supporting at least C++11, though C++14 is required for most headers and C++20 for std::format compatibility.

The {fmt} library is a modern C++ formatting library hosted at fmtlib/fmt that uses CMake as its primary build system. Understanding the specific build system requirements ensures you can compile the library across Linux, macOS, and Windows without encountering configuration errors. This guide covers the exact versions, compiler support, and configuration options defined in the upstream source code.

CMake Version Requirements

The fmtlib project requires CMake 3.12 as the absolute minimum version. In CMakeLists.txt at lines 4-6, the build script explicitly checks the CMake version and aborts configuration if the installed version is too old.

For access to cutting-edge features like the experimental fmt-module target for C++20 modules, CMake 3.28 or newer is recommended. The top-level CMake script adapts its behavior based on the detected version, ensuring backward compatibility while enabling modern workflows when available.

C++ Language Standards

The core library maintains backward compatibility with C++11, but practical usage typically requires C++14 or later. According to the standard selection logic in CMakeLists.txt at lines 54-57, the configuration automatically selects the highest C++ standard your compiler supports, falling back to C++11 only when necessary.

Specific headers have different requirements:

  • <fmt/format.h> and common components require C++14
  • The optional std::format compatibility layer (via <fmt/std.h>) requires C++20

Supported Compilers

The fmtlib CI configuration in .github/workflows/linux.yml and related workflow files defines the officially supported compiler versions. These represent the minimum versions that receive automated testing:

  • GCC 7 or newer (full C++14 support; GCC 9+ recommended for C++17/20 features)
  • Clang 6 or newer (C++14 capable; Clang 10+ for modern standards)
  • MSVC 19.24 or newer (Visual Studio 2019 16.4), providing full C++14 support and partial C++17/20 features

Using compiler versions older than these will likely result in compilation failures, particularly when using advanced formatting features.

Platform Compatibility

The CMake configuration in CMakeLists.txt at lines 498-525 handles platform-specific requirements automatically. The library is portable across Linux, macOS, and Windows without requiring manual platform detection in your own build scripts.

On POSIX systems, the build system automatically links against pthread when necessary. On Windows, it correctly manages __declspec(dllexport)/__declspec(dllimport) decorations for shared library builds. These platform sections ensure that find_package(fmt) works identically across all supported operating systems.

Build Configuration Options

The project exposes several CMake options defined in CMakeLists.txt at lines 390-426 that control the build artifacts:

  • FMT_HEADER_ONLY: Skip library compilation and use header-only mode
  • FMT_INSTALL: Generate installation targets (default: ON)
  • FMT_DOC: Build documentation (requires additional dependencies)

By default, the configuration produces both shared and static library targets with installation rules enabled. You can toggle these options at configure time using standard CMake syntax: -DFMT_HEADER_ONLY=ON.

Practical Build Examples

Basic CMake Integration

To consume fmtlib after installation via make install:

cmake_minimum_required(VERSION 3.12)
project(my_app)

find_package(fmt REQUIRED)

add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE fmt::fmt)

Header-Only Configuration

To use fmtlib without compiling a separate library:

cmake_minimum_required(VERSION 3.12)
project(header_only_demo)

add_subdirectory(path/to/fmt)
add_executable(demo main.cpp)
target_link_libraries(demo PRIVATE fmt::fmt-header-only)

This sets FMT_HEADER_ONLY implicitly and avoids building .cpp files.

C++20 Module Support

For projects using C++20 with std::format compatibility:

#include <fmt/chrono.h>
#include <fmt/std.h>   // Provides std::format compatibility

int main() {
    std::string s = std::format("Answer: {}", 42);
    return 0;
}

Compile with C++20 enabled:

g++ -std=c++20 -I/path/to/fmt/include main.cpp -o demo

Note that the std::format compatibility layer requires both C++20 support in your compiler and the appropriate fmtlib headers.

Summary

  • CMake 3.12+ is mandatory, with 3.28+ recommended for module support (verified in CMakeLists.txt lines 4-6)
  • C++11 is the minimum language level, but C++14 is required for <fmt/format.h> and C++20 for std::format compatibility
  • Officially tested compilers include GCC ≥7, Clang ≥6, and MSVC ≥19.24 (VS 2019 16.4)
  • The build system automatically handles Linux, macOS, and Windows platform differences
  • Key CMake options include FMT_HEADER_ONLY, FMT_INSTALL, and FMT_DOC (defined at lines 390-426)

Frequently Asked Questions

What is the minimum CMake version for fmtlib?

You need CMake 3.12 minimum. The build script in CMakeLists.txt explicitly enforces this at lines 4-6 and will terminate with an error if you attempt to configure with an older version. For C++20 modules support, upgrade to CMake 3.28 or newer.

Can I use fmtlib with C++11 only?

Technically yes, but with significant limitations. While the core library supports C++11, most practical usage including <fmt/format.h> requires C++14. The CMake configuration in lines 54-57 automatically detects and uses the highest available standard, so you only need to ensure your compiler supports at least C++11.

Which compiler versions are tested in CI?

The .github/workflows/linux.yml file defines the official test matrix: GCC 7+, Clang 6+, and MSVC 19.24+ (Visual Studio 2019 16.4). These versions guarantee full C++14 support. The CI system validates every commit against these compiler versions across Linux, macOS, and Windows runners.

How do I build fmtlib as a header-only library?

Set the FMT_HEADER_ONLY CMake option to ON when configuring, or simply link against the fmt::fmt-header-only target instead of fmt::fmt. This approach skips compilation of the library's .cpp files and includes everything through headers, which is useful for reducing build complexity in small projects.

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 →