VCpkg 开源库管理工具

VcPkg & MinGW GCC

VCpkg 开源库管理工具

Windows 下开发 C/C++ 程序,少不了编译开源的第三方库。比如用于网络连接的高性能库 libcurl、用于压缩解压的 zlib 等等。使用这些库开发极大的方便了程序员,使得我们不必重复造轮子。由于这些开源库绝大部分都来源于 Linux 系统,其工程文件、编译系统都使用 gnu 系列工具,使得将其移植到 Windows 的 VC 开发环境下一直是难点。

还需要考虑预先编译出哪种类型的开源库程序,比如:Debug 还是 Release、动态库还是静态库、MD 还是 MT、32 位还是 64 位。光是这三种组合就有 16 种可能性。如果像 libcurl 这种还要考虑是否引用其他开源库的功能,那么编译类型的组合会更多。

VCpkg 就是解决这个问题的:

  • 自动调用 git 等工具下载开源库源代码;
  • 源码包的缓存管理和版本管理,可以升级版本;
  • 紧密结合 CMake 轻松编译;
  • 依赖关系检查,比如编译 libcurl,会自动下载 zlib、openssl 进行编译;
  • 无缝集成 Visual Studio,不需要设置库文件、头文件的所在目录,自动集成。
  • Visual Studio 全平台支持,支持 Debug/Release、x86/x64 编译,还支持 UWP、ARM 平台的编译。

一般使用流程:

  • 执行 vcpkg 安装模块,等待编译动作完成;
  • 执行 vcpkg integrate 集成到项目或者 Visual Studio,又或者全局集成;
  • 在代码中通过头文件使用安装好的模块;

vcpkg 主目录文件夹结构:

| buildtrees | 所有下载好的 library 源代码和构建目录 |
| docs | 文档与示例 |
| downloads | 下载缓冲文件夹,执行安装命令时会先查询这里 |
| installed | 包含安装好的 library 头文件和编译文件 |
| packages | 内部文件夹,在安装时用到 |
| ports | 包含分类中的库描述文件,包含版本、下载地址等 |
| scripts | 脚本目录,如 cmake, powershell 脚本 |
| toolsrc | VcPkg C++ 源代码和组件 |
| triplets | 包含支持架构配置文件,如 x86-windows、x64-uwp |

vcpkg 安装依赖模块的基本执行流程:

  • 环境初始化
  • 下载源代码,如果已经在 cache 中,则跳过下载环节
  • 校验文件有效性
  • 解压缩源代码
  • 利用配套工具配置源码工程,如 cmake,如果是 ffmpeg 则用 msys2
  • 执行 MSBuild 编译源码,一般会同时编译 Release 和 Debug 版本。
  • 把编译好的文件拷贝到相关目录中去,一般是 installed 目录

如果没有在 vcpkg 主目录运行,可能会遇到 Error: Could not detect vcpkg-root。

使用 PowerShell 执行 Vcpkg 工程目录下的 bootstrap-vcpkg.bat 进行编译,会在同级目录下生成 vcpkg.exe 文件。

命令使用示范:

>vcpkg --help
Commands:
  vcpkg search [pat]              Search for packages available to be built
  vcpkg install <pkg>...          Install a package
  vcpkg remove <pkg>...           Uninstall a package
  vcpkg remove --outdated         Uninstall all out-of-date packages
  vcpkg list                      List installed packages
  vcpkg update                    Display list of packages for updating
  vcpkg upgrade                   Rebuild all outdated packages
  vcpkg x-history <pkg>           (Experimental) Shows the history of CONTROL versions of a package
  vcpkg hash <file> [alg]         Hash a file by specific algorithm, default SHA512
  vcpkg help topics               Display the list of help topics
  vcpkg help <topic>              Display help for a specific topic

  vcpkg integrate install         Make installed packages available user-wide. Requires admin
                                  privileges on first use
  vcpkg integrate remove          Remove user-wide integration
  vcpkg integrate project         Generate a referencing nuget package for individual VS project use
  vcpkg integrate powershell      Enable PowerShell tab-completion

  vcpkg export <pkg>... [opt]...  Exports a package
  vcpkg edit <pkg>                Open up a port for editing (uses %EDITOR%, default 'code')
  vcpkg import <pkg>              Import a pre-built library
  vcpkg create <pkg> <url> [archivename]
                                  Create a new package
  vcpkg owns <pat>                Search for files in installed packages
  vcpkg depend-info <pkg>...      Display a list of dependencies for packages
  vcpkg env                       Creates a clean shell environment for development or compiling
  vcpkg version                   Display version information
  vcpkg contact                   Display contact information to send feedback
  ...

>vcpkg search assimp
>vcpkg search | findstr assimp
assimp               5.0.1            The Open Asset import library
magnum-plugins[assimpimporter]        AssimpImporter plugin

>vcpkg search | findstr glu
aws-sdk-cpp[glue]                     C++ SDK for the AWS glue service
freeglut             3.2.1-4          Open source implementation of GLUT with source and binary backwards compatibil...
glui                 2019-11-30       GLUI is a GLUT-based C++ user interface library
mathgl[glut]                          glut module

>vcpkg install assimp:
Computing installation plan...
The following packages will be built and installed:
    assimp[core]:x86-windows
  * minizip[core]:x86-windows
  * rapidjson[core]:x86-windows
  * zlib[core]:x86-windows
