vcpkg简介
vcpkg要解决什么问题
C++语言的历史非常悠久,导致其在某些方面的使用体验非常差,比如三方库的依赖。
比如要引入一个skia库,我们大概有以下办法:
- 源码集成,会有几个问题
- 但Skia的构建是GN组织的,如果主工程是CMake组织的,则存在适配问题
- 每次Clean之后要构建Skia的源码,比较耗时
- Skia的构建可能又有一些依赖,构建成功率无法保证
- 制品集成,也会有一些问题
- 如果Skia频繁更新,那么制品也要频繁更新
- 如果我们的工程涉及多个平台,那么制品的构建工作量也不少(当然,可以搭建流水线生成制品)
- 制品保存在哪(项目OR云端?),如何拉取(Git或者CMake FetchContent)
另外,每个项目对于Skia使用的功能不同,Skia会在构建期间通过构建参数控制。所以,制品集成往往很难迁移和共享。
想想我们用Java有Maven、Python有pip、Dart有pub,似乎没这么多坑?
确实,C++的依赖引入之所以如此复杂,个人认为大概有几个原因
- C++出现的非常早,当前还没有成体系的包管理和依赖管理的概念(比如,我们构建Android源码时,还要Ubuntu系统通过apt-get install安装一些依赖,这种方式就是一种古老的方式流传下来的),而现代编程语言一开始就有相关的设计
- 接上一点,C++因为一开始只有语言而无生态,就导致野路子非常多,CMake、QMake、GN、meson等各种构建系统,互相不服。而Java这些语言则有官方一锤定音。结果是,三方库没有一套通用的构建规范。
- C++的应用场景也更加底层,面向硬件,而Java、Python之类本身就是跨平台的,所以构建自然会一致些
之所以讨论以上这些,是为了指明理解vcpkg的角度:vcpkg不是什么横空出世的玩意,他是为了解决C++没有现代化包管理工具的问题。
包/依赖管理该有的,vcpkg都有,比如:
- Understanding features in vcpkg | Microsoft Learn:通过 feature可以选择集成三方库的部分能力
- 版本的管理
- 依赖、间接依赖和依赖冲突的处理策略等
如何使用vcpkg
我觉得没有必要专门为vcpkg写使用文档,因为其官方文档足够好了:
但是,对于vcpkg一些功能的实现和一些常见问题的解决,则需要一些经验和技巧,这也是后面将重点输出的:
- 实践
- 源码