vcpkg 包管理器

强调:安装 IDE 时不要变更默认路径!否则,使用 vcpkg 磨难重重,vcpkg issue#12488我安装 Language English 就失败了,后面也就没尝试

从 visual studio 2015 的“选项”跳转到的中文网站,选择英文语言包下载到的其实是中文语言包,需要更换到对应的英文网站下载才是正确的。仍旧需要使用默认安装路径!

网速要好,偶尔也需要翻墙。如果使用系统自带的 powershell 碰到下载失败、下载慢,且版本陈旧。建议下载 powershell core 试一试,可能会有惊喜。 在 Windows 终端中设置代理 解决问题:$Env:https_proxy="http://127.0.0.1:10809"

使用 vcpkg 安装库后,如果较长时间未更新,再次更新时可能报错:

1
2
3
4
5
6
PS F:\vcpkg> .\vcpkg.exe update
Using local portfile versions. To update the local portfiles, use `git pull`.
Error: while loading boost-signals:
The port directory (F:\vcpkg\ports\boost-signals) does not exist
Error: failed to load port from F:\vcpkg\ports\boost-signals
Note: Updating vcpkg by rerunning bootstrap-vcpkg may resolve this failure.

此时按照提示重新执行多次 bootstrap-vcpkg 也是无效的,我们需要清理掉过时的库:

1
2
3
4
5
6
7
8
PS F:\vcpkg> .\vcpkg.exe list boost-signals
boost-signals2:x86-windows-static-md 1.71.0 Boost signals2 module
boost-signals:x86-windows 1.68.0 Boost signals module
PS F:\vcpkg> .\vcpkg.exe remove boost-signals:x86-windows
The following packages will be removed:
boost-signals:x86-windows
Removing package boost-signals:x86-windows...
Removing package boost-signals:x86-windows... done

之后就使用正常了:

1
2
3
4
5
6
7
8
PS F:\vcpkg> .\vcpkg.exe update
Using local portfile versions. To update the local portfiles, use `git pull`.
The following packages differ from their port versions:
abseil:x86-windows 2020-03-03-4 -> 2020-09-23#3
abseil:x86-windows-static-md 2020-03-03-4 -> 2020-09-23#3
asio:x86-windows 1.12.2 -> 1.18.0
asio:x86-windows-static-md 1.12.2-2 -> 1.18.0
boost-accumulators:x86-windows-static-md 1.71.0 -> 1.75.0

除特别备注,全部摘自 vcpkg: A C++ package manager for Windows, Linux and MacOS。此章节类似读书(博客)笔记。

安装库

  1. 同时支持动态链接库,以及 静态链接。Windows 下默认编译 32 位的动态库。从23年9月开始默认编译 64位的库。

    If no triplet is specified, vcpkg will install and compile for the default triplet for the target platform: x86-windows, x64-linux.cmake, or x64-osx.cmake.

    warning: Starting with the September 2023 release, the default triplet for vcpkg libraries will change from x86-windows to the detected host triplet (x64-windows). To resolve this message, add --triplet x86-windows to keep the same behavior

  2. MT 和 MD:vcpkg 静态链接库默认 /MT(d);动态链接库默认 /MD(d)

    build static libraries against the static CRT (/MT in Visual Studio): x86-windows-static, x64-windows-static, etc.

    Change Compiler settings from MT to MD

    This should be as easy as copying triplets\x86-windows-static.cmake to a new file of your own name (triplets\x86-windows-static-md.cmake, for example). Then change the setting for VCPKG_CRT_LINKAGE to dynamic instead of static.

  3. 不改变环境变量,不依赖注册表 或 Visual Studio 在 Windows 平台还是和后者密切关联的

    为什么总要下载 ninja ? 不会弃用自家 Visual Studio,全面拥抱 ninja 了吧?

  4. 在 Windows 环境使用时,编译源码需要依赖 MSVC2015 或 2017,优先使用后者

    同时安装了 MSVC2015 和 2017 时,如何指定使用前者?Using VS2015 when VS2017 is available,没门!

    We don’t currently have an easy, supported way to opt out of VS2017.

    给出的 set VCPKG_PLATFORM_TOOLSET 的 workaround 也有大的缺陷:

    This will work for CMake-based ports that don’t use Ninja and possibly others. Notably, this will not change boost.

    2019-10-17 打算不管不顾 二进制兼容可能出现的例外,安装时不再纠结 msvc 版本(2015/17/19),就直接安装 vc2019。在 vc2015/17 中使用出错了再说。

  5. 支持导出编译后的库和头文件

  6. vcpkg 自包含,每个 vcpkg 文件夹就是一个实例。每台设备可以有多个实例。

  7. 支持更新、升级已经安装的库

    和更新 vcpkg 自身是不同的概念。更新 vcpkg 自身:git pull

  8. 支持删除已安装的库,并且级联删除其下游(依赖前者的其他库)

    卸载 boost .\vcpkg.exe remove boost-vcpkg-helpers --recurse

  9. 虽然理论上可能用不到 git、cmake,但好多库都是从 github 上获取,是 cmake 组织的。自己安装并配到环境变量里吧,省得每个实例都下载

    vcpkg 针对 git、cmake 设有最低版本,如果系统中查找到版本较低,依旧会重新下载 git 和 cmake。有点坑的地方在于 vcpkg 基本都在追踪最新版本。所以,交给 vcpkg 自己操心吧。下载慢就多等会儿。

