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 压缩包形式导出 |