速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

我们是否需要通用的 C++ 软件包管理器?

  • 2017-12-07
  • 本文字数:2916 字

    阅读完需:约 10 分钟

C++ 在软件包管理器上并不存在短板。当前有大量的工具可用,例如 buckaroo cget conan conda cpm cppan hunter 等等,不胜枚举。

可是,如此之多的软件包管理器,反而让开源软件作者难以抉择。或许大家会迫切需要能有一种通用的软件包管理器,但事实上,由于 C++ 尚不具有通用的构建系统,因此看上去也不会存在通用的软件包管理。此外,各种软件包管理器所关注的方面各不相同,例如与 CMake 的直接集成、可重复构建、共享二进制服务器、解决可满足性依赖等。

我建议,不要把注意力都放在如何整合所有的软件包管理器,并形成一种通用的管理器,而是应该尝试如何创建一种标准化方法,理解依赖关系并实现软件包的安装。C++ 软件的开发者只需要符合一种简单的格式,就可以支持多种软件包管理器。这种做法也使开发者可以将注意力集中在不同软件包管理器的独有特性上,而不是将放在如何转换为新格式可使用的软件库上。我们的标准化工作分为两个部分,分别是软件包规范和工具链规范。

任何一个标准化工作想要取得成功,就应构建于当前的实践之上。当前的软件包并没有通用的依赖关系定义方法,因此我们需要在软件包管理器间做一些协同。但是,即便是在不同的构建工具之间,还是存在通用的软件库(或软件包)构建和安装方法,并且很多软件包管理器是构建在同样的工作流上的。C++ 需要的是一种通用格式,将软件包需求提供给不同的软件包管理工具。

本文中,我将探讨具体的标准化工作。

使用需求(Usage Requirement)

当前,软件包管理器的主要工作是安装依赖关系,并决定所安装的版本。提供使用需求并不是软件包管理器的工作。一方面,软件包管理器并不知道使用需求。虽然它可以从所用的依赖关系中做出推测,但推测的内容并不完整。另一方面,构建脚本的确知道使用需求,因此在安装时应使用构建脚本,这样可保持构建脚本和软件包管理器间的不耦合关系。

现在,构建脚本要实现将使用需求告知软件包管理器(这可以通过在构建中的一些查询步骤实现),但这并非构建脚本的当前工作方式。当前,构建脚本生成软件包配置文件,该配置文件进而被下游的构建脚本使用。配置文件有两种格式,即 CMake pkgconfig 。鉴于使用需求超出了软件包管理器的范畴,在此我们将不探讨它的具体内容。但毫无疑问,一种明显的解决方案就是采用依赖于构建的 pkgconfig 文件。

软件包规范

软件包规范是描述软件包内容细节的文件。其中将包括如下域:

  • 软件包名。
  • 描述。
  • 版本。
  • 可能的构建模式,即指定构建软件包所使用的构建系统。相比于依赖软件包管理器去推理构建系统,指定构建模式的方式更好,因为前者时常是模棱两可的。
  • 运行软件包的需求列表,其中包括版本限制。还可以指定需求只是用于构建,或只是用于测试。
  • 将需求中的软件包名映射到一个 URL(或者可能是一个指向软件包的 URL,软件包中包括这些映射)。对于不具有软件包索引的软件包管理器,或是需要可重复构建的软件包管理器,这非常有用。
  • 可能与该软件包具有冲突的软件包列表。
  • 该软件包可替换的软件包列表。

在理想情况下,该规范将存储在软件库本身,可能存储在最顶层。并且为实现快速的访问,软件包管理器还应索引这些文件。

此外,并非所有软件库都可提供这些软件包文件。因此我们需要有一种方式,非侵入式(non-intrusive)地提供软件包文件。在这种情况下,规范中还需指定如下域:

  • 下载软件包的 URL。
  • 可能会使用的构建脚本。在没有提供构建脚本时,或是原始的构建脚本并不充分时,可以使用在此指定的构建脚本。