使用库

  1. 可以集成到 Visual Studio。当存在多个 vcpkg 实例(目录)时,最后执行 vcpkg integrate install 的目录有效。

    所以,改变目录后,重新执行上述命令即可!

  2. 从 Visual Studio 中解除 vcpkg,执行 vcpkg.exe integrate remove 即可。

    虽然试验中,使用 vcpkg integrate install/remove 开关 vcpkg 能够及时生效,无需重启 MSVC。但总是心里毛毛的。

    之前使用过笨方法,针对每个项目 xxx.vcxproj 手工增加 <VcpkgEnabled>false</VcpkgEnabled> 配置项

  3. 可以撇开主要 Vcpkg 实例,使用库的特定版本 / 将某个实例集成到特定项目中

    This will modify the project file, so we do NOT recommend this approach for open source projects.引用来源:linking-nuget-file

  4. Visual Studio 使用 Vcpkg 默认策略是动态库。对静态库的支持很差,需要手工改一些内容。

    In Visual Studio, you can override the auto-detected triplet (which will default to DLLs) using the MSBuild properties “VcpkgTriplet” and “VcpkgEnabled”.

    如何覆写 MSBuild 属性呢?——目前只发现,以文本形式手动修改 .vxproj 工程文件的方式。好蠢

    试验 Property Sheets 总是莫名其妙无效,直接复制到 .vxproj 中又能生效。

    1
    2
    3
    4
    5
    <PropertyGroup Label="Globals">
    <VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows-static</VcpkgTriplet>
    <!-- <VcpkgEnabled>true</VcpkgEnabled> -->
    <!-- <VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows-static</VcpkgTriplet> -->
    </PropertyGroup>
  5. Nothing

编译选项

截止到目前版本,

1
2
3
4
PS E:\vcpkg> .\vcpkg.exe version
Vcpkg package management program version 2018.10.20-nohash

See LICENSE.txt for license information.

Vcpkg 单个 triplet 文件能够同时生成 Debug/Release 调试版本和发布版本的库。通过自定义 triplet 能够支持 「(x64/win32) &(动态链接库/静态链接库)&(/MD(d)运行时 //MT(d)运行时)」。

  1. 其内嵌对 「(x64/win32) &(使用 /MT(d) 运行时的静态链接库 | 使用 /MD(D) 运行时的动态链接库)」 的支持,在 triplets 文件夹中查看;
  2. 其对 「(动态链接库/静态链接库)&(/MD(d)运行时//MT(d)运行时)」其他组合的支持,需要用户自行编写 triplet 文件实现。

IDE

在上述前提下,要求 Visual Studio 自动化支持 (动态链接库/静态链接库)&(/MD(d)运行时//MT(d)运行时)的任意组合不现实,尤其是场景 2 全权交给用户自行操作的情况。

另外,由于 Visual Studio 并没有「动态链接/静态连接」的开关选项。所以,IDE 仅支持 (Debug/Release) X (x64/win32) X(动态链接库/静态链接库)X(/MD(d)运行时//MT(d)运行时)。

  • 其他组合,需要手动修改 Visual Studio 工程的 property sheet 实现。

NOTICE 第三方库采用的运行时,和项目编译时采用的运行时,这是两个概念。应该一致,但不代表一定一致。

使用 vc2019 时,平台工具集与 IDE 不一致时,vcpkg integrate 不生效。比如:

  • 使用 vc2019 + v140 不生效;只能使用 vc2019 + v142

但使用 vc2015 时,+ v140/v140_xp/v120 都能够生效(后者不支持 std::chrono 等特性)。

另外,vc2019 在以下方面和 vc2015 也不同:

  • 在项目属性 C/C++ -常规-附加包含目录-继承的值 看不到 $(VcpkgRoot)include
  • 链接器-输入-附加依赖项-继承的值 中看不到 $(VcpkgRoot)debug\lib\*.lib 字样。vc2015 能够看到。

其他资源

Visual Studio开源库集成器Vcpkg全教程–利用Vcpkg轻松集成开源第三方库

github 中的手册:docs

在 FAQ 中也提到了 Vcpkg 和 NuGet、Conan、Chocolatey 的区别