教程:从清单文件安装依赖项

vcpkg 有两种运行模式:经典模式和清单模式。 本文介绍如何使用清单模式安装包,这是大多数用户推荐的工作流。

在清单模式下,在名为 vcpkg.json 的清单文件中声明项目的直接依赖项。

清单文件有自己的 vcpkg_installed 目录,可在其中安装依赖项,与所有包都安装在通用 %VCPKG_ROOT%/installed 目录中的经典模式不同。 因此,每个项目都可以有自己的清单和自己的一组依赖项,这些依赖项不会与其他项目的依赖项发生冲突。

使用版本控制自定义注册表等高级功能也需要清单模式。

在本教程中,您将学习如何执行以下操作:

先决条件

  • vcpkg
  • 终端
  • 代码编辑器
  • C++ 编译器
  • (可选)CMake 或 MSBuild

1 - 创建包含清单的项目

在新文件夹中,使用以下内容创建名为 main.cxx 的源文件:

#include <cxxopts.hpp>
#include <fmt/format.h>
#include <range/v3/view.hpp>

namespace view = ranges::views;

int fib(int x)
{
  int a = 0, b = 1;

  for (int it : view::repeat(0) | view::take(x))
  {
    (void)it;
    int tmp = a;
    a += b;
    b = tmp;
  }

  return a;
}

int main(int argc, char **argv)
{
  cxxopts::Options options("fibo", "Print the fibonacci sequence up to a value 'n'");
  options.add_options()("n,value", "The value to print to", cxxopts::value<int>()->default_value("10"));

  auto result = options.parse(argc, argv);
  auto n = result["value"].as<int>();

  for (int x : view::iota(1) | view::take(n))
  {
    fmt::print("fib({}) = {}\n", x, fib(x));
  }
}

该代码引用开放源代码库:cxxoptsfmtrange-v3;这些库均在 https://github.com/Microsoft/vcpkg 的 vcpkg 公共注册表中提供。

要声明这些依赖项,请在项目所在的同一目录中创建一个名为 vcpkg.json 的文件:

vcpkg.json:

{
  "dependencies": [
    "cxxopts",
    "fmt",
    "range-v3"
  ]
}

只需在 "dependencies" 列表中指定直接依赖项。 运行时,vcpkg 会解析并安装任何所需的可转移依赖项。

2 - 将 vcpkg 与构建系统集成

在此步骤中,我们将向你展示如何将 vcpkg 与 CMake 或 MSBuild 集成,以便在构建项目时自动安装或还原项目依赖项。

如果使用其他构建系统,请跳到下一步:安装依赖项

在 MSBuild 项目中使用 vcpkg,请运行以下命令:

vcpkg integrate install

只需在首次要启用 MSBuild 集成时运行 vcpkg integrate install 命令。 这将为所有现有和未来项目启用 MSBuild 集成。 使用 vcpkg integrate remove 可移除 MSBuild 系统范围的集成。

此集成方法自动将已安装 vcpkg 的包添加到以下项目属性:Include DirectoriesLink DirectoriesLink Libraries。 此外,这会创建一个构建后操作,该操作可确保将任何所需的 DLL 复制到构建输出文件夹中。 这适用于使用 Visual Studio 2015 或更高版本的所有解决方案和项目。

3 - 安装依赖项

如果使用 CMake 或 MSBuild 并遵循上一步操作,则可以跳到下一步:构建项目

如果使用其他构建系统或想要手动安装依赖项,只需在包含清单文件的目录中运行 vcpkg install

PS D:\projects\manifest-example> vcpkg install
Detecting compiler hash for triplet x64-windows...
The following packages will be built and installed:
    cxxopts:x64-windows -> 3.1.1
    fmt:x64-windows -> 10.0.0
    range-v3:x64-windows -> 0.12.0#1
  * vcpkg-cmake:x64-windows -> 2023-05-04
  * vcpkg-cmake-config:x64-windows -> 2022-02-06#1
Additional packages (*) will be modified to complete this operation.
Installing 1/5 vcpkg-cmake-config:x64-windows...
Installing 2/5 vcpkg-cmake:x64-windows...
Installing 3/5 cxxopts:x64-windows...
Installing 4/5 fmt:x64-windows...
Installing 5/5 range-v3:x64-windows...
Total install time: 48 s
cxxopts provides CMake targets:

    # this is heuristically generated, and may not be correct
    find_package(cxxopts CONFIG REQUIRED)
    target_link_libraries(main PRIVATE cxxopts::cxxopts)

The package fmt provides CMake targets:

    find_package(fmt CONFIG REQUIRED)
    target_link_libraries(main PRIVATE fmt::fmt)

    # Or use the header-only version
    find_package(fmt CONFIG REQUIRED)
    target_link_libraries(main PRIVATE fmt::fmt-header-only)

