1. vcpkg 使用
vcpkg 是微软开源的 C++ 包管理工具,目前已成为 C++ 生态中最流行的依赖管理方案之一。它与 CMake 的深度集成使得三方库管理变得简单可靠。
1.1 安装与基础使用
# 1. 克隆 vcpkg
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
# 2. 安装(Windows)
.\bootstrap-vcpkg.bat
# 2. 安装(Linux/macOS)
./bootstrap-vcpkg.sh
# 3. 安装依赖
# 单库安装
vcpkg install spdlog:x64-linux
# 多库同时安装
vcpkg install boost filesystem curl:x64-linux
# 4. 使用(CMake 集成)
# 在 CMakeLists.txt 中
find_package(fmt CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE fmt::fmt)
1.2 triplet 配置
vcpkg 使用 triplet 来定义目标平台和构建类型:
# 常用 triplets
# x86-windows - x86 Windows
# x64-windows - x64 Windows
# x64-windows-md - x64 Windows with MD runtime
# x64-linux - x64 Linux
# x64-osx - x64 macOS
# arm64-uwp - ARM64 UWP
# x64-linux-static - x64 Linux 静态链接
# 自定义 triplet 示例:
# vcpkg/triplets/x64-myconfig.cmake
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_BUILD_TYPE release)
1.3 manifest 模式(推荐)
vcpkg 2021.04 版本引入了 manifest 模式,允许在项目中声明依赖:
# vcpkg.json - 项目根目录
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"name": "my-awesome-project",
"version": "1.0.0",
"dependencies": [
"fmt",
"spdlog",
"boost-filesystem",
"boost-asio",
"nlohmann-json",
{
"name": "opencv",
"features": ["dnn", "png", "jpeg"]
}
],
"features": {
"gpu": {
"description": "Enable GPU support",
"dependencies": ["cuda", "cudnn"]
}
},
"overrides": [
{
"name": "openssl",
"version": "1.1.1t"
}
]
}
💡 manifest 模式的优势
- 依赖声明与项目源码在一起,版本可追溯
- 支持 feature 条件依赖
- 支持版本覆盖锁定
- 支持锁文件(vcpkg-lock.json)
2. Conanfile
2.1 Conan 基础
Conan 是另一个流行的 C++ 包管理器,与 vcpkg 相比更专注于企业场景:
# conanfile.txt 示例
[requires]
fmt/9.1.0
spdlog/1.12.0
boost/1.84.0
[generators]
cmake_find_package
CMakeToolchain
[options]
fmt:shared = False
boost/*:shared = False
[imports]
bin, *.dll -> ./bin
lib, *.lib -> ./lib
2.2 Conan vs vcpkg 对比
vcpkg 优势
- ✓ 与 CMake 原生集成
- ✓ 无需额外运行时
- ✓ Windows 一致体验
- ✓ 活跃的社区
Conan 优势
- ✓ 更成熟的企业特性
- ✓ ConanCenter 质量保证
- ✓ 更好的版本语义支持
- ✓ 完整的 CI/CD 集成
2.3 版本锁定
# vcpkg lock 文件(vckg.lock.json)
# 自动生成,记录精确版本
{
"version": 1,
"requirements": [
{
"name": "fmt",
"version": "10.2.1"
},
{
"name": "spdlog",
"version": "1.12.0"
}
],
"patches": []
}
# 强制使用锁文件版本
vcpkg install --x-experimental-lockfile
# 或者手动编辑 vcpkg.json overrides
3. CMake Presets
3.1 CMakePresets.json 基础
CMake 3.21+ 引入了 CMakePresets.json,使得构建配置可共享:
// CMakePresets.json
{
"version": 4,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21
},
"presets": [
{
"name": "release-linux",
"inherits": ["base"],
"binaryDir": "${sourceDir}/build/release-linux",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"ENABLE_TESTS": "ON",
"VCPKG_MANIFEST_MODE": "ON",
"VCPKG_TARGET_TRIPLET": "x64-linux"
}
},
{
"name": "debug-windows",
"inherits": ["base"],
"binaryDir": "${sourceDir}/build/debug-windows",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"VCPKG_TARGET_TRIPLET": "x64-windows"
}
}
]
}
3.2 CMakeUserPresets.json
用户可以通过 CMakeUserPresets.json 覆盖或添加个人配置:
// CMakeUserPresets.json(不提交到版本控制)
{
"version": 4,
"include": "../CMakePresets.json",
"presets": [
{
"name": "local-dev",
"inherits": ["release-linux"],
"cacheVariables": {
"CMAKE_PREFIX_PATH": "/home/dev/custom-libs"
}
}
]
}
3.3 与 vcpkg 集成
// 在 CMakeLists.txt 中启用 vcpkg
cmake_minimum_required(VERSION 3.21)
project(my_app)
// 方式1:使用 vcpkg toolchain(推荐)
set(VCPKG_MANIFEST_MODE ON)
set(VCPKG_TARGET_TRIPLET x64-linux)
include(${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
// 方式2:使用 vcpkg CMake Toolchain(更灵活)
# CMakePresets.json 中
{
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
4. 交叉编译
4.1 ARM 交叉编译
# vcpkg triplet for ARM64 Linux
# vcpkg/triplets/arm64-linux.cmake
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE static)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/toolchain-arm64.cmake)
# toolchain-arm64.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
# 使用
vcpkg install --triplet arm64-linux
cmake --preset=release-arm64
4.2 Windows 到 Linux 交叉编译
# Windows 上交叉编译 Linux
# 1. 安装 MinGW-w64 或 LLVM
# 2. 使用对应 triplet
vcpkg install --triplet=x64-linux
# CMakePresets.json
{
"name": "linux-from-windows",
"cacheVariables": {
"CMAKE_SYSTEM_NAME": "Linux",
"CMAKE_C_COMPILER": "x86_64-linux-gnu-gcc",
"CMAKE_CXX_COMPILER": "x86_64-linux-gnu-g++"
}
}
4.3 平台特定依赖
// 根据平台选择依赖
if (WIN32)
list(APPEND DEPS "windows-sdk")
find_package(windows-sdk CONFIG REQUIRED)
elseif (UNIX AND NOT APPLE)
list(APPEND DEPS "linux-headers")
elseif (APPLE)
list(APPEND DEPS "apple-framework")
endif()
5. CI/CD 集成
5.1 GitHub Actions 流水线
# .github/workflows/cmake.yml
name: CMake CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
strategy:
matrix:
config:
- {name: "Linux Release", os: ubuntu-latest, triplet: x64-linux, buildtype: Release}
- {name: "Windows Debug", os: windows-latest, triplet: x64-windows, buildtype: Debug}
- {name: "macOS", os: macos-latest, triplet: arm64-osx, buildtype: Release}
runs-on: ${{ matrix.config.os }}
steps:
- uses: actions/checkout@v3
- name: Setup vcpkg
uses: lukka/run-vcpkg@v11
with:
vcpkggitrepository: https://github.com/microsoft/vcpkg
vcpkgtriplet: ${{ matrix.config.triplet }}
vcpkginstalledpath: ${{ github.workspace }}/vcpkg_installed
- name: Configure CMake
run: |
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=${{ matrix.config.buildtype }} \
-DVCPKG_MANIFEST_MODE=ON \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Build
run: cmake --build build --parallel
- name: Test
run: ctest --output-on-failure -C ${{ matrix.config.buildtype }}
5.2 缓存优化
# GitHub Actions 缓存 vcpkg 编译结果
- name: Cache vcpkg
uses: actions/cache@v3
with:
path: |
${{ github.workspace }}/vcpkg_installed
~/.cache/vcpkg
key: vcpkg-${{ matrix.config.triplet }}-${{ hashFiles('vcpkg.json') }}
restore-keys: |
vcpkg-${{ matrix.config.triplet }}-
5.3 完整流水线检查表
# CI/CD 流水线检查表
## 构建矩阵
□ Linux (GCC + Clang)
□ Windows (MSVC)
□ macOS (Apple Clang)
□ Debug + Release 组合
□ 静态 + 动态链接(如需要)
## 依赖管理
□ vcpkg.json 提交到仓库
□ vcpkg-lock.json 提交(版本锁定)
□ overrides 配置审核
□ triplet 自定义配置
## 性能优化
□ ccache 启用
□ Unity Build(如支持)
□ 并行编译优化
□ 构建缓存(ccache 或 sccache)
## 质量门禁
□ 编译警告视为错误(-Werror)
□ Clang-Tidy 静态分析
□ CMake Format 检查
□ 依赖漏洞扫描
✅ 快速决策
- ✓ 新项目使用 vcpkg + CMake Presets
- ✓ 跨平台项目使用 manifest 模式
- ✓ 企业项目考虑 Conan(更成熟的生态)
- ✓ 所有项目都应锁定依赖版本
- ✓ CI/CD 必须包含所有目标平台
- ✓ 使用 ccache/sccache 加速编译
总结
C++ 包管理已经进入成熟期。vcpkg + CMake Presets 的组合提供了简洁、跨平台的依赖管理方案,Conan 则更适合需要企业级支持的项目。无论选择哪种方案,关键在于:依赖版本锁定、跨平台验证、以及与 CI/CD 的深度集成。
在实践中,建议从 vcpkg 开始,它与 CMake 的原生集成可以快速启动项目。对于需要更严格依赖控制的企业场景,可以逐步引入 Conan 作为补充。