vcpkg包管理工具介绍

1 vcpkg简介

vcpkg 是一个开源项目,由微软开发并维护,旨在简化跨平台 C++ 库的获取与管理过程。对于开发者来说,寻找、安装以及管理第三方C++库往往是一件既耗时又容易出错的工作,尤其是在不同的操作系统上进行开发时。vcpkg 就是为了解决这一痛点而诞生的工具。官方文档: vcpkg 文档 | Microsoft Learn, 这里我会结合自己实际的使用体验进行介绍。

  • 跨平台支持:vcpkg 支持 Windows、Linux 和 macOS 操作系统,这意味着你可以用一种方式在所有这些平台上管理你的依赖项。
  • 简化依赖管理:通过简单的命令行操作即可安装、卸载和升级库。这使得开发者能够更加专注于应用程序本身的开发,而不是被复杂的库管理和构建流程所困扰。
  • 预编译二进制文件:为了加速开发流程,vcpkg 提供了许多库的预编译二进制文件。这样就避免了每次都要从源码编译库的麻烦,特别是在开发环境中频繁地切换或测试不同版本的库时。
  • 社区驱动:vcpkg 是一个活跃的开源项目,拥有庞大的社区支持。这意味着它不仅有定期更新以包含最新的库版本,还有一群热心的贡献者可以帮助解决使用过程中遇到的问题。

2 安装

1
2
3
4
git clone https://github.com/microsoft/vcpkg.git # 克隆仓库
cd vcpkg
./bootstrap-vcpkg.sh # Linux bash
.\bootstrap-vcpkg.bat # Windows Powershell

设置环境变量:

Windows

1
2
3
4

$env:VCPKG_ROOT = "C:\path\to\vcpkg"
$env:PATH = "$env:VCPKG_ROOT;$env:PATH"
# 永久设置需要再系统环境变量中添加

Linux

1
2
3
export VCPKG_ROOT=/path/to/vcpkg
export PATH=$VCPKG_ROOT:$PATH
# 永久设置需要添加到~/.bashrc

3 案例项目解析

3.1 官方案例引入

3.1.1 项目配置

这里引入官方的案例项目:通过 CMake 安装和使用包 | Microsoft Learn, 但对其进行相应的补充和扩展

1
2
3
4
mkdir vckpg_example
cd vcpkg_example
vcpkg new --application # 初始化vcpkg项目
vcpkg add port fmt # 添加 fmt 依赖项

添加如下所示的 CMakeLists.txt:

1
2
3
4
5
6
7
8
9
cmake_minimum_required(VERSION 3.10)

project(HelloWorld)

find_package(fmt CONFIG REQUIRED) # 指定vcpkg的查找的库

add_executable(HelloWorld helloworld.cpp)

target_link_libraries(HelloWorld PRIVATE fmt::fmt)

创建包含以下内容的 helloworld.cpp 文件:

1
2
3
4
5
6
7
#include <fmt/core.h>

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

配置vcpkg

创建 CMakePresets.json

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": 2,
"configurePresets": [
{
"name": "vcpkg",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
}
]
}

创建 CMakeUserPresets.json

1
2
3
4
5
6
7
8
9
10
11
12
{
"version": 2,
"configurePresets": [
{
"name": "default",
"inherits": "vcpkg",
"environment": {
"VCPKG_ROOT": "/home/toni/proj/vcpkg"
}
}
]
}

配置文件 CMakePresets.jsonCMakeUserPresets.json的区别是什么?

  • CMakePresets.json与 CMakeLists.txt 文件同级, 用于项目级和用户级的 CMake 配置。
  • CMakeUserPresets.json允许用户自定义与个人开发环境相关的构建预设,通常不共享给其他开发者,可以继承和覆盖项目级的 CMakePresets.json 中的预设,增加额外的个性化配置。
  • CMakePresets.json是必须的, 而 CMakeUserPresets.json是可选的

3.1.2 编译指令

1
2
3
4
$ cmake --preset=default # 或vcpkg
$ cmake --build build
$ ./build/HelloWorld #运行编译结果
Hello World

3.2 代码智能补全配置

按照官网的提示完成的项目虽然可以运行, 但其由于依赖包是vcpkg统一管理的, 因此IDE通常找不到头文件而无法提供代码智能补全, 这里我以 VSCode+clangd开发环境为例:

1728029671453

这里需要手动将其头文件搜索路径引入进来, 这里提前引入统一的安装命令:install:

1
vcpkg install fmt

安装后再如下位置可以找到源文件:

1728030298083

在项目根目录创建 .clangd文件:

1
2
3
4
CompileFlags:
Add:
- "-isystem/home/toni/proj/vcpkg/installed/x64-linux/include"

注意还需修改头文件的<>引入符合为””, 现在已经能够识别头文件位置了:

1728030546951

4 基本概念和术语

术语 定义 作用/用途 示例
Package(包) 项目依赖的第三方库或软件组件 用于安装和管理库,例如 boostsqlite3 vcpkg install boost
Port(端口) 将库移植到 vcpkg 的构建和安装说明 定义如何下载、编译、安装库。通常在 ports/<package> 目录下 ports/boost 中定义了 boost 的安装和配置方式
Triplet(三元组) 定义目标平台的架构、操作系统和链接方式(静态或动态) 通过三元组为不同平台编译库,如 x64-windows-static x64-windows-static, x86-linux-dynamic, arm64-osx
Overlay Ports 自定义或覆盖默认端口文件 允许自定义端口的行为和版本,避免修改 vcpkg 官方端口 --overlay-ports=<path> 参数用来指定自定义端口
Manifest Mode(清单模式) 使用 vcpkg.json 定义项目的依赖 自动解析并安装项目依赖,简化依赖管理 vcpkg.json 中定义依赖库,如 boost, openssl
Classic Mode(经典模式) 手动管理和安装依赖库,不依赖 vcpkg.json 包会安装在全局环境中,多个项目可以共享 vcpkg install <package>
Registries(注册表) 存储和分发包的仓库,类似于 npm 的注册表 可以使用官方注册表或配置私有注册表 vcpkg 默认使用 GitHub 仓库,但可以自定义注册表
Baseline(基线) 定义依赖包的稳定版本集合 锁定项目的依赖包版本,避免因更新包导致的不兼容问题 vcpkg.json 中的 builtin-baseline 定义项目依赖的基线版本
Toolchain File(工具链文件) CMake 中用于配置编译器、链接器和选项的文件 让 CMake 项目在构建时自动使用 vcpkg 安装的包 cmake -DCMAKE_TOOLCHAIN_FILE=<path-to-vcpkg>/scripts/buildsystems/vcpkg.cmake
Vcpkg Artifacts 扩展机制,用于管理和安装开发工具和工具链 不仅限于库的管理,还可以安装编译器、调试工具等 安装编译器、调试工具等其他构建工具