range-v3 provides CMake targets:

    # this is heuristically generated, and may not be correct
    find_package(range-v3 CONFIG REQUIRED)
    target_link_libraries(main PRIVATE range-v3::meta range-v3::concepts range-v3::range-v3)

该命令完成后,所有生成的包都将出现在 vcpkg_installed 目录中。 此目录的具体位置取决于构建系统;通常,在构建系统的默认输出文件夹内,或 vcpkg.json 文件旁边。

4 - 构建项目

默认情况下,MSBuild 项目中禁用清单模式。

要在项目中启用清单,请在 .vcxproj 文件中设置 VcpkgEnableManifest 属性:

<PropertyGroup Label="Vcpkg">
  <VcpkgEnableManifest>true</VcpkgEnableManifest>
</PropertyGroup>

或者,可以通过传递 msbuild /p:VcpkgEnableManifest=true 作为参数,在 MSBuild 调用时启用清单模式。

PS D:\projects\manifest-example> msbuild /p:VcpkgEnableManifest=true
MSBuild version 17.7.0-preview-23319-02+6829506b8 for .NET Framework
Build started 8/11/2023 11:29:50 AM.

Project "D:\projects\manifest-example\manifest-example.sln" on node 1 (default targets).
ValidateSolutionConfiguration:
  Building solution configuration "Debug|x64".
Project "D:\projects\manifest-example\manifest-example.sln" (1) is building "D:\projects\manifest-example\manifest-example.vcxproj" (2) on node 1 (default targets).
PrepareForBuild:
  (omitted)
InitializeBuildStatus:
  (omitted)
ComputeStdModulesCompileInputs:
  (omitted)
SetModuleDependencies:
  Creating directory "x64\Debug\manifest.ceffc6eb_MD.tlog\".
VcpkgTripletSelection:
  Using triplet "x64-windows" from "D:\projects\manifest-example\vcpkg_installed\x64-windows\x64-windows\"
  Using normalized configuration "Debug"
VcpkgInstallManifestDependencies:
  Installing vcpkg dependencies to D:\projects\manifest-example\vcpkg_installed\x64-windows\
  Creating directory "D:\projects\manifest-example\vcpkg_installed\x64-windows\".
  "D:\vcpkg\vcpkg.exe" install  --x-wait-for-lock --triplet "x64-windows" --vcpkg-root "D:\vcpkg\" "--x-manifest-root=D:\projects\manifest-example\" "--x-install-root=D:\projects\manifest-example\vcpkg_installed\x64-windows\"
  "D:\vcpkg\vcpkg.exe" install  --x-wait-for-lock --triplet "x64-windows" --vcpkg-root "D:\vcpkg\" "--x-manifest-root=D:\projects\manifest-example\" "--x-install-root=D:\projects\manifest-example\vcpkg_installed\x64-windows\"
  Detecting compiler hash for triplet x64-windows...
  The following packages will be built and installed:
      cxxopts:x64-windows -> 3.1.1
      fmt:x64-windows -> 10.0.0
      range-v3:x64-windows -> 0.12.0#1
    * vcpkg-cmake:x64-windows -> 2023-05-04
    * vcpkg-cmake-config:x64-windows -> 2022-02-06#1
  (omitted)
ClCompile:
  (omitted)
Link:
  (omitted)
AppLocalFromInstalled:
  pwsh.exe -ExecutionPolicy Bypass -noprofile -File "D:\vcpkg\scripts\buildsystems\msbuild\applocal.ps1" "D:\projects\manif
  est-mode-msbuild\x64\Debug\manifest-example.exe" "D:\projects\manifest-example\vcpkg_installed\x64-windows\x64-windows\debug\bin"
  "x64\Debug\manifest.ceffc6eb.tlog\manifest-example.write.1u.tlog" "x64\Debug\vcpkg.applocal.log"
  D:\projects\manifest-example\x64\Debug\fmtd.dll
FinalizeBuildStatus:
  (omitted)
Done Building Project "D:\projects\manifest-example\manifest-example.vcxproj" (default targets).

Done Building Project "D:\projects\manifest-example\manifest-example.sln" (default targets).

Build succeeded.

后续步骤

在本指南中,使用清单文件安装了一个简单项目的依赖项。

以下是接下来要尝试的一些其他任务:

  • 使用三元组安装自定义平台、编译器或构建体系结构的包
  • 使用版本控制锁定版本实现可重复构建
  • 使用二进制缓存在本地或持续集成运行中重复使用二进制文件
  • 使用自定义注册表管理专用库