有经验的程序员,不论所用何种语言,对代码依赖都不会陌生。代码无论是依赖于内部依赖关系,还是依赖于外部库或框架,通常都不会孤立运行。代码的重复使用,亦即使用现有代码的做法,是提升开发效率的重要工具。不过,对代码的重复使用会导致产生一种依赖项。遗憾的是,依赖项都有其消极一面。它们很难管理。

什么是依赖管理?

依赖管理是一种多层面进程,负责构建和维护从代码库调用的外部实体列表。遗憾的是,这项工作并不像听起来那么容易。首当其冲的问题就是,你必须确保引入的依赖项都是正确的。然后,你还需要考虑如何处理依赖冲突。

维护依赖列表是一件需要效率和可靠性的事,因而这项工作应尽可能实现自动化。同时,对于解决依赖冲突等类似任务,还需要进行人工干预。为了辅助实现这个过程,开发人员会利用依赖管理工具。

依赖管理工具

依赖管理工具不仅负责构建依赖列表,还负责及时报告最新的更新。举例而言,新版本的库一经发布,代码库就可能受到影响,这时工具就需要对此进行识别和处理。

依赖管理工具需要密切关注动态链接库等事项,要定期识别和解决可能出现的任何问题。出现问题是常事,例如将不同依赖项依赖于同一工件的不同版本时,就会引发问题。如果依赖项“A”依赖于特定版本的依赖项“C”,且与此同时,依赖项“B”却依赖于依赖项“C”的另一版本,那么就会出现依赖冲突,需要解决。

依赖管理中的一个常见问题是如何使依赖项保持最新状态。理想情况下,依赖项会随时更新,以便从最新更改中受益。即便是稳定型产品,虽然利用最新功能并非必要,但实施最新错误修复和其他改进仍很重要。然而这种情况并不多见。事实上,更新被忽略、进程有所拖延是常有的事。

使用人工操作进程,工作复杂而耗时,这就是为什么依赖管理工具要致力于提升进程的自动化水平。这也提示我们一定要记住,通常情况下,解决依赖冲突仍然需要人工干预。

不论所用的编程语言是什么,依赖管理工具在任何软件开发环境中都很常见。例如,你会发现 Maven 和 Gradle 在 Java 程序员中十分流行,而 pip 却在 Python 圈子更受欢迎,还有 npm 和 Yarn,一般用于 Node.js,而 Composer 更适用于 PHP 项目。即使是 Rust 这门十分年轻的语言,也从早期阶段就开始将 Cargo 作为包管理的有效工具。对于以上和其他一些语言,包管理工具还存在无数种,但 C++ 依赖管理工具却绝对是稀有品种。

为什么用 C++ 进行依赖管理很难?

如果要资深 C++ 开发人员说出对使用依赖项有什么认识,那一定是 C++ 依赖管理真的很难做。事实上,C++ 并不像其他语言,它没有标准或占主导地位的包管理器。这造成的结果就是,C++ 依赖管理要么不值一提,例如只能凭借在文件中复制粘贴这样的方法,毫无自动管理可言,要么需要靠 APT 等类似的操作系统特定工具来维持。

由于缺乏规范或标准而变得复杂

C/C++ 生态系统庞大、成熟且相当复杂。想想大量现存的第三方库,包括那些由开源社区支持的库,再想想这些库随着时间的推移,会跨平台、跨操作系统甚至是随语言版本而发展,这些都会导致生态系统变得支离破碎,而依赖管理在其中也远远不像原本那样省时。构建系统各有不同,例如每个系统都有自己的特性和选项可供选择。处理不同的构建系统本身就很难,然而这还只是难题的一部分。

可移植性

