Integrating yaml-cpp with CMake using FetchContent: A Complete Guide
You can integrate yaml-cpp into your CMake project by using FetchContent_Declare to download the source from the jbeder/yaml-cpp repository, invoking FetchContent_MakeAvailable to configure the build, and linking against the exported yaml-cpp::yaml-cpp target.
The jbeder/yaml-cpp library provides a robust, CMake-based build system that makes it ideal for modern C++ projects requiring YAML parsing capabilities. By leveraging CMake's FetchContent module, you can embed yaml-cpp directly from its GitHub repository without requiring system-wide installations or manual dependency management. This approach ensures reproducible builds across development environments while maintaining access to the library's full configuration options.
How FetchContent Integrates with yaml-cpp
yaml-cpp is architected specifically to support seamless integration via CMake's FetchContent. The root CMakeLists.txt defines the project as a self-contained CMake package that exports a modern, namespaced target.
The Library Target and Alias
In CMakeLists.txt (lines 69-71), the core library is created using add_library(yaml-cpp …) and immediately exported as an ALIAS target yaml-cpp::yaml-cpp. This alias is the canonical interface for consuming the library, regardless of whether you are building it as a static or shared library. The target encapsulates both the compiled binary and the necessary header include paths, which are configured in lines 83-88 using target_include_directories.
Package Configuration Template
The repository includes yaml‑cpp-config.cmake.in, which serves as a template for generating the CMake package configuration file. When processed by configure_package_config_file, this template creates yaml‑cpp-config.cmake in the build directory, defining the imported target yaml‑cpp::yaml-cpp for downstream projects. This ensures that the same target name works whether you use FetchContent or a system-installed copy via find_package.
Step-by-Step FetchContent Integration
Declaring the Dependency
Use FetchContent_Declare to specify the Git repository and a specific tag or commit hash. This declaration should appear in your project's main CMakeLists.txt before any targets that depend on yaml-cpp.
include(FetchContent)
FetchContent_Declare(
yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
GIT_TAG yaml-cpp-0.9.0 # or any valid tag/commit
)
Configuring Build Options
Before calling FetchContent_MakeAvailable, you can set cache variables to control the build configuration. The yaml-cpp project respects several options, including YAML_BUILD_SHARED_LIBS to force static or shared linkage, and YAML_CPP_BUILD_CONTRIB to enable optional utility components.
# Optional: force a static build instead of default
set(YAML_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
# Optional: enable contrib sources (e.g., emit utilities)
set(YAML_CPP_BUILD_CONTRIB ON CACHE BOOL "" FORCE)
Making the Content Available and Linking
The FetchContent_MakeAvailable command downloads the source if necessary, then calls add_subdirectory to process yaml-cpp's CMakeLists.txt. After this call, the yaml-cpp::yaml-cpp target is available in the current scope.
FetchContent_MakeAvailable(yaml-cpp)
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE yaml-cpp::yaml-cpp)
Complete Integration Examples
Example 1: Basic Static Library Usage
This configuration fetches yaml-cpp version 0.9.0 and forces a static library build, ensuring the resulting binary has no external yaml-cpp dependencies.
include(FetchContent)
FetchContent_Declare(
yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
GIT_TAG yaml-cpp-0.9.0
)
set(YAML_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(yaml-cpp)
add_executable(my_app src/main.cpp)
target_link_libraries(my_app PRIVATE yaml-cpp::yaml-cpp)
Example 2: Shared Library with Contrib Components
When building shared libraries or when you need the optional util components (like command-line parsing tools), enable the contrib option before making the content available.
include(FetchContent)
FetchContent_Declare(
yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
GIT_TAG master
)
set(YAML_CPP_BUILD_CONTRIB ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(yaml-cpp)
add_library(my_lib src/lib.cpp)
target_link_libraries(my_lib PUBLIC yaml-cpp::yaml-cpp)
Example 3: System Installation Fallback
If yaml-cpp is installed on the system via cmake --install, the same target interface works with find_package. The generated yaml‑cpp-targets.cmake (referenced from the config file at line 17) defines the imported target yaml‑cpp::yaml‑cpp, allowing seamless switching between FetchContent and system packages.
find_package(yaml-cpp REQUIRED)
add_executable(my_tool src/tool.cpp)
target_link_libraries(my_tool PRIVATE yaml-cpp::yaml-cpp)
Key Source Files and Configuration
Understanding the following files helps debug integration issues or customize the build:
CMakeLists.txt(root): Defines theyaml-cpplibrary target (lines 69-71), installation rules for headers (lines 83-88), and optional subdirectories forutil/andtest/components.yaml‑cpp-config.cmake.in: Template for the exported CMake package that downstream projects consume.include/: Contains public headers likeyaml.handnode.h, automatically added to the target's interface include directories.
Summary
- Target Name: Always link against
yaml-cpp::yaml-cpp, the ALIAS target exported by the project'sCMakeLists.txt. - FetchContent Workflow: Use
FetchContent_Declarewith the Git URL, set options likeYAML_BUILD_SHARED_LIBSbeforeFetchContent_MakeAvailable, then link the target. - Configuration Options: Control library type via
YAML_BUILD_SHARED_LIBSand enable extra tools viaYAML_CPP_BUILD_CONTRIB. - Portability: The same
yaml-cpp::yaml-cpptarget works for both FetchContent integration and system-wide installations viafind_package.
Frequently Asked Questions
How do I pin a specific version of yaml-cpp using FetchContent?
Specify the GIT_TAG parameter in FetchContent_Declare with a release tag (e.g., yaml-cpp-0.9.0), commit hash, or branch name. This ensures reproducible builds by locking the dependency to a known state of the jbeder/yaml-cpp repository.
Can I build yaml-cpp as a shared library with FetchContent?
Yes. Set YAML_BUILD_SHARED_LIBS to ON before calling FetchContent_MakeAvailable. This overrides the default static library setting in the project's CMakeLists.txt, creating a shared object instead.
What is the difference between yaml-cpp and yaml-cpp::yaml-cpp targets?
The yaml-cpp target is the internal library name created by add_library, while yaml-cpp::yaml-cpp is the ALIAS target exported for external use. You should always link against the namespaced yaml-cpp::yaml-cpp target to ensure compatibility with both FetchContent and installed package configurations.
How do I disable tests and utilities when fetching yaml-cpp?
By default, the test/ and util/ directories are added conditionally via add_subdirectory in the root CMakeLists.txt. These are typically disabled when yaml-cpp is built as a subdirectory (as with FetchContent), but you can explicitly ensure they are off by setting YAML_CPP_BUILD_TESTS and YAML_CPP_BUILD_TOOLS to OFF before fetching.
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 →