CPM.cmake轻量级包管理器

CPM.cmake 是一个轻量级、现代化的 CMake 包管理器,它基于 CMake 的 FetchContent 模块构建,允许你在 CMake 项目中以声明式方式引入第三方依赖。与传统的包管理器(如 vcpkg、Conan)不同,CPM 不需要额外安装工具,只需在 CMakeLists.txt 中包含一个脚本即可使用。


1. 什么是 CPM.cmake?

  • 全称:CMake Package Manager
  • 特点
    • 无需外部依赖(仅需 CMake ≥ 3.14)
    • 自动下载、配置、构建和链接依赖
    • 支持 Git、URL、本地路径等多种来源
    • 依赖可被多个项目共享(通过缓存)
    • 与 CMake 原生集成,语法简洁

GitHub 仓库:https://github.com/cpm-cmake/CPM.cmake


2. 快速开始

2.1 安装 CPM.cmake

在你的项目根目录的 CMakeLists.txt 文件开头添加以下代码:

cmake 复制代码
# 下载并包含 CPM.cmake
include(FetchContent)
FetchContent_Declare(
  CPM
  GIT_REPOSITORY https://github.com/cpm-cmake/CPM.cmake.git
  GIT_TAG        v1.10.0  # 检查最新版本:https://github.com/cpm-cmake/CPM.cmake/releases
)
FetchContent_MakeAvailable(CPM)

✅ 推荐:将 CPM.cmake下载到项目中的cmake/CPM.cmake 并通过 include(cmake/CPM.cmake) 引入,便于版本锁定和离线使用。https://github.com/cpm-cmake/CPM.cmake/releases/


2.2 添加第一个依赖

例如,添加 fmt 库:

cmake 复制代码
CPMAddPackage("gh:fmtlib/fmt@10.2.1")

这行代码会:

  • 从 GitHub 克隆 fmtlib/fmt 仓库
  • 切换到 10.2.1 标签
  • 自动调用 add_subdirectory() 将其加入构建系统

之后你就可以直接链接:

cmake 复制代码
target_link_libraries(your_target PRIVATE fmt::fmt)

3. CPMAddPackage 语法详解

CPMAddPackage() 支持多种参数形式:

3.1 简写形式(推荐)

cmake 复制代码
CPMAddPackage("gh:user/repo@version")      # GitHub
CPMAddPackage("gl:user/repo@version")      # GitLab
CPMAddPackage("bb:user/repo@version")      # Bitbucket

示例:

cmake 复制代码
CPMAddPackage("gh:nlohmann/json@v3.11.2")

3.2 完整参数形式

cmake 复制代码
CPMAddPackage(
  NAME          your_dep_name       # 可选,默认为 repo 名
  GITHUB_REPOSITORY "user/repo"
  VERSION       "1.2.3"
  GIT_TAG       "v1.2.3"            # 优先于 VERSION
  OPTIONS       "OPTION1 ON" "OPTION2 OFF"
  EXCLUDE_FROM_ALL TRUE               # 不自动构建(仅配置)
)

3.3 从 URL 或本地路径添加

cmake 复制代码
CPMAddPackage(
  NAME mylib
  URL https://example.com/mylib.zip
  URL_HASH SHA256=abc123...
)

# 或本地路径(用于调试或私有库)
CPMAddPackage(
  NAME local_lib
  SOURCE_DIR "${CMAKE_SOURCE_DIR}/third_party/mylib"
)

4. 高级用法

4.1 条件性添加依赖(避免重复)

CPM 会自动检测是否已添加同名包,但你也可以显式检查:

cmake 复制代码
if(NOT TARGET nlohmann_json::nlohmann_json)
  CPMAddPackage("gh:nlohmann/json@v3.11.2")
endif()

4.2 传递 CMake 选项给依赖

有些库支持自定义构建选项(如 BUILD_SHARED_LIBS):

cmake 复制代码
CPMAddPackage(
  NAME fmt
  GITHUB_REPOSITORY fmtlib/fmt
  GIT_TAG 10.2.1
  OPTIONS
    "FMT_INSTALL OFF"
    "FMT_DOC OFF"
)

