How to Use spdlog with CMake: Integration Guide for Header-Only and Compiled Builds
Use add_subdirectory(path/to/spdlog) to create the spdlog::spdlog or spdlog::spdlog_header_only targets, then link them with target_link_libraries(your_target PRIVATE spdlog::spdlog).
The gabime/spdlog repository provides a comprehensive CMake build system that supports both header-only and compiled library configurations. Located at the root of the repository, the CMakeLists.txt file defines convenient import targets and cache options that control linking behavior, external dependencies, and C++ standard requirements. This flexibility allows you to integrate spdlog into existing CMake projects using either a bundled source subdirectory or as an installed system package.
CMake Build Options and Configuration
The top-level CMakeLists.txt exposes several boolean options that determine how the library is built and consumed. These options must be set before calling add_subdirectory(spdlog) to take effect.
Static vs. Shared Library Selection
By default, spdlog builds as a static library. To create a shared library instead, set SPDLOG_BUILD_SHARED to ON before including the subdirectory:
set(SPDLOG_BUILD_SHARED ON)
add_subdirectory(spdlog)
This option respects the standard CMake BUILD_SHARED_LIBS variable if SPDLOG_BUILD_SHARED is not explicitly defined.
Header-Only vs. Compiled Mode
The build system generates two distinct targets:
spdlog::spdlog– A compiled static or shared library containing the implementation objects.spdlog::spdlog_header_only– An INTERFACE target that adds include directories without compiling separate objects.
Link against spdlog::spdlog_header_only when you want zero compilation overhead and do not need to maintain a separate spdlog binary.
External fmt Library Support
By default, spdlog bundles its own fmt library. To link against a system-installed version, enable one of these options before add_subdirectory:
SPDLOG_FMT_EXTERNAL– Links againstfmt::fmt(compiled).SPDLOG_FMT_EXTERNAL_HO– Links againstfmt::fmt-header-only.
set(SPDLOG_FMT_EXTERNAL ON)
add_subdirectory(spdlog)
Linking spdlog Targets in Your Project
Both targets automatically propagate include directories (include/) and the thread library (Threads::Threads) to your project. Choose the appropriate target based on your deployment needs:
| Target | Library Type | Use Case |
|---|---|---|
| spdlog::spdlog | STATIC or SHARED | When you want faster compile times and a separate library file |
| spdlog::spdlog_header_only | INTERFACE (header-only) | When you want simple integration without extra build artifacts |
Both targets automatically handle the required include directories and threading support.
Step-by-Step Integration Examples
Compiled Static Library Setup
The most common approach bundles spdlog as a compiled static dependency:
cmake_minimum_required(VERSION 3.10)
project(my_app LANGUAGES CXX)
# Build spdlog as a static library (default)
add_subdirectory(spdlog)
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE spdlog::spdlog)
Header-Only with External fmt
For projects that already use the {fmt} library, avoid duplication by using the header-only spdlog target with external fmt:
cmake_minimum_required(VERSION 3.10)
project(my_app LANGUAGES CXX)
set(SPDLOG_FMT_EXTERNAL_HO ON)
add_subdirectory(spdlog)
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE spdlog::spdlog_header_only)
Shared Library with C++20 std::format
To utilize C++20's std::format instead of the bundled fmt library, enable SPDLOG_USE_STD_FORMAT. This requires a C++20 compliant compiler:
cmake_minimum_required(VERSION 3.10)
project(my_app LANGUAGES CXX)
set(SPDLOG_BUILD_SHARED ON) # Produce libspdlog.so / spdlog.dll
set(SPDLOG_USE_STD_FORMAT ON) # Require C++20
add_subdirectory(spdlog)
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE spdlog::spdlog)
Key CMake Files in the Repository
Understanding the repository structure helps when debugging build issues or extending the configuration:
CMakeLists.txt(root) – Definesspdlogandspdlog_header_onlytargets, handlesSPDLOG_FMT_EXTERNALlogic, and sets installation rules.cmake/utils.cmake– Contains helper functions likespdlog_extract_version()and compiler warning configurations.example/CMakeLists.txt– Provides a minimal working example demonstrating both compiled and header-only linkage patterns.
Summary
- Include spdlog using
add_subdirectory(path/to/spdlog)to create the CMake targets. - Choose your target:
spdlog::spdlogfor compiled,spdlog::spdlog_header_onlyfor header-only. - Set options before inclusion:
SPDLOG_BUILD_SHARED,SPDLOG_FMT_EXTERNAL, andSPDLOG_USE_STD_FORMATmust be defined prior to theadd_subdirectorycall. - External dependencies are handled automatically; linking either target propagates include directories and threading libraries.
- Reference implementation details are found in
CMakeLists.txtat the repository root andcmake/utils.cmake.
Frequently Asked Questions
Should I use header-only or compiled spdlog?
Use spdlog::spdlog_header_only for quick prototyping or when you want to avoid maintaining a separate library file. Use spdlog::spdlog for larger projects where compile times matter, as the compiled library prevents recompiling spdlog's implementation with every translation unit that includes its headers.
How do I use spdlog with a system-installed fmt?
Set SPDLOG_FMT_EXTERNAL to ON before adding the subdirectory. This links spdlog::spdlog against fmt::fmt from your system package manager instead of the bundled copy. For header-only fmt usage, use SPDLOG_FMT_EXTERNAL_HO instead.
Can I build spdlog as a shared library?
Yes. Set SPDLOG_BUILD_SHARED to ON before calling add_subdirectory(spdlog). This generates libspdlog.so on Linux or spdlog.dll on Windows. When linking against the shared library, ensure your executable can locate the DLL at runtime.
What C++ standard does spdlog require?
By default, spdlog requires C++11. If you enable SPDLOG_USE_STD_FORMAT, the requirement increases to C++20 to support std::format. The CMake configuration automatically checks compiler capabilities and will fail configuration if the standard is insufficient.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →