# Available Build Flags for fmtlib: CMake Options for Header-Only, Modules, and Configuration

> Discover fmtlib's CMake options including header-only builds, C++20 modules, and platform APIs. Customize your fmtlib build with these essential flags.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: how-to-guide
- Published: 2026-09-11

---

**fmtlib exposes twelve primary build flags through CMake `option()` commands in [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt), including `FMT_HEADER_ONLY` (via the `fmt-header-only` interface target), `FMT_MODULE` for C++20 modules, and `FMT_OS` for platform-specific APIs.**

The fmt library uses CMake as its primary build system, exposing granular control over library features, testing, and installation through cache variables in the top-level [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt). These **fmtlib build flags** allow developers to toggle between header-only and compiled library modes, enable experimental C++20 modules, suppress OS-specific code, and enforce strict compiler warnings. Understanding these options ensures you compile only the functionality your project requires.

## Core Library Configuration

### Header-Only Mode (`fmt-header-only` target)

Unlike other options controlled by CMake variables, header-only mode is activated through the **interface target** `fmt-header-only`. When you link against `fmt::fmt-header-only` instead of `fmt::fmt`, the build system automatically defines `FMT_HEADER_ONLY=1` and enforces C++11 standards. This configuration eliminates the need to compile `src/format.cc` or link a static library, making fmt a pure header-only dependency.

```cmake

# CMakeLists.txt in your project

target_link_libraries(your_target PRIVATE fmt::fmt-header-only)

```

According to the source in [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt) (lines 54-58), this interface target sets the compile definition and ensures all headers compile as standalone translation units.

### C++20 Module Support (`FMT_MODULE`)

Set `-DFMT_MODULE=ON` to enable the experimental `fmt-module` library. This option defaults to the value of `${FMT_USE_MODULES}`, which CMake derives from your compiler's capabilities. When enabled and supported, the `add_module_library` helper constructs the module interface unit, allowing you to import fmt via `import fmt;` instead of including headers.

```bash
cmake -DFMT_MODULE=ON -DCMAKE_CXX_STANDARD=20 …

```

The generated target `fmt-module` requires compiler support for C++20 modules as detected by the build system.

### OS-Specific APIs (`FMT_OS`)

Defaults to `ON`. When disabled (`-DFMT_OS=OFF`), the build excludes `src/os.cc` from compilation and forces `FMT_OS=0` via compile definitions. This removes platform-specific functionality such as console color support, wide character output, and system error code handling. Disable this flag when targeting embedded systems or when you need a minimal footprint without OS dependencies.

## Testing, Documentation, and Quality Assurance

### Test Suite (`FMT_TEST`)

Controls whether CMake enters the `test/` subdirectory to build the comprehensive unit-test suite. The default value depends on whether fmt is the master project (top-level CMakeLists) or a subdirectory. Set `-DFMT_TEST=OFF` to skip building tests and reduce compile times.

```bash
cmake -DFMT_TEST=OFF …

```

### Documentation Generation (`FMT_DOC`)

When enabled (`ON` by default only when fmt is the master project), this option generates the `doc` target using Doxygen and MkDocs. The build will fail if these tools are missing, so disable this flag (`-DFMT_DOC=OFF`) for faster builds when you don't need API documentation.

### Fuzzing Targets (`FMT_FUZZ`)

Defaults to `OFF`. Enabling this builds the fuzzing harness located in `test/fuzzing/` and adds the `FMT_FUZZ` compile definition. This is typically used for security research and continuous integration testing rather than production builds.

### CUDA Tests (`FMT_CUDA_TEST`)

Controls the inclusion of CUDA-specific test targets. Defaults to `OFF` and requires a CUDA toolchain.

## Compiler Configuration and Warnings

### Pedantic Warnings (`FMT_PEDANTIC`)

Enables strict warning flags including `-Wall -Wextra -pedantic` on GCC and Clang, or `/W4` on MSVC. This flag defaults to `OFF` but is recommended for development to catch potential issues early.

### Warnings as Errors (`FMT_WERROR`)

Treats all compiler warnings as errors by injecting `-Werror` (GCC/Clang) or `/WX` (MSVC). Use this flag in CI pipelines to enforce code quality and prevent regressions.

### Unicode Support (`FMT_UNICODE`)

Defaults to `ON`. On MSVC, this adds the `/utf-8` compiler flag to ensure proper UTF-8 source and execution character sets. For GCC and Clang, Unicode support is always enabled regardless of this flag.

