vcpkg安装与使用教程

一、什么是vcpkg

vcpkg是用于C++的一种命令行包管理器。它极大地简化了 Windows、Linux 和 MacOS 上第三方库的购置与安装。如果项目要使用第三方库,建议通过vcpkg来安装它们。 vcpkg 同时支持开源和专有库。

二、为什么要用vcpkg

  • 传统使用开源库的方法
    Windows下开发C/C++程序,少不了编译开源的第三方库。比如用于网络连接的高性能库libcurl、用于压缩解压的zlib等等。使用这些库开发极大的方便了程序员,使得我们不必重复造轮子。但是使用这些库必须要处理以下问题。
  • 编译工具
    由于这些开源库绝大部分都来源于Linux系统,导致其工程文件、编译系统都使用gnu系列工具,使得将其移植到Windows的VC开发环境下一直是难点。尽管最近几年很多开源库都支持了跨平台的cmake,但是编译过程仍然复杂和多样化。
  • 常见的编译方式有:
编译方式 特点 举例
configure、make 需要msys这样的unix环境才可以编译 ffmpeg
自定义编译工具 需要学习特定的编译命令和工具 openssl、boost
cmake 相对简单轻松 libcurl
VC工程文件 这种最简单,直接拿来即可编译
  • 编译类型
    当了解了这些还不够,我们还需要考虑预先编译出哪种类型的开源库程序。比如:Debug还是Release、动态库还是静态库、MD还是MT、32位还是64位。光是这三种组合就有16种可能性。如果像libcurl这种还要考虑是否引用其他开源库的功能,那么编译类型的组合会更多。管理起来很麻烦。
  • 工程目录设定
    由于多样的编译类型,工程目录也必须仔细设定才能保证自己的软件项目能够正常编译。
  • Vcpkg的优点
    自动下载开源库源代码
    源码包的缓存管理和版本管理,可以升级版本
    轻松编译
    依赖关系检查(比如编译libcurl,会自动下载zlib、openssl进行编译)
    无缝集成Visual Studio,不需要设置库文件、头文件的所在目录,自动集成。
    Visual Studio全平台支持,不仅支持Debug/Release、x86/x64编译,还支持UWP、ARM平台的编译。

三、获取

Vcpkg的官方源码站点为:https://github.com/microsoft/vcpkg

帮助文档:https://learn.microsoft.com/zh-cn/vcpkg/get_started/overview

四、编译

Vcpkg大量使用的psl脚本,所以官方强烈推荐使用PowerShell而不时CMD命令行来执行各种操作。尽管在使用的时候兼容CMD,但是在编译这一步,请使用PowerShell。本文的操作都使用PowerShell 7

编译很简单,执行Vcpkg工程目录下的“bootstrap-vcpkg.bat”文件,即可编译。编译好以后会在同级目录下生成vcpkg.exe文件。编译期间,脚本会自动下载vswhere组件。

五、使用

5.1 查看vcpkg支持的开源库列表

vcpkg search

5.2 安装一个开源库

这里的“安装”其实是指下载和编译。
比如我们需要安装常用的jsoncpp库,那么执行命令
vcpkg install jsoncpp
我们大致可以了解到install会经历这几个过程:

  1. 环境初始化
  2. 下载源代码(如果已经在vcpkg\downloads文件夹中,则不重复下载)
  3. 校验文件有效性
  4. 解压缩源代码
  5. 利用配套工具配置源码工程,在这里是使用的是cmake(如果是ffmpeg,则用msys2)
  6. 编译源码。一般会同时编译Release和Debug版本。
  7. 把编译好的文件拷贝到相关文件夹中去(一般是vcpkg\installed文件夹)

5.3 指定编译某种架构的程序库

如果不指定安装的架构,vcpkg默认把开源库编译成当前操作系统架构的库。那vcpkg总共支持多少种架构呢?我们可以使用如下命令便知:
vcpkg help triplet
我们可以看到会列出如下清单:

arm-android
arm-ios
arm-linux-release
arm-linux
arm-mingw-dynamic
arm-mingw-static
arm-mingw
arm-neon-android
arm-uwp-static-md
arm-windows-static
arm-windows
arm64-android
arm64-ios
arm64-linux-release
arm64-linux
arm64-mingw-dynamic
arm64-mingw-static
arm64-mingw
arm64-osx-dynamic
arm64-osx-release
arm64-osx
arm64-uwp-static-md
arm64-uwp
arm64-windows-static-md
arm64-windows-static-release
arm64-windows-static
arm64ec-windows
armv6-android
ppc64le-linux-release
ppc64le-linux
riscv32-linux-release
riscv32-linux
riscv64-linux-release
riscv64-linux
s390x-linux-release
s390x-linux
wasm32-emscripten
x64-android
x64-freebsd
x64-ios
x64-linux-dynamic
x64-linux-release
x64-mingw-dynamic
x64-mingw-static
x64-mingw
x64-openbsd
x64-osx-dynamic
x64-osx-release
x64-uwp-static-md
x64-windows-release
x64-windows-static-md
x64-windows-static-release
x86-android
x86-freebsd
x86-ios
x86-linux
x86-mingw-dynamic
x86-mingw-static
x86-mingw
x86-uwp-static-md
x86-uwp
x86-windows-static-md
x86-windows-static
x86-windows-v120

这个清单以后随着版本的迭代还会再增加。vcpkg不仅支持x86架构,还支持arm架构。注意:这里的arm架构特指类似于surface这种运行在arm处理器上的Win10平台,而并非我们传统意义上的Linux或android的ARM平台。

那如果要安装编译某一个架构的开源库,我们该怎么写呢?我们只需要在需要安装的包后面指定相应的triplet即可。例如我们需要编译64位版本的jsoncpp,那么执行如下命令即可。
vcpkg install jsoncpp:x64-windows-release

5.4 移除一个已经安装(编译)的开源库

如果移除一个已经安装的开源库,那么执行remove指令即可。比如我们要移除jsoncpp,那么执行命令:
vcpkg remove jsoncpp
注意:
这个时候只是移除了默认的x86-winodws版本的文件,如果有其他平台的版本需要移除,需要制定相应的triplet。
移除也只是移除了二进制程序库而已,源码包和解压缩的源码并没有删除。
如果想要一键移除“过时”的包,执行命令:
vcpkg remove --outdated

5.5 列出已经安装的开源库

执行list指令即可,例如:
vcpkg list

5.6 更新已经安装的开源库

一般有两种更新方式。一个是update指令,可以显示可以升级的开源库的列表。另一个是upgrade的指令,会重新编译所有需要更新的包。

由于vcpkg是使用本地缓存列表的方式,而不是实时去获取最新列表,因此建议每间隔一个月在vcpkg安装目录下执行一次git pull,然后再使用下面的命令更新:

vcpkg upgrade --no-dry-run

只更新某个包,例如:vcpkg upgrade opencv4:x64-windows --no-dry-run

六、集成

上面我们已经安装了一些第三方库,那如何使用呢?常规情况下,我们需要设置include目录、lib目录等,会有很多工作量。而vcpkg提供了一套机制,可以全自动的适配目录,而开发者不需要关心已安装的库的目录在哪里,也不需要设置。这是vcpkg的一大优势。

6.1 与 Visual Studio 集成

执行命令:vcpkg integrate install

当出现“Applied user-wide integration for this vcpkg root.”字样的时候,说明已经集成成功。这时候可以在任意的工程中使用安装好的第三方库,通过<库名\头文件>的方式即可引入需要的头文件,并会自动在项目输出目录中创建所需的dll等。

移除全局集成只要执行命令:vcpkg integrate remove

6.2 与 CMake(GUI)集成