特别需要指出的是,一些软件包可在所有软件包管理器上使用,非侵入格式可为这些软件包提供一种标准的定义方式。当前,每个软件包管理器都具有自己的格式,它们会重新实现自身的软件包“食谱”。

我们可使用类似于 pkgconfig 的可用格式定义这些信息。这时,其中可以进一步包括 pkgconfig 文件中使用的变量定义和替换。为支持对可选依赖非常有用的条件定义,该格式需要做进一步的扩展。下面给出的例子中展示了这样的软件包文件格式:

复制代码
Name: foo
Description: A foo library
Version: 1.0
Requires:
zlib > 1.5
Dependencies:
zlib = http://zlib.net/zlib-1.2.11.tar.gz

现在的问题是,如何解决软件包文件和构建系统之间的复制问题,因为构建中需要再次请求依赖关系。我希望在将来,构建系统可以读取同一软件包文件,以了解要搜索的依赖关系。如果该问题可以被标准化,那么这种集成是非常有可能的。

工具链规范

在软件包管理器知道了去哪里找到依赖关系后,下一步就是构建和安装软件包。尽管我们可以尽量创建标准的构建脚本,但是有一些构建过于复杂,以至于无法处理每个给出的构建需求。我们知道,CMake 正力图成为一种高层的构建脚本,可生成其它的构建脚本。但即便如此,依然是不够的。软件作者此时会转而使用其它的构建工具。

我们并非力图去做标准化,并给出大而全的构建脚本,而是关注如何实现一种调用构建系统的标准方式,这更为简单。使用 configure、build 和 install 是调用构建的通用方式,这非常易于标准化。这样,软件包管理器的关键部分,是如何告知构建系统所使用的构建“环境”或工具链。当前,每个构建系统都有不同的格式,例如 CMake 使用的是工具链文件,Meson 使用了交叉文件和环境变量,boost 构建使用了一个 user-config.jam 文件,makefile 和 autotools 使用的是一系列环境变量。

因此,我们需要提出一种描述工具链的标准化格式,其中应该包括:

  • 所使用的编译器。
  • 编译器标志。
  • 链接器标志。
  • 系统。
  • 交叉编译。
  • 构建类型(debug 或 release)。
  • 软件库类型(共享库还是静态库)。
  • 头文件目录。
  • 预处理定义。
  • 编译中使用的选项。
  • 链接共享、静态或可执行中使用的选项。
  • 寻找依赖关系的路径列表。
  • 交叉编译中使用的根路径(即 sysroots)。

这里可以使用很简单的格式,例如“变量 = 赋值”的形式。进一步,每个变量应都可在软件包文件中访问,这样可基于工具链确定可选依赖关系。

在整个工具链和构建系统中,标准化的工具链有助于实现一致的构建和安装。也有助于确保构建系统足以处理软件包管理器所需的构建场景。

下面给出一个用于 mingw 工具链的文件:

复制代码
system = windows
cross_compile = true
c_compiler = x86_64-w64-mingw32-gcc
cxx_compiler = x86_64-w64-mingw32-g++
rc_compiler = x86_64-w64-mingw32-windres
root_path = /usr/x86_64-w64-mingw32
emulator = wine
install_prefix = ~/packages
prefix_path = ~/packages

一旦构建系统支持工具链文件,这时编写包装器就是一件相对简化的事情,并由包装器实现标准化格式转换为原生的构建工具。当然,并非每个选项都能被所有的构建工具理解。因此,如果能向用户给出警告,说明某个选项不被某个构建工具所支持,这将十分有帮助的。

进一步考虑