C++ 依赖管理很难用的另一大原因是,源码可移植,而二进制文件却不行。举例来说,C++ 并不像 Java 那样可以使用 JVM 在不同平台执行编译代码。使用 C++ 时,库在不同平台均可用,这意味着在管理依赖项时,如果需要维护可移植性,则不同平台的相同库就全部都需要维护。为不同平台保留不同的工件或许是一个办法,但如果需要为每个架构和操作系统都存储预编译二进制文件,则 ABI 兼容性所需的组合数量又会非常庞大(在某些情况下还不止如此,根据编译标志,同一操作系统的 ABI 各有不同)。

依赖管理工具会使用不同的技术处理可移植性问题。例如下方提到的 Conan C/C++ 包管理器,它使用分散系统为多二进制包维护同一存储库系统。而 Cargo 作为 Rust 包管理器,其方法是在 crates.io 中检索依赖项,crates.io 是一个由社区维护的中央包注册表。

应如何管理 C++ 依赖项?

开发车间会使用各种不同的方法来进行 C++ 依赖管理,包括手动下载、传输或复制文件、编写或采用更复杂的工具等,这些对任务执行均有帮助。一些程序员会选择使用操作系统特定的工具,例如 APT,而其他程序员则会采用更偏人工的方法。

对于那些使用偏人工方法的人,几乎无法绕开的问题就是效率偏低以及容易出错,这时就需要人工维护依赖图以避免版本冲突。既然我们致力于在开发和处理时间上提高效率,那么建议参考一些现存的热门 C++ 依赖管理系统。

现有工具

现有几种 C++ 依赖管理工具人们正在积极开发,其中每一种都有其功能、优势及不足。比较流行的特征包括与 Visual Studio 等 CMake 和 IDE 进行集成、跨平台支持以及使用简便。虽然也有下面提到的 Buckaroo、Hunter 和 Build2 等其他选择,但目前两大最常用的成熟工具仍是 Conan 和 vcpkg。

Conan C/C++ 包管理器是一个开源项目,它使用了灵活的分散式客户服务器模型来存储供客户检索的包。该工具支持多平台和工具集,允许存储源码和二进制文件,并且还拥有一套丰富的选项,可用于为不同开发环境微调进程。它的文档编写质量很高,背后还有一个活跃的社区,其中包括数千公司和上万名开发人员。目前,ConanCenter 存储库中共有 2,611 个包。

vcpkg 包管理器是一个来自 Microsoft 的开源、跨平台依赖管理器。它使用简便,用于在开源和私人存储库中检索和管理库,且与 Visual Studio 和 Visual Studio Code 进行了集成。它的文档质量高,适合新手,文档中还包含了入门指南一节供参考。Vcpkg 在检索特定版本的库时,所使用的方法是基于在 Vcpkg 存储库中检索相关分支,这种方法在某些人看来笨拙而过于技术化(没有任何声明性的简单语法可实现这一点)。目前,vcpkg 存储库中共有 1,822 个包。

Buckaroo 是一种开源解决方案,自称是 C++ 和 Friends 包管理器。它的文档中包含入门指南、如何与常见 IDE 集成的相关提示,以及一些其他提示和技巧。Buckaroo 不像其他依赖管理器可完全支持 CMake 构建系统,它默认采用 Buck 构建系统,对 CMake 仅提供有限支持。Buck 是一种由 Facebook 开发的构建系统,它鼓励使用小模块,但并不支持对二进制依赖项进行打包。依赖项可以直接从 GitHub、BitBucket 和 GitLab 中拉取。

Hunter 是一种支持多平台的依赖管理器,可用于 C/C++ 和其他语言。它旨在使用 CMake 构建系统进行包管理,同时也能够使用自定义模板支持非 CMake 包。它的文档中包含快速入门指南,以及如何与常见 IDE 集成的说明。Hunter 的主要优势在于它仅需要 CMake,因此对开发人员来说比较透明。用户对于 Hunter 的主要意见是,它的一切都构建自源码,使用时过于耗时。

