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

> Discover fmtlib build system requirements. Learn about CMake versions, compiler needs for C++11, C++14, C++20, and std::format compatibility for your next C++ project.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: getting-started
- Published: 2026-09-06

---

**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`](https://github.com/fmtlib/fmt/blob/main/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`](https://github.com/fmtlib/fmt/blob/main/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`](https://github.com/fmtlib/fmt/blob/main/.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`](https://github.com/fmtlib/fmt/blob/main/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`](https://github.com/fmtlib/fmt/blob/main/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
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
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:

```cpp
#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:

```bash
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`](https://github.com/fmtlib/fmt/blob/main/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`](https://github.com/fmtlib/fmt/blob/main/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`](https://github.com/fmtlib/fmt/blob/main/.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.