vcpkg 概述

Vcpkg 是由 Microsoft 和 C++ 社区维护的免费开源 C/C++ 包管理器,可在 Windows、macOS 和 Linux 上运行。 它是核心的 C++ 工具,使用 C++ 和 CMake 脚本编写。 它旨在解决管理 C/C++ 库的独特难题。

为什么使用 vcpkg?

vcpkg 功能

端口和三元组

vcpkg 端口是一种版本控制生成方案,可生成一个包。 最常见的包类型是包含标头、源代码和二进制文件的 C/C++ 库。

三元组以单个方便的名称捕获目标生成环境(cpu、os、编译器、运行时等)。 vcpkg 默认提供超过 70 个三元组,但你也可以定义自己的三元组。

为了在系统上安装包,vcpkg 会运行端口的配方文件(CMake 脚本)。 该脚本可能包含下载源代码或在系统中运行生成的步骤。 在生成期间,vcpkg 使用三元组中的信息来确保生成的包与所需的配置匹配。

二进制缓存

尽管 vcpkg 根据需要从源生成库,但可以在二进制缓存中备份生成的包。 这样,便可以运行其他开发人员计算机或持续集成以引用这些预生成的包,而无需每次运行新的生成。 vcpkg 会检查缓存是否已包含有效的现有包以及相应的二进制文件,以确定是否需要重新生成。

清单

可以在清单文件中声明直接依赖项并添加可选功能或版本约束。 清单文件可以签入到源控制系统中并与团队共享。

版本控制

vcpkg 具有处理包版本的唯一方法。 清单文件可以引用默认设置的单个基线版本。 该基线提供轻而易举且无冲突的依赖项管理,具有完全可重现性。 此外,你仍然可以通过固定各个包版本来获得更高级的控制。

注册表

注册表是 vcpkg 用户可以安装的端口和可用版本的集合。 vcpkg 默认提供开放源代码库的特选注册表。 还可以为自定义、修补或私人库创建自己的注册表。

资产缓存

资产缓存可使 vcpkg 在实体隔离和离线环境中工作,即使远程主机出现故障或被盗用,也可确保业务连续性。 它使用下载镜像上传和还原资产,例如源代码和生成工具。

vcpkg 与其他包管理器的比较

vcpkg 与 NuGet 的比较

NuGet 是 .NET 包管理器,通常用于 C/C++ 开发,尤其适用于同时包含 .NET 项目的 MSBuild 解决方案。 一般情况下,Microsoft C++ 团队不建议使用 NuGet 进行 C/C++ 开发,因为 NuGet 存在以下限制:

  • 编译风格。 由于 NuGet 无法即时从源生成包,因此必须提供预生成的二进制文件,以符合所有用户的所有可能的应用程序二进制接口 (ABI) 限制。 用户负责自行生成包。 由于缺少相关的元数据,也很难区分二进制文件。 这会导致用户将体系结构、操作系统以及编译器信息放置在包名称中。 这是不可取的,因为在包获取期间无法强制实施对体系结构、OS 和编译器信息的约束。
  • 二进制文件与源代码。 NuGet 从一开始就旨在提供相对较小的预生成二进制文件。 开发人员需要有权访问源代码,以确保 ABI 兼容性、性能、完整性和可调试性。
  • 不支持 NuGet PackageReference.vcxproj 文件不支持 NuGet PackageReference,并且由于 C++ 和 .NET MSBuild 项目之间存在技术和体系结构差异,因此没有添加它的计划。 这意味着 NuGet C++ 用户不会受益于使用全局缓存和在具有条件逻辑访问权限的简单 MSBuild 术语中引用依赖项的功能。
  • 可传递的 ABI 跟踪。 vcpkg 重新构建受特定包更改影响的开源依赖项。 例如,如果为 Boost 发布了新的更新,vcpkg 会重新生成 Boost 的所有依赖项以及依赖于 Boost 的库,从而确保它们仍然有效。 在解决此类生成时冲突之前,不会合并用于更新 vcpkg 存储库中的库的拉取请求。

vcpkg 与系统包管理器的比较

适用于 Linux、macOS 和 Windows 的各种系统包管理器可用于获取和管理 C/C++ 库。 这些包管理器通常非常适合用于管理应用程序。 但是,由于其支持的一般性质,它们通常无法提供令 C/C++ 开发人员受益的功能。 虽然你的情况可能会有所不同,并且某些系统包管理器确实提供其中一些功能,但没有一个系统包管理器拥有以下全部功能:

  • 可再分发的开发人员资产:vcpkg 可以获取可再分发的开发人员资产,以帮助进行调试。
  • 预生成包与从源生成:vcpkg 可以根据自定义要求从源生成包。 无需处理预生成的预编译包,即可让它们发挥作用。
  • 目录范围的版本控制:vcpkg 允许你依赖于一组已进行版本控制的兼容包,而无需对各个包版本进行微观管理。 您仍然可以根据需要执行此操作,但但默认体验旨在易于上手。
  • 一个系统上同一个库的多个副本:可以使用 vcpkg 在同一系统上安装同一个依赖项的多个副本,而系统包管理器可以将一个版本安装到单个系统范围的位置。 当有多个项目依赖于库的不同版本时,情况就会变得复杂。
  • 目录大小:由于 vcpkg 专用于 C/C++,因此相较于系统包管理器,它具有非常大的 C/C++ 库集合,并且得以主动维护。 一般情况下,你更有可能发现适用于此类 C++ 开发的最新的库。
  • 跨平台支持:系统包管理器提供锁定到该特定系统的包。 如果需要面向多种操作系统,则需要为第二个系统寻找不同的包管理器。 相比之下,vcpkg 是跨平台的包管理器。 因此,只需相应地调整目标生成即可。

在有些情况下使用系统包管理器绝对更合适。

  • 系统包管理器往往能有效地提供并维护特定于该系统的库
  • 如果使用的项目具有简单的生成配置,则预生成的包应在该系统上开箱即用。
  • 如果不打算进行任何跨平台开发,则不会遇到与系统包管理器的操作系统兼容性问题。

vcpkg 旨在与系统包管理器并行工作,因此可以随意使用最适合于每个依赖项的工具。

vcpkg 入门

若要试用 vcpkg,请查阅我们的入门教程:

如果生成系统不是 CMake 或 MSBuild,vcpkg 也支持与首选环境进行手动集成