Build2 自身即是一种构建系统。它能够提供构建部分,也能提供包管理部分。它的文档中包含安装和入门指南说明,以及用例。其优势在于,作为一个包含构建和包管理部分的完整工具链,它需要的仅仅是 C++ 编译器而已。另一方面,许多 C++ 开发人员并不会为了获取包管理功能而考虑迁移到其他构建系统,而且,build2 首先是一个无法与 make、ninja 或 CMake 集成或兼容的构建系统。因此你不得不迁移到 build2,将其作为自己的构建系统。build2 所维护的存储库位于 https://cppget.org,目前其中仅有 95 个托管包,这个数量并不大。

最佳做法

高效且运行合理的依赖管理应做到对开发人员基本透明。当然,不可避免地会出现错误并且需要一些调整,但只要遵循一组最佳做法,这些问题都可以最小化。

其中,有几条经验非常重要,首要的就是构建应保持稳定,并在各平台和操作系统间保持一致。如果构建在某一个机器上运行,那么它在不同环境中的其他机器上也应以同样方式构建和运行。也就是说,对依赖项进行合理维护的依据,不仅有版本,还有平台。尽管与依赖管理并不直接相关,开发人员仍须记住,如果在多环境中进行构建,即便代码一模一样,也要在每个环境中逐一对构建成果进行测试。

另外,依赖项应尽可能地重复使用,以使依赖图更加精简。在所做工作或赖以运行的功能方面,项目中的组件很少是独一无二的。因此,要确定已具备了什么,避免将事情不必要地扩大或复杂化。关于此有一个非常简单的例子,即通常来说,不需要在单个项目中依赖于两个不同的日志库。也就是说,对依赖管理的需要处于首位,因为环境总是复杂的。

最后,尽可能不要手动操作。

结论

依赖管理是一组工具和技术,用于识别和解决与代码库中的依赖项相关的问题。依赖项的形式多种多样,包括库和框架,且存在于各种从大到小、从概念验证到较成熟、跨行业、跨编码技术水平以及跨编程语言的不同项目当中。

相比其他语言的依赖管理,C++ 依赖管理难度更大。这既是因为目前缺乏标准,存在可移植性问题,全球代码库愈发成熟,也是因为 C++ 这种语言本身就比较复杂。解决问题的方法有好有坏,不过幸运的是,有几种工具可以帮助你更好地执行任务。在这些工具中,最普遍的莫过于 Conan 和 vcpkg,如果愿意,也可以尝试一些其他工具。毫无疑问,不论选择了何种包或工具集,都能够减少过去手动复制粘贴的麻烦(对其他人来说可能没过去多久)

点击获取试用License!

