CPM.cmake
CPM.cmake (CMake Package Manager) provides a lightweight abstraction over the standard CMake FetchContent module. It bridges the gap between manual vendoring (git submodules) and full-scale Package managers (vcpkg/Conan).
In the context of this course, CPM.cmake is the preferred distribution model for:
- Small-to-Medium Projects: Where the overhead of configuring vcpkg manifests is unjustified.
- Library Development: Where the library itself has dependencies and aims to be consumable by other CMake projects.
- Bleeding Edge Dependencies: When a library update is required that has not yet propagated to vcpkg or Conan registries.
Architectural Mechanism
Section titled “Architectural Mechanism”CPM.cmake operates strictly on the Source-Based Model.
- Resolution: It resolves dependencies via Git repositories (GitHub/GitLab) or URL archives.
- Retrieval: It checks a local cache directory. If the requested version is missing, it downloads the source.
- Integration: It invokes
add_subdirectory()on the downloaded source. - Graph Merger: The dependency”s CMake targets are added directly to the main project’s build graph.
The ABI Guarantee
Section titled “The ABI Guarantee”Because dependencies are compiled as sub-projects of the main build, they inherit the exact global Build configuration.
- Same Compiler (Clang/GCC/MSVC).
- Same Standard Flags (
-std=c++23). - Same Sanitizer Configuration (ASan/UBSan).
- Same Runtime Library (UCRT/glibc).
This architecture creates a mathematical guarantee of ABI compatibility, eliminating the “Mismatch Linker Error” class of bugs.
Proof of Reproducibility Guarantee
Section titled “Proof of Reproducibility Guarantee”Claim: Given identical CPMAddPackage calls with pinned GIT_TAG values and identical CMake Cache, any two machines produce bit-for-bit identical build outputs.
Proof sketch:
- Each
CPMAddPackage(NAME foo GIT_TAG abc123)resolves to a deterministic Git commit. A Git commit SHA uniquely identifies a tree of source files [Git internals]. - CPM computes a cache key as
NAME + version/tag. For a pinned tag, this key is invariant across machines. FetchContent_Declaredownloads the archive for the pinned commit. The archive contents are deterministic (Git packs are content-addressed).add_subdirectorycompiles the source with the global CMake configuration. If the global configuration is identical (same compiler, same flags, same toolchain), the compiler produces identical object files.- The linker combines these object files deterministically given the same input order.
The output is deterministic given the same pinned versions and build configuration.
Limitations: This proof assumes pinned tags (immutable references). If a branch name is used as GIT_TAGThe resolved commit may differ between machines at different times, breaking Reproducibility. Always pin to tags or commit SHAs.
Bootstrapping (Zero-Dependency Setup)
Section titled “Bootstrapping (Zero-Dependency Setup)”CPM.cmake is distributed as a single CMake script. The standard practice is to “bootstrap” it — Downloading it automatically during the CMake configure phase if it does not exist. This ensures the Project is self-contained.
Create cmake/CPM.cmake or include this block in your root CMakeLists.txt:
set(CPM_DOWNLOAD_VERSION 0.40.0)
if(CPM_SOURCE_CACHE) set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")elseif(DEFINED ENV{CPM_SOURCE_CACHE}) set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")else() set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")endif()
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") file(DOWNLOAD https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake ${CPM_DOWNLOAD_LOCATION} )endif()
include(${CPM_DOWNLOAD_LOCATION})Adding Packages
Section titled “Adding Packages”Dependencies are declared using CPMAddPackage. This function handles version checking, caching, And target creation.
Basic Syntax
Section titled “Basic Syntax”CPMAddPackage( NAME fmt GITHUB_REPOSITORY fmtlib/fmt GIT_TAG 10.1.1 OPTIONS "FMT_INSTALL OFF" # Do not install fmt when installing our project "FMT_TEST OFF" # Do not build fmt's tests)
# Link against the target defined by fmt's CMakeLists.txttarget_link_libraries(MyApplication PRIVATE fmt::fmt)Analysis
Section titled “Analysis”- NAME: The logical name used for caching.
- GITHUB_REPOSITORY: Shorthand for
https://github.com/user/repo. - GIT_TAG: A specific commit hash or tag. Best Practice: Always pin to a specific tag or hash for reproducibility. Prevent using
masterorHEAD. - OPTIONS: These are passed as CMake Cache Variables to the dependency. This is critical for controlling the build (e.g., disabling examples, docs, and tests of dependencies to save build time).
The CPM Source Cache (CPM_SOURCE_CACHE)
Section titled “The CPM Source Cache (CPM_SOURCE_CACHE)”By default, FetchContent and CPM download sources into the build/_deps directory. This has two Significant drawbacks:
- Redundant Downloads: Deleting the
buildfolder requires re-downloading all dependencies. - Disk Usage: Multiple projects using
fmtwill duplicate the source code.
To resolve this, configure the CPM Source Cache. This is an environment variable pointing to a Directory outside the build tree.
Configuration
Section titled “Configuration”Linux/macOS (.bashrc / .zshrc):
export CPM_SOURCE_CACHE=$HOME/.cache/CPMWindows (PowerShell Profile):
[System.Environment]::SetEnvironmentVariable("CPM_SOURCE_CACHE", "$env:LOCALAPPDATA\CPM", "User")CMake Behavior with Cache:
- CMake checks
$CPM_SOURCE_CACHE/fmt/10.1.1. - If found, it uses
add_subdirectorydirectly from that path. - If not found, it downloads to that path, ensuring future builds (even of different projects) reuse the source.
Package Configuration Pattern
Section titled “Package Configuration Pattern”To maintain a clean root CMakeLists.txtAbstract dependency logic into a dedicated module.
File Structure:
Project/ CMakeLists.txt cmake/ dependencies.cmake src/cmake/dependencies.cmake:
# Centralized dependency declarationCPMAddPackage( NAME nlohmann_json GITHUB_REPOSITORY nlohmann/json VERSION 3.11.2)
CPMAddPackage( NAME spdlog GITHUB_REPOSITORY gabime/spdlog VERSION 1.12.0 OPTIONS "SPDLOG_BUILD_EXAMPLE OFF")Root CMakeLists.txt:
cmake_minimum_required(VERSION 3.25)project(App)
include(cmake/CPM.cmake) # Bootstrapinclude(cmake/dependencies.cmake) # Load Libs
add_executable(App main.cpp)target_link_libraries(App PRIVATE nlohmann_json::nlohmann_json spdlog::spdlog)Local Overrides
Section titled “Local Overrides”A frequent requirement in systems programming is debugging a library within the context of the Application. CPM allows overriding a dependency with a local path using a CMake CLI flag, bypassing The network fetch.
Scenario: Debugging spdlog inside App.
cmake -S . -B build -DCPM_spdlog_SOURCE=/home/user/workspace/spdlog-forkWhen this flag is detected, CPM ignores the GITHUB_REPOSITORY argument and calls add_subdirectory(/home/user/workspace/spdlog-fork).
This mechanism is invaluable for debugging: you can modify the dependency’s source code in-place, Rebuild the application, and test fixes without modifying the project’s dependency declarations.
CPM.cmake Internals: How It Works
Section titled “CPM.cmake Internals: How It Works”How CPMAddPackage Works
Section titled “How CPMAddPackage Works”CPM.cmake is a single-file CMake script (approximately 2000 lines) that wraps FetchContent. When CPMAddPackage is called, it performs the following steps:
- Parse arguments: Extract
NAME``GITHUB_REPOSITORY``GIT_TAG``VERSION``OPTIONSEtc. - Compute cache key: Generate a deterministic key from
NAME+ version/tag. IfVERSIONis specified but notGIT_TAGCPM tries common tag prefixes (v``VNo prefix) to map the version to a Git tag. - Check local cache: Look in
CPM_SOURCE_CACHE/<name>/<version>and in${CMAKE_BINARY_DIR}/_deps/<name>-<hash>/. - Download if missing: Use
FetchContent_Declare+FetchContent_Populateto download the source from the Git repository or URL. - Set CMake options: Apply
OPTIONSas-D<OPTION>cache variables to the dependency’s CMake configuration. - Integrate: Call
add_subdirectory()on the fetched source, adding all targets to the main build graph. - Return target names: Set
<name>_ADDED``<name>_SOURCE_DIRAnd<name>_BINARY_DIRvariables for the caller.
Lock Mechanism
Section titled “Lock Mechanism”CPM does not have a formal lockfile like vcpkg’s vcpkg.json baseline or Conan’s conan.lock. Instead, it relies on pinned tags in the source code as the lock mechanism. The GIT_TAG field In each CPMAddPackage call serves as the de facto lock.
This is weaker than a dedicated lockfile because:
- There is no automated verification that a tag has not been force-pushed (deleted and recreated).
- There is no mechanism to detect that a dependency has added new transitive dependencies.
- There is no tool to audit whether all dependencies are pinned.
Mitigation: Use commit SHAs instead of tags for critical dependencies, and use CI to verify that CPM_SOURCE_CACHE is populated from the expected versions.
Offline Mode
Section titled “Offline Mode”CPM supports offline builds through two mechanisms:
- Pre-populated cache: If
CPM_SOURCE_CACHEcontains all dependencies, CPM uses them without network access. This is the recommended approach for CI and air-gapped environments. FETCHCONTENT_FULLY_DISCONNECTED: CMake 3.28+ supports this variable. When set toONFetchContentskips all downloads. If a dependency is not in the cache, CMake fails with an error.
# Offline CI buildexport CPM_SOURCE_CACHE=/mnt/cached-depscmake -S . -B build -DFETCHCONTENT_FULLY_DISCONNECTED=ONcmake --build buildLimitations
Section titled “Limitations”While efficient for small-to-medium graphs, CPM scales poorly when:
- Diamond Dependencies Occur: If Lib A wants
fmt 9.0and Lib B wantsfmt 10.0CPM attempts to enforce a single version ( the first one defined). Manual intervention viaCPMAddPackageoverrides is required to resolve the conflict via SAT solving logic manually. - Build Times Explode: Since every dependency is built from source, a clean build of a project with 50 dependencies may take an unacceptable amount of time. (Mitigation: Use
ccache.) - Non-CMake Projects: CPM relies on the dependency having a
CMakeLists.txt. For libraries using only Makefiles or premake, CPM cannot integrate them into the build graph.
The Diamond Dependency Problem
Section titled “The Diamond Dependency Problem”Consider the following dependency graph:
my-app +-- lib-a | +-- fmt 10.1.0 +-- lib-b +-- fmt 9.0.0CPM processes CPMAddPackage calls in order. If lib-a declares fmt 10.1.0 first, CPM adds it to The build graph. When lib-b subsequently declares fmt 9.0.0CPM detects the conflict and issues A warning but does not automatically resolve it. The first version wins.
Resolution strategies:
- Manually pin a compatible version: Declare
fmt 10.1.0at the project root before includinglib-aandlib-bSo both subdirectories see the same version. - Use a CPM override variable:
CPM_fmt_VERSION=10.1.0overrides allfmtversion requests. - Migrate to Conan/vcpkg: These tools have SAT-based solvers that can find a compatible version automatically.
How CPM Downloads Packages at Configure Time
Section titled “How CPM Downloads Packages at Configure Time”CPM operates entirely within CMake’s configure phase. When CPMAddPackage is called, CPM performs The following steps:
Step-by-Step Download Process
Section titled “Step-by-Step Download Process”- Cache Check: CPM computes a cache key from the package
NAMEand version/tag. It checks if the source already exists inCPM_SOURCE_CACHEor_deps. - Network Fetch: If the source is not cached, CPM uses CMake’s
FetchContent_Declareto download from the specified URL or Git repository. - Version Validation: For Git-based packages, CPM checks out the specified
GIT_TAG(tag, branch, or commit SHA). For URL-based packages, it extracts the archive. add_subdirectory: CPM callsadd_subdirectoryon the fetched source, integrating the dependency’s CMake targets into the main build graph.
# What CPMAddPackage does internally (simplified):FetchContent_Declare(fmt URL https://github.com/fmtlib/fmt/archive/refs/tags/10.1.1.tar.gz)FetchContent_MakeAvailable(fmt)Configure-Time Only
Section titled “Configure-Time Only”Because CPM runs at configure time, it has no concept of “build time” package resolution. All Packages are resolved before the first compilation command. This means:
- Adding a new package requires re-running
cmake -S . -B build. - Network failures at configure time block the entire build.
- The configure step can be slow for projects with many dependencies (network latency + CMake parsing for each dependency).
Version Pinning and Branch/Tag Support
Section titled “Version Pinning and Branch/Tag Support”Git Tag (Recommended)
Section titled “Git Tag (Recommended)”CPMAddPackage( NAME fmt GITHUB_REPOSITORY fmtlib/fmt GIT_TAG 10.1.1 # A release tag -- immutable and reproducible)Tags are immutable named references to specific commits. Pinning to a tag guarantees that every Developer gets the exact same source code.
Commit SHA (Most Reproducible)
Section titled “Commit SHA (Most Reproducible)”CPMAddPackage( NAME fmt GITHUB_REPOSITORY fmtlib/fmt GIT_TAG a1b2c3d4e5f6789012345678abcdef12 # Full SHA-1 hash)Commit SHAs are the most precise pinning mechanism. Even if the tag is moved (force-pushed), the SHA Remains stable.
Branch (Not Recommended for Production)
Section titled “Branch (Not Recommended for Production)”CPMAddPackage( NAME fmt GITHUB_REPOSITORY fmtlib/fmt GIT_TAG main # Floating reference -- changes over time)Using a branch name means the resolved commit changes every time the branch is updated. This breaks Reproducibility. Use branches only for development/testing.
Semantic Versioning (via CPM)
Section titled “Semantic Versioning (via CPM)”CPM supports VERSION as a convenience that maps to a Git tag:
CPMAddPackage( NAME fmt GITHUB_REPOSITORY fmtlib/fmt VERSION 10.1.1 # CPM translates this to GIT_TAG v10.1.1)CPM attempts common tag prefixes (v``VOr no prefix) when resolving versions.
CPMAddPackage Options Reference
Section titled “CPMAddPackage Options Reference”The full set of options for CPMAddPackage:
CPMAddPackage( NAME spdlog # Logical name (required) VERSION 1.12.0 # Semantic version (optional) GIT_TAG v1.12.0 # Git tag/branch/SHA (takes precedence over VERSION) GITHUB_REPOSITORY gabime/spdlog # Shorthand for git@github.com:gabime/spdlog.git GITLAB_REPOSITORY group/project # Shorthand for GitLab GIT_REPOSITORY https://... # Full Git URL (lowest priority) URL https://...tar.gz # Direct archive URL URL_HASH SHA256=abc123... # Integrity check for URL downloads SOURCE_DIR ${CMAKE_BINARY_DIR}/spdlog-src # Custom source directory DOWNLOAD_ONLY TRUE # Fetch source but do not add_subdirectory EXCLUDE_FROM_ALL TRUE # Exclude from 'all' target OPTIONS "SPDLOG_BUILD_EXAMPLE OFF" "SPDLOG_FMT_EXTERNAL ON")Key Options Explained
Section titled “Key Options Explained”DOWNLOAD_ONLY: Fetches the source but does not call add_subdirectory. Useful when the Dependency is not a CMake project but you need the source files available:
CPMAddPackage( NAME googletest GITHUB_REPOSITORY google/googletest GIT_TAG v1.14.0 DOWNLOAD_ONLY TRUE)
# Manually add subdirectory with custom optionsadd_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})URL + URL_HASH: For packages that do not have a Git repository, or when you want to avoid Git overhead:
CPMAddPackage( NAME tinyformat URL https://raw.githubusercontent.com/c42f/tinyformat/master/tinyformat.h DOWNLOAD_ONLY TRUE)EXCLUDE_FROM_ALL: Prevents the dependency from being built as part of cmake --build build (the all target). The dependency is only built when a target that depends on it is built. This is Useful for test-only dependencies.
CPM Source Cache Internals
Section titled “CPM Source Cache Internals”The CPM_SOURCE_CACHE directory uses a predictable structure based on the package name and version:
~/.cache/CPM/ fmt/ 10.1.1/ # Source for fmt 10.1.1 include/ src/ CMakeLists.txt 10.2.0/ # Source for fmt 10.2.0 ... spdlog/ 1.12.0/ ... cpm/ CPM_0.40.0.cmake # CPM itself is cached hereCache Sharing Across Projects
Section titled “Cache Sharing Across Projects”When CPM_SOURCE_CACHE is set, all CPM-based projects on the machine share the same source cache. This means:
- Project A downloads
fmt 10.1.1on the first build. - Project B uses
fmt 10.1.1and finds it already in the cache (instant). - No redundant downloads, no wasted disk space.
Fallback Behavior
Section titled “Fallback Behavior”If CPM_SOURCE_CACHE is not set and the source is not in _depsCPM downloads to ${CMAKE_BINARY_DIR}/_deps/<name>-<hash>/. This directory is inside the build tree and is deleted When the build directory is cleaned.
Cache Management
Section titled “Cache Management”# Show the size of the CPM cachedu -sh ~/.cache/CPM
# Remove a specific version to force re-downloadrm -rf ~/.cache/CPM/fmt/10.1.1
# Clear the entire cacherm -rf ~/.cache/CPMComparison with vcpkg and Conan
Section titled “Comparison with vcpkg and Conan”| Feature | CPM.cmake | vcpkg | Conan 2.x |
|---|---|---|---|
| Setup complexity | Single file include | Clone + bootstrap | pip install + profile config |
| Package source | Any Git repo or URL | vcpkg registry (ports) | ConanCenter + custom remotes |
| Binary caching | Not supported | NuGet / HTTP / files | Built-in remote support |
| Version resolution | First-wins (no SAT) | Baseline + constraints | SAT solver (libsolv) |
| Transitive deps | Via add_subdirectory | Managed by vcpkg | Managed by Conan |
| Cross-compilation | Inherits host config | Triplets | Profiles |
| IDE support | Native (CMake targets) | Good (toolchain file) | Good (generators) |
| Lock mechanism | Pinned tags (in source) | vcpkg.json baseline | conan.lock file |
| Offline builds | Pre-populated cache | Binary cache + ports | Pre-populated cache |
| Best for | Small-to-medium projects | Any size, teams | Large teams, binary distro |
When to Prefer CPM
Section titled “When to Prefer CPM”- Small projects with fewer than 10 dependencies: The simplicity of a single
dependencies.cmakefile outweighs the benefits of a full package manager. - Library development: When your library is consumed by other CMake projects, CPM ensures zero external tooling requirements. The consumer just runs
cmake. - Bleeding-edge or unreleased dependencies: When you need a commit from
mainthat has not been published to any registry. - Monorepo subprojects: CPM can reference other directories in the same repository using
SOURCE_DIR.
When to Prefer vcpkg
Section titled “When to Prefer vcpkg”- Projects with more than 15 dependencies: The build time savings from binary caching become significant.
- Team development: Lockfile-equivalent (baseline) ensures all developers build against the same dependency versions.
- Cross-platform projects: Triplets provide consistent build configurations across platforms.
When to Prefer Conan
Section titled “When to Prefer Conan”- Large teams with binary distribution requirements: Conan’s binary-first model eliminates redundant compilation across CI agents and developer machines.
- Private package repositories: Conan’s remote architecture supports Artifactory, S3, and custom HTTP servers for proprietary libraries.
- Complex cross-compilation: Conan’s build/host profile separation provides explicit control over cross-compilation scenarios.
Common CPM Packages
Section titled “Common CPM Packages”Below is a reference list of commonly used C++ libraries and their CPM declarations:
# JSON parsingCPMAddPackage( NAME nlohmann_json GITHUB_REPOSITORY nlohmann/json VERSION 3.11.3)
# LoggingCPMAddPackage( NAME spdlog GITHUB_REPOSITORY gabime/spdlog VERSION 1.14.0)
# String formattingCPMAddPackage( NAME fmt GITHUB_REPOSITORY fmtlib/fmt VERSION 10.2.1)
# Unit testingCPMAddPackage( NAME googletest GITHUB_REPOSITORY google/googletest GIT_TAG v1.14.0 OPTIONS "gtest_force_shared_crt ON")
# Argument parsingCPMAddPackage( NAME cxxopts GITHUB_REPOSITORY jarro2783/cxxopts VERSION 3.1.1)
# Concurrent data structuresCPMAddPackage( NAME concurrentqueue GITHUB_REPOSITORY cameron314/concurrentqueue VERSION 1.0.4)
# HashingCPMAddPackage( NAME robin-hood-hashing GITHUB_REPOSITORY martinus/robin_hood_hashing VERSION 3.11.5)Common Pitfalls
Section titled “Common Pitfalls”add_subdirectoryconflicts: If two dependencies both define a target with the same name (e.g., both vendorfmt), CMake will fail with “add_library cannot create target ‘fmt’ because another target with the same name already exists.” UseEXCLUDE_FROM_ALLand manual integration, or ensure dependencies use namespaced targets (fmt::fmt).- CMake minimum version mismatch: A dependency may require
cmake_minimum_required(VERSION 3.28)while your project targets 3.20. CPM does not isolate CMake minimum version requirements. The highest minimum version across all dependencies wins. - Network failures in CI: CPM requires network access during the configure step. In air-gapped CI environments, pre-populate
CPM_SOURCE_CACHEor useFETCHCONTENT_FULLY_DISCONNECTED=ON(CMake 3.28+) to skip downloads. - No lockfile means no guaranteed reproducibility: Unlike vcpkg (baseline) or Conan (lockfile), CPM has no mechanism to guarantee that two machines resolve the same versions. Pin every dependency to a tag or SHA.
- Dependency builds with wrong flags: Because CPM uses
add_subdirectoryThe dependency’sCMakeLists.txtcan modify global CMake state (e.g.,add_compile_optionswithout target scope). This can inject unwanted flags into your build. Always review dependency CMakeLists for global state mutations. - Large monorepo clones: CPM clones the entire Git repository history by default (shallow clone depth is 1, but some repos have large single commits). For large dependencies like Boost, consider using
URLwith a release archive instead ofGITHUB_REPOSITORYto reduce download time.
CPM with ccache for Faster Rebuilds
Section titled “CPM with ccache for Faster Rebuilds”When dependencies are built from source on every clean build, build times can be significant. Using ccache (compiler cache) alongside CPM drastically reduces rebuild times by caching object files:
# Install ccachesudo apt install ccache
# Configure CMake to use ccachecmake -S . -B build \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccacheWith ccacheThe first build compiles all dependencies from source (normal time). Subsequent clean Builds reuse cached object files, reducing the build time from minutes to seconds for most Dependencies.
Measuring CPM Build Impact
Section titled “Measuring CPM Build Impact”# In CMakeLists.txt, time the configure and build phasesfunction(time_cpm_packages) message(STATUS "CPM dependency resolution started") # CPMAddPackage calls here... message(STATUS "CPM dependency resolution complete")endfunction()CPM and FetchContent: Key Differences
Section titled “CPM and FetchContent: Key Differences”CPM is built on top of CMake’s FetchContent module but adds several features:
| Feature | FetchContent | CPM.cmake |
|---|---|---|
| Package declaration | FetchContent_Declare | CPMAddPackage (single call) |
| Version-to-tag mapping | Manual | Automatic (v prefix, etc.) |
| Source cache | _deps/ directory only | CPM_SOURCE_CACHE (shared) |
| GitHub shorthand | None | GITHUB_REPOSITORY |
| GitLab shorthand | None | GITLAB_REPOSITORY |
| Options passthrough | Manual set before MakeAvailable | OPTIONS keyword |
| Offline mode | Manual | Cache-based |
| Download-only mode | Manual FetchContent_Populate | DOWNLOAD_ONLY keyword |
| Bootstrap | Requires pre-existing script | Self-bootstrapping via file(DOWNLOAD) |
CPM Version Compatibility
Section titled “CPM Version Compatibility”CPM.cmake versions follow semantic versioning. Key version milestones:
| Version | Feature |
|---|---|
| 0.38.x | Stable release, widely used |
| 0.39.x | Added FETCHCONTENT_SOURCE_DIR_* overrides |
| 0.40.x | Current stable, improved cache handling |
When pinning the CPM version in the bootstrap script, use a specific version rather than latest:
set(CPM_DOWNLOAD_VERSION 0.40.0)See Also
Section titled “See Also”- Dependency Resolution — Package manager taxonomy and version resolution
- vcpkg — Full-featured alternative for larger projects
- Conan — Binary-first package manager for teams
- Property Propagation — How
add_subdirectorymerges build properties - Binary Caching — Why CPM lacks binary caching and how to compensate
Summary
Section titled “Summary”This topic covers the essential concepts and techniques related to cpm.cmake, including key principles and practical applications.
Key concepts include:
- core concepts and definitions
- key principles and frameworks
- practical applications
- common techniques and methods
- evaluation and critical analysis
A thorough understanding of these concepts, combined with regular practice and review, is essential for mastery of this topic.
Worked Examples
Section titled “Worked Examples”Worked examples demonstrating the application of key concepts are covered in the detailed sub-pages linked above.