Guide
Fetch and link an external library with CMake FetchContent
Learn how to declare, download, and link an external CMake project using FetchContent, with steps for configuration, verification, and handling network or version issues.
Published by Tasadduq Burney
24 Jul 2025, 15:05 UTC
3 min129.9K views0

Desired outcome
You need an external library available as a CMake target during configure, without requiring a system install or a separate package step. FetchContent downloads, configures and builds the dependency inside the current build tree, then exposes it for target_link_libraries.
The useful takeaway is to declare the dependency once, make it available before any target that uses it, and let CMake cache the source so re‑configures are fast when the network is unavailable.
Prerequisites
- CMake 3.11 or newer.
- Write permission in the build directory.
- Network access for the initial fetch (or a local fallback).
- Understanding that FetchContent respects CMake policies; policy CMP0077 controls whether the host can override properties of an imported target from the fetched project.
Procedure
- In the top‑level CMakeLists.txt, set the minimum version and project name.
- Include the FetchContent module.
- Declare the external project. Example: fetching the fmt library from GitHub, pinning a specific tag.
- Optionally control where the source is cached.
- Make the content available; this runs its configure step.
- Add your executable and link against the fetched target. The target name follows the pattern :: (lowercase).
- Configure from a separate build directory.
- Build the project.
cmake_minimum_required(VERSION 3.11)
project(my_app)include(FetchContent)FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.2.1
)set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/deps" CACHE PATH "Base directory for FetchContent downloads")FetchContent_MakeAvailable(fmt)add_executable(app main.cpp)
target_link_libraries(app PRIVATE fmt::fmt)cmake -S . -B build -DCMAKE_BUILD_TYPE=Releasecmake --build buildExpected checks
- During cmake configuration, look for lines such as:
-- Downloading fmt from https://github.com/fmtlib/fmt.gitand-- Build files have been written to: .../_deps/fmt-src. - Verify that the source appears under the directory set by FETCHCONTENT_BASE_DIR (default
_depsinside the build tree). - After building, inspect the link step. On Linux, run
ldd build/appand confirm that libfmt.so appears. On Windows, check the linker command log for fmt.lib. - To confirm caching, delete the
builddirectory, disconnect network, and reruncmake -S . -B build. If the configuration succeeds without downloading, the source was retrieved from the cache.
Recovery options and limitations
- Network failure: Provide a local fallback by pre‑downloading the archive and pointing FetchContent to a file URL, e.g.
FetchContent_Declare(fmt URL file:///path/to/fmt-10.2.1.zip)or setFETCHCONTENT_SOURCE_DIR_fmtto an existing checkout. - Version mismatch: If the fetched project’s CMakeLists.txt requires a newer CMake version than the host, the configure step fails. Options are to raise the host’s
cmake_minimum_requiredor to patch the dependency. - Large repositories: Initial fetch can be slow and consume disk space. Use a shallow clone:
set(GIT_SHALLOW ON)beforeFetchContent_MakeAvailable, or prefer a binary package when available. - Double build risk: If the library also ships pre‑built binaries, FetchContent will still build from source. In that case, use the binary distribution via
find_packageinstead. - Resetting a bad fetch: Remove the build directory and the cached source under
FETCHCONTENT_BASE_DIR, then reconfigure.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.