在CMake的配置参数中,增加vcpkg工具链的路径:”-DCMAKE_TOOLCHAIN_FILE=${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake”。

CMakeLists.txt中添加:SET(CMAKE_TOOLCHAIN_FILE $ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)

如果使用CMake的GUI,则在点击Configure按钮之前先点击Add Entry按钮,然后输入以下信息:

  • Name:CMAKE_TOOLCHAIN_FILE
  • Type:FILEPATH
  • Value:指向vcpkg的 scripts/buildsystems/vcpkg.cmake 文件的完整路径。

七、设置网络代理

条件允许的话尽量使用代理吧,这样就不会出现下载慢或下载失败的情况了。

在Windos平台的PowerShell中依据你的代理服务器配置执行下面命令,例如:

$env:HTTP_PROXY="127.0.0.1:10809" 
$env:HTTPS_PROXY="127.0.0.1:10809"

在Linux平台的终端中,例如:

export http_proxy=http://127.0.0.1:10809
export https_proxy=http://127.0.0.1:10809

八、可能遇到的问题

8.1 下载慢

设置Powershell使用网络代理,参考上一章节。

8.2 Failed to do post-extract rename-in-place.

例如:

Failed to do post-extract rename-in-place.
fs.rename(D:\SoftwareDevelopment\vcpkg\downloads\tools\git-2.25.1-1-windows.partial.34372, D:\SoftwareDevelopment\vcpkg\downloads\tools\git-2.25.1-1-windows, operation not permitted)

字面意思是权限不足,重命名失败,但我明明是用管理员权限运行的PowerShell。

手动重命名提示的文件(夹)即可。这里是将git-2.25.1-1-windows.partial.34372文件夹重命名为git-2.25.1-1-windows

8.3 Building package boost-compatibility:x86-windows failed with: BUILD_FAILED

遇到这种问题,需要通过日志查看具体出错原因,寻找FailedError关键字。

例如:Downloading https://raw.githubusercontent.com/boostorg/boost/boost-1.72.0/boostcpp.jamFailed.

vcpkg\downloads\temp文件里有一个大小为0的boost-1.72.0-boostcpp.jam文件。注意文件名不完全相同,说明它需要下载后重命名。

下载时出错,重试多次都不行,网络也没问题。那就复制地址,用浏览器下载这个文件,然后保存在vcpkg\downloads文件夹里并重命名boost-1.72.0-boostcpp.jam就行了。

8.4 CMake Error: Problem with archive_write_header(): Can’t create ”

PowerShell中报类似如下的错误:

Building package expat[core]:x86-windows…
— Downloading https://github.com/libexpat/libexpat/archive/R_2_2_7.tar.gz…
— Extracting source D:/CDH/vcpkg/downloads/libexpat-libexpat-R_2_2_7.tar.gz
CMake Error at scripts/cmake/vcpkg_execute_required_process.cmake:72 (message):
Command failed: D:/CDH/vcpkg/downloads/tools/cmake-3.14.0-windows/cmake-3.14.0-win32-x86/bin/cmake.exe -E tar xjf D:/CDH/vcpkg/downloads/libexpat-libexpat-R_2_2_7.tar.gz
Working Directory: D:/CDH/vcpkg/buildtrees/expat/src/TEMP
Error code: 1
See logs for more information:
D:\CDH\vcpkg\buildtrees\expat\extract-err.log

Call Stack (most recent call first):
scripts/cmake/vcpkg_extract_source_archive.cmake:43 (vcpkg_execute_required_process)
scripts/cmake/vcpkg_extract_source_archive_ex.cmake:108 (vcpkg_extract_source_archive)
scripts/cmake/vcpkg_from_github.cmake:139 (vcpkg_extract_source_archive_ex)
ports/expat/portfile.cmake:6 (vcpkg_from_github)
scripts/ports.cmake:90 (include)

在其中的extract-err.log里,是:

CMake Error: Problem with archive_write_header(): Can’t create ”
CMake Error: Current file: libexpat-R_2_2_7/README.md
CMake Error: Problem extracting tar: D:/CDH/vcpkg/downloads/libexpat-libexpat-R_2_2_7.tar.gz

解决方案是打开“控制面板->区域->管理->更改系统区域设置”,取消勾选“Beta版:使用Unicode UTF-8提供全球语言支持”。

8.5 Please install the English language pack

打开Visual Studio Installer,在“语言包”里勾选“英语”进行安装。

九、参考文档

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注