4.3 共享缓存(加速 CI 和多项目构建)

CPM 默认使用 CMake 的全局缓存目录(通常为 ~/.cache/CMake/CPM),多个项目会共享已下载的依赖,避免重复克隆。

可通过环境变量自定义缓存路径:

bash 复制代码
export CPM_SOURCE_CACHE=/path/to/shared/cache

5. 完整示例项目

目录结构:

复制代码
my_project/
├── CMakeLists.txt
├── main.cpp
└── cmake/
    └── CPM.cmake   # (可选)本地副本

CMakeLists.txt:

cmake 复制代码
cmake_minimum_required(VERSION 3.14)
project(MyApp LANGUAGES CXX)

# 引入 CPM
include(cmake/CPM.cmake)  # 或使用 FetchContent 方式在线获取

# 添加依赖
CPMAddPackage("gh:fmtlib/fmt@10.2.1")
CPMAddPackage("gh:gabime/spdlog@v1.13.0")

# 创建可执行文件
add_executable(app main.cpp)

# 链接依赖
target_link_libraries(app PRIVATE fmt::fmt spdlog::spdlog)
target_compile_features(app PRIVATE cxx_std_17)

main.cpp:

cpp 复制代码
#include <fmt/core.h>
#include <spdlog/spdlog.h>

int main() {
    fmt::print("Hello from fmt!\n");
    spdlog::info("Hello from spdlog!");
    return 0;
}

构建命令:

bash 复制代码
mkdir build && cd build
cmake ..
cmake --build .
./app

6. 最佳实践

  • 固定版本号:始终指定明确的 Git Tag 或 Commit,避免意外更新。
  • 使用简写语法gh:user/repo@tag 更简洁且不易出错。
  • 避免在函数/宏中调用 CPMAddPackage:可能导致作用域问题。
  • CI 中启用缓存 :设置 CPM_SOURCE_CACHE 加快构建速度。
  • 不要混合 CPM 与其他包管理器:可能引起冲突。

7. 常见问题

Q: CPM 和 vcpkg/Conan 有什么区别?

A: CPM 是"源码嵌入式"管理器,直接将依赖作为子项目编译;而 vcpkg/Conan 通常预编译二进制。CPM 更适合希望完全控制构建过程的项目。

Q: 如何离线使用?

A: 将 CPM.cmake 脚本和依赖源码缓存到本地,或使用 SOURCE_DIR 指向本地副本。

Q: 支持私有仓库吗?

A: 支持!只要 Git 可访问(如配置 SSH 密钥),即可使用完整 Git URL:

cmake 复制代码
CPMAddPackage(
  GIT_REPOSITORY git@github.com:your/private-repo.git
  GIT_TAG v1.0.0
)

8. 参考资料


📌 提示:截至 2026 年,CPM.cmake 已成为许多现代 C++ 项目的首选依赖管理方案,尤其适合中小型项目和快速原型开发。

相关推荐
故事还在继续吗3 小时前
C++20关键特性
开发语言·c++·c++20
青少儿编程课堂3 小时前
2026青少儿信息素养大赛备赛指南!Python/Scratch/C++备考要点
开发语言·c++·python
旖-旎3 小时前
深搜练习(电话号码字母组合)(3)
c++·算法·力扣·深度优先遍历
AIFarmer4 小时前
【无标题】
开发语言·c++·算法
John_ToDebug4 小时前
WebHostView 与 TabStrip 交互机制深度解析
c++·chrome·windows
南境十里·墨染春水5 小时前
C++笔记 STL——set
开发语言·c++·笔记
dgaf5 小时前
DX12 快速教程(17) —— 立体图标与合并渲染
c语言·c++·3d·图形渲染·d3d12
众少成多积小致巨5 小时前
Cmake 入门指南
cmake
charlie1145141918 小时前
通用GUI编程技术——图形渲染实战(三十八)——顶点缓冲与输入布局:GPU的第一个三角形
开发语言·c++·学习·图形渲染·win32
用户805533698038 小时前
现代Qt开发教程(新手篇)1.10——进程
c++·qt