关于 C++ 依赖管理相关推荐

  1. Gradle系列教程之依赖管理

    这一章我将介绍Gradle对依赖管理的强大支持,学习依赖分组和定位不同类型仓库.依赖管理看起来很容易,但是当出现依赖解析冲突时就会很棘手,复杂的依赖关系可能导致构建中依赖一个库的多个版本.Gradle ...

  2. 用CocoaPods做iOS程序的依赖管理

    CocoaPods 简介 每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm.随着 iOS 开发者的增多,业界也出现了为 iOS 程序提供 ...

  3. [笔记]解决m2eclipse给项目添加maven依赖管理时可能不给项目的build path...

    为什么80%的码农都做不了架构师?>>>    解决办法:在m2eclipse提供的菜单里关闭项目的Maven依赖管理,然后再启动Maven的依赖管理!!! 检查:1)查看项目的.c ...

  4. Composer PHP依赖管理

    对于现代语言而言,包管理器基本上是标配.Java有Maven,Python有pip,Ruby有gem,Nodejs有npm.PHP的则是PEAR,不过PEAR坑不少: 依赖处理容易出问题 配置非常复杂 ...

  5. nodejs Yarn替代npm的包管理——快速、安全、可靠性高的依赖管理

    Yarn能帮你解决的五件事 转自: http://www.qingpingshan.com/jb/javascript/185590.html 长话短说(TL;DR):在 JavaScript 领域有 ...

  6. Gradle之依赖管理

    Gradle之依赖管理 泡在网上的日子 / 文 发表于2015-01-29 16:12 第8824次阅读 Gradle,Android Studio 2 编辑推荐:稀土掘金,这是一个针对技术开发者的一 ...

  7. Gradle for Android 第三篇( 依赖管理 )

    Gradle for Android 第三篇( 依赖管理 ) 依赖管理是Gradle最闪耀的地方,最好的情景是,你仅仅只需添加一行代码在你的build文件,Gradle会自动从远程仓库为你下载相关的j ...

  8. 【Groovy】Gradle 构建工具 ( 自动下载并配置构建环境 | 提供 API 扩展与开发工具集成 | 内置 Maven 和 Ivy 依赖管理 | 使用 Groovy 编写构建脚本 )

    文章目录 一.Gradle 自动下载并配置构建环境 二.Gradle 提供 API 扩展与开发工具集成 三.Gradle 内置 Maven 和 Ivy 依赖管理 四.Gradle 使用 Groovy ...

  9. 【Groovy】构建工具 ( 构建工具引入 | Gradle 构建工具作用 | 传统的依赖管理 )

    文章目录 一.构建工具引入 二.Gradle 构建工具作用 三.传统的依赖管理 一.构建工具引入 构建工具 用于 管理代码项目的 依赖 , 编译 , 测试 , 发布 周期 ; 常见的构建工具 : An ...

  10. 007_Maven依赖管理

    1. Maven一个核心的特性就是依赖管理.当我们处理多模块的项目(包含成百上千个模块或者子项目), 模块间的依赖关系就变得非常复杂, 管理也变得很困难.针对此种情形, Maven提供了一种高度控制的 ...

最新文章

  1. MyISAM与InnoDB区别
  2. objective-c对NSArray的学习
  3. vue 双向数据绑定的实现学习(一)
  4. 牛客 - Shortest Common Non-Subsequence(dp+序列自动机)
  5. win7将 esc与 capslock 互换
  6. android 获取程序,Android获取桌面应用程序
  7. d3.js 搭建 d3-force-directed-graph 例子
  8. 从Oracle向PPAS移行不成功时的处理
  9. -bash: ifconfig: 未找到命令
  10. 跨线程操作无效:从创建该线程的线程以外的线程访问控件
  11. NetSetMan v5.0.5特别版
  12. Pandas实战-Series的方法
  13. 雾霾天气下运动目标检测技术MATLAB
  14. Visio 画流图 程序流图 斜线
  15. matlab投资组合权重,马科维茨投资组合理论(均方模型)学习笔记――基于Matlab(四)...
  16. Anaconda下载simpleITK包和pytorch包
  17. Springboot企业资源管理信息系统kvonv计算机毕业设计-课程设计-期末作业-毕设程序代做
  18. java做一个简单的文件管理器
  19. 程序员的小幽默:让你笑到肚子痛的搞笑动图
  20. jquery设置checkbox选中和未选中的方式

热门文章

  1. 重磅!道翰天琼破解认知智能核心秘密三大核心技术,机器人大脑API平台。
  2. 学习node.js前所需储备知识
  3. 如何实现电脑文件的自动备份?
  4. TCP/IP卷一:87---TCP拥塞控制之(对标准算法的改进:NewReno、采用选择确认机制、转发确认(FACK)和速率减半、限制传输、拥塞窗口校验)
  5. 在IDEA中手动创建基于Maven的Servlet项目
  6. qt平台集成google拼音中文输入法
  7. 你是否愿意用华为鸿蒙系统,如果华为改用自研的“鸿蒙”系统,你是否愿意尝试?...
  8. Python字典嵌套
  9. 《明日世界》电驴下载放出
  10. 计算机基础——Windows 7操作系统