一、什么是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会经历这几个过程:
- 环境初始化
- 下载源代码(如果已经在vcpkg\downloads文件夹中,则不重复下载)
- 校验文件有效性
- 解压缩源代码
- 利用配套工具配置源码工程,在这里是使用的是cmake(如果是ffmpeg,则用msys2)
- 编译源码。一般会同时编译Release和Debug版本。
- 把编译好的文件拷贝到相关文件夹中去(一般是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
遇到这种问题,需要通过日志查看具体出错原因,寻找Failed或Error关键字。
例如:Downloading https://raw.githubusercontent.com/boostorg/boost/boost-1.72.0/boostcpp.jam… Failed.
在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.logCall 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,在“语言包”里勾选“英语”进行安装。
九、参考文档
- 《Visual Studio开源库集成器Vcpkg全教程–利用Vcpkg轻松集成开源第三方库》版权声明:本文为CSDN博主「Achilles」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
- 《vcpkg:用于 Windows、Linux 和 MacOS 的 C++ 包管理器》
- 《完美解决 vcpkg 下载速度慢》作者:东风小火