### System Headers (`FMT_SYSTEM_HEADERS`)

When set to `ON`, this marks fmt headers as system headers during installation using the `SYSTEM` attribute. This prevents compiler warnings from fmt headers appearing in downstream projects that include them.

## Installation Controls

### Install Rules (`FMT_INSTALL`)

Controls whether CMake generates install rules for headers, libraries, and CMake config files. Defaults based on master project status. Set `-DFMT_INSTALL=OFF` when embedding fmt as a subdirectory in a larger project to prevent pollution of your install prefix.

## Common Build Configurations

### Building a Static Library (Default)

```bash
git clone https://github.com/fmtlib/fmt.git
cd fmt
cmake -DCMAKE_BUILD_TYPE=Release -DFMT_TEST=OFF -DFMT_DOC=OFF .
cmake --build . --parallel

```

This produces `libfmt.a` (Linux/macOS) or `fmt.lib` (Windows) in the build directory.

### Header-Only Integration

```bash
cmake -DCMAKE_BUILD_TYPE=Release -DFMT_TEST=OFF -DFMT_DOC=OFF .
cmake --build .

```

Then link the interface target in your project:

```cmake
target_link_libraries(myapp PRIVATE fmt::fmt-header-only)

```

No library file is produced; all code resides in headers checked by [`include/fmt/core.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/core.h).

### Minimal Embedded Build (No OS, No Tests)

```bash
cmake -DCMAKE_BUILD_TYPE=MinSizeRel \
      -DFMT_OS=OFF \
      -DFMT_TEST=OFF \
      -DFMT_DOC=OFF \
      -DFMT_INSTALL=OFF \
      .
cmake --build . --parallel

```

This configuration excludes `src/os.cc` and produces a minimal static library suitable for embedded targets.

### Development Build with Strict Warnings

```bash
cmake -DCMAKE_BUILD_TYPE=Debug \
      -DFMT_PEDANTIC=ON \
      -DFMT_WERROR=ON \
      -DFMT_TEST=ON \
      .
cmake --build . --parallel
ctest --output-on-failure

```

## Summary

- **fmtlib build flags** are standard CMake `option()` variables defined in the root [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt), controlled via `-D` flags at configure time.
- **Header-only mode** uses the `fmt-header-only` interface target rather than a CMake variable, automatically defining `FMT_HEADER_ONLY=1`.
- **OS features** can be stripped by setting `-DFMT_OS=OFF`, which excludes `src/os.cc` and defines `FMT_OS=0`.
- **C++20 modules** are available via `-DFMT_MODULE=ON` when compiler support is detected.
- **Quality flags** (`FMT_PEDANTIC`, `FMT_WERROR`) inject strict compiler warnings and treat them as errors.
- **Auxiliary options** control test building (`FMT_TEST`), documentation (`FMT_DOC`), fuzzing (`FMT_FUZZ`), and installation (`FMT_INSTALL`).

## Frequently Asked Questions

### How do I enable header-only mode in fmtlib?

Header-only mode is enabled by linking against the `fmt::fmt-header-only` target instead of `fmt::fmt`. This interface target, defined in [`CMakeLists.txt`](https://github.com/fmtlib/fmt/blob/main/CMakeLists.txt), automatically sets `FMT_HEADER_ONLY=1` and enforces C++11. No separate CMake cache variable controls this; simply avoid building the static library target and use the interface in your `target_link_libraries()` call.

### What does the `FMT_OS` flag control?

`FMT_OS` (default `ON`) determines whether fmt includes OS-specific APIs from `src/os.cc`. When disabled, the build excludes this source file and defines `FMT_OS=0`, removing support for colored console output, wide characters, and system error formatting. Use this for embedded systems or when you need a minimal library without platform dependencies.

### How do I build fmtlib with C++20 module support?

Pass `-DFMT_MODULE=ON` to CMake when configuring with a C++20-capable compiler. The build system checks for module support via `FMT_USE_MODULES` and attempts to build the `fmt-module` target using the `add_module_library` helper. You must also set `CMAKE_CXX_STANDARD` to 20 or higher. If the compiler lacks module support, CMake will skip building the module library.

### Can I disable tests and documentation to speed up the build?

Yes. Set `-DFMT_TEST=OFF` and `-DFMT_DOC=OFF` to skip building the unit tests (which requires building `test/header-only-test.cc` and other test files) and documentation (which requires Doxygen and MkDocs). These default to `OFF` when fmt is included as a subdirectory, but default to `ON` when fmt is the top-level project.