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

fmtlib exposes twelve primary build flags through CMake option() commands in 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. 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.


# CMakeLists.txt in your project

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

According to the source in 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.

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.

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)

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

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

Then link the interface target in your project:

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.

Minimal Embedded Build (No OS, No Tests)

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

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, 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, 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.

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 →