Additional packages (*) will be modified to complete this operation.
Warning: The following VS instances are excluded because the English language pack is unavailable.
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
Please install the English language pack.

安装具有 Cuda 加速的 opencv 库:

vcpkg search opencv
vcpkg install opencv[cuda]:x64-windows 
vcpkg --triplet x64-windows install opencv[cuda]

支持的架构组合查询:

>vcpkg help triplet
VCPKG built-in triplets VCPKG community triplets
arm-uwp arm-ios
arm64-windows arm-mingw
x64-linux arm-windows
x64-osx arm64-ios
x64-uwp arm64-mingw
x64-windows-static arm64-uwp
x64-windows arm64-windows-static
x86-windows wasm32-emscripten
x64-ios
x64-mingw
x64-osx-dynamic
x64-windows-static-md
x86-ios
x86-mingw
x86-uwp
x86-windows-static-md
x86-windows-static

作为 MinGW 的用户,我非愿意看到 triplet 列表中有 x64-mingw 和 x86-mingw 的身影。

可以设置默认的架构:

VCPKG_DEFAULT_TRIPLET=x64-windows

vcpkg 的 Triplet files 是用来记录和库相关的 OS、CPU、Compiler、Runtime 等信息的文件,它包含了编译模块时使用的工具链。

安装第三方的 MinGW 架构依赖库时出现错误:

>vcpkg install assimp:x64-mingw
Computing installation plan...
The following packages will be built and installed:
    assimp[core]:x64-mingw
  * minizip[core]:x64-mingw
  * rapidjson[core]:x64-mingw
  * zlib[core]:x64-mingw
Additional packages (*) will be modified to complete this operation.
Unable to determine toolchain to use for triplet x64-mingw with CMAKE_SYSTEM_NAME MinGW

提示信息表明,vcpkg 无法从 CMAKE_SYSTEM_NAME 指定的 x64-mingw 架构确定需要用到的工具链:

triplets/community/x64-mingw.cmake

这个问题有点恶心,因为 vcpkg 的源代码忽略了 MinGW,解决方法是修改 build.cpp 重新编译 vcpkg:

diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp
index c61c6b7..d7c78aa 100644
--- a/toolsrc/src/vcpkg/build.cpp
+++ b/toolsrc/src/vcpkg/build.cpp
@@ -558,6 +558,10 @@ namespace vcpkg::Build
         else if (cmake_system_name == "Android")
         {
             return m_paths.scripts / fs::u8path("toolchains/android.cmake");
+        }
+        else if (cmake_system_name == "MinGW")
+        {
+            return m_paths.scripts / fs::u8path("toolchains/mingw.cmake");
         }
         else if (cmake_system_name.empty() || cmake_system_name == "Windows" || cmake_system_name == "WindowsStore")
         {
--

参考 https://github.com/microsoft/vcpkg/issues/12065

安装好依赖模块后,接着是将 vcpkg 集成到项目或进行全局集成:

>vcpkg integrate install
Applied user-wide integration for this vcpkg root.

All MSBuild C++ projects can now #include any installed libraries.
Linking will be handled automatically.
Installing new libraries will make them instantly available.

CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake"

使用 CMake 的编译项目中使用 vcpkg 安装的库,最佳方式指定 CMake (Toolchain File) 工具链文件 scripts/buildsystems/vcpkg.cmake,让 find_package() 命令发现安装的库。

要使用这个文件,通过命令参数传入 CMake 即可:

cmake .. -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake (Linux/MacOS)
cmake .. -DCMAKE_TOOLCHAIN_FILE=vcpkg\scripts\buildsystems\vcpkg.cmake (Windows)

再比如,如果要用 VS2017 编译器,输入下面命令即可:

cmake .. -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake -G "Visual Studio 15 2017 Win64"

还有一种方法,直接在 CMakeLists.txt 文件中指定 CMAKE_TOOLCHAIN_FILE 变量,即:

set(CMAKE_TOOLCHAIN_FILE "D:\vcpkg\scripts\buildsystems\vcpkg.cmake")
project(PROJECT_NAME)

注意,要在 project() 命令之前设置。另外,类似 CMAKE_SYSTEM_NAME,CMAKE_C_COMPILER 等这些变量都要在 project()命令之前设定,不然 CMake 会按照默认的设置处理。

如果电脑中没有安装 cmake,vcpkg 会自动下载 cmake portable 版本。

集成安装:

命令 说明
vcpkg integrate install 为所有用户集成安装依赖包
vcpkg integrate remove 为所有用户移除集成安装
vcpkg integrate project 为独立 VS 项目创建 nuget 包引用
vcpkg integrate powershell 为 PowerShell Tab 自动完成集成
---------------------------- ---------------------------------

依赖包的管理:

vcpkg.exe remove assimp
vcpkg.exe remove --outdated
vcpkg.exe list
vcpkg.exe export assimp --7zip

导出时必须指定导出的包格式。vcpkg支持5种导出包格式,有:

参数 格式
–raw 以不打包的目录格式导出
–nuget 以 nuget 包形式导出
–ifw 基于 IFW 的安装包
–zip 以 zip 压缩包形式导出
–7zip 以 7z 压缩包形式导出
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353