作为 cget 软件包管理器的作者,我也提出了自己的软件包依赖关系描述格式。但是标准化的 C++ 软件包规范,有助于实现在不同的构建和软件包工具间的协同和互操作。此外,如果力图去构建一种通用构建工具和软件包管理器(例如 build2 ),这无疑将是一场艰苦的战斗,并人们也不会很快地采用该工具。因此,我们聚焦于如何尽可能地实现现有实践的标准化,这样用户也不必重写他们的构建文件。

查看英文原文: Does C++ need a universal package manager?

感谢雨多田光对本文的审校。

2017-12-07 17:255990
用户头像

发布了 391 篇内容, 共 136.5 次阅读, 收获喜欢 256 次。

关注

评论

发布
暂无评论
发现更多内容

grub内核启动参数(kernel command-line parameters)

百度搜索:蓝易云

cdr 2023 mac破解版 附激活码 CorelDRAW Graphics Suite 2023中文安装包

Rose

大型复杂项目管理中传统与敏捷的有效结合

爱吃小舅的鱼

项目管理 敏捷开发

Ubuntu20.04升级openssh9.4(源码升级)

百度搜索:蓝易云

一个例子理解C++面向对象——构造函数、虚函数、抽象基类

百度搜索:蓝易云

.NET 9 AOT的突破 - 支持老旧Win7与XP环境

沙漠尽头的狼

Nginx性能优化的几个方法

江南一点雨

探索新机遇:当跨境外贸独立站挑战重重,反向海淘代购模式成为新蓝海

代码忍者

反向海淘

Steinberg Dorico Pro for Mac 破解补丁 及安装包

Rose

技术与市场预测不确定性:企业应对指南

爱吃小舅的鱼

技术与市场预测不确定性 应对策略

前端使用json-server快速搭建服务

百度搜索:蓝易云

字节码文件解剖

不在线第一只蜗牛

3D摄影棚布光工具 Set A Light 3D Studio for Mac 永久版

Rose

实验室辅助管理系统(源码+文档+部署+讲解)

深圳亥时科技

从方言对话这枚“落子”,看AI手机“棋局”的尴尬赛点

脑极体

AI

Ubuntu 12.04 LTS查看网关地址方法汇总

百度搜索:蓝易云

基于微服务SDK框架与JavaAgent技术,低成本助力应用高效发布

华为云开发者联盟

微服务 灰度发布 java-agent Java Chassis 3

大数据集群搭建,CDH让你事半功倍!

敏捷调度TASKCTL

cloudera CDH 集群搭建 CDH 大数据 Hadoop 集群迁移

Acrobat Pro DC 2024,打造顶级文档处理平台

Rose

DataWorks:新一代 Data+AI 数据开发与数据治理平台演进

阿里云大数据AI技术

大数据 Serverless 云原生 Dataworks

商协会管理系统(源码+文档+部署+讲解)

深圳亥时科技

AnyToISO Pro mac破解版:ISO镜像文件制作工具

Rose

EndNote 21 for mac 授权破解版 EndNote下载安装包

Rose

CrossOver 24 for Mac(windows 虚拟机) 附激活补丁

Rose

强大防护软件 Deep Freeze(冰点还原精灵),释放电脑潜能!

Rose

GreptimeDB vs. SQLite —— 高通 8155 平台上的性能对比报告

Greptime 格睿科技

sqlite 数据库 边缘计算 嵌入式 性能报告

我的新书出版啦!和大家聊聊写书的酸甜苦辣

码哥字节

数据库 nosql 写作 redis 精讲 程序员 java

管理上层期望:与干系人保持同步

爱吃小舅的鱼

管理上层期望

一文读懂什么是RAG,如何搭建多模态RAG降低大模型幻觉

Zilliz

Milvus LLM 大模型幻觉 多模态rag RAG搭建

功能强大、简单易用的视频下载工具 4K Video Downloader for mac

Rose

Omi录屏专家 Screen Recorder by Omi Mac v1.3.9激活版

Rose

我们是否需要通用的C++软件包管理器?_语言 & 开发_Paul Fultz II_InfoQ精选文章