课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
对于不同的编程软件来说都有符合自己的一些操作软件来提高编程效率以及其他的管理应急措施。
下面我们就通过对c++的软件管理器来作为案例分析介绍一下都有哪些作用的。
使用需求(UsageRequirement)
当前,软件包管理器的主要工作是安装依赖关系,并决定所安装的版本。提供使用需求并不是软件包管理器的工作。一方面,软件包管理器并不知道使用需求。虽然它可以从所用的依赖关系中做出推测,但推测的内容并不完整。另一方面,构建脚本的确知道使用需求,因此在安装时应使用构建脚本,这样可保持构建脚本和软件包管理器间的不耦合关系。
现在,构建脚本要实现将使用需求告知软件包管理器(这可以通过在构建中的一些查询步骤实现),但这并非构建脚本的当前工作方式。当前,构建脚本生成软件包配置文件,该配置文件进而被下游的构建脚本使用。配置文件有两种格式,即CMake和pkgconfig。鉴于使用需求超出了软件包管理器的范畴,在此我们将不探讨它的具体内容。但毫无疑问,一种明显的解决方案就是采用依赖于构建的pkgconfig文件。
软件包规范
软件包规范是描述软件包内容细节的文件。其中将包括如下域:
软件包名。
描述。
版本。
可能的构建模式,即指定构建软件包所使用的构建系统。相比于依赖软件包管理器去推理构建系统,指定构建模式的方式更好,因为前者时常是模棱两可的。
运行软件包的需求列表,其中包括版本限制。还可以指定需求只是用于构建,或只是用于测试。
将需求中的软件包名映射到一个URL(或者可能是一个指向软件包的URL,软件包中包括这些映射)。对于不具有软件包索引的软件包管理器,或是需要可重复构建的软件包管理器,这非常有用。
可能与该软件包具有冲突的软件包列表。
该软件包可替换的软件包列表。
在理想情况下,该规范将存储在软件库本身,可能存储在最顶层。并且为实现快速的访问,软件包管理器还应索引这些文件。
此外,并非所有软件库都可提供这些软件包文件。因此我们需要有一种方式,非侵入式(non-intrusive)地提供软件包文件。在这种情况下,规范中还需指定如下域:
下载软件包的URL。
可能会使用的构建脚本。在没有提供构建脚本时,或是原始的构建脚本并不充分时,可以使用在此指定的构建脚本。
特别需要指出的是,一些软件包可在所有软件包管理器上使用,非侵入格式可为这些软件包提供一种标准的定义方式。当前,每个软件包管理器都具有自己的格式,它们会重新实现自身的软件包“食谱”。
我们可使用类似于pkgconfig的可用格式定义这些信息。这时,其中可以进一步包括pkgconfig文件中使用的变量定义和替换。为支持对可选依赖非常有用的条件定义,该格式需要做进一步的扩展。
现在的问题是,如何解决软件包文件和构建系统之间的复制问题,因为构建中需要再次请求依赖关系。我希望在将来,构建系统可以读取同一软件包文件,以了解要搜索的依赖关系。如果该问题可以被标准化,那么这种集成是非常有可能的。
工具链规范
在软件包管理器知道了去哪里找到依赖关系后,下一步就是构建和安装软件包。尽管我们可以尽量创建标准的构建脚本,但是有一些构建过于复杂,以至于无法处理每个给出的构建需求。我们知道,CMake正力图成为一种高层的构建脚本,可生成其它的构建脚本。但即便如此,依然是不够的。软件作者此时会转而使用其它的构建工具。
我们并非力图去做标准化,并给出大而全的构建脚本,而是关注如何实现一种调用构建系统的标准方式,这更为简单。使用configure、build和install是调用构建的通用方式,这非常易于标准化。这样,软件包管理器的关键部分,是如何告知构建系统所使用的构建“环境”或工具链。当前,每个构建系统都有不同的格式,例如CMake使用的是工具链文件,Meson使用了交叉文件和环境变量,boost构建使用了一个user-config.jam文件,makefile和autotools使用的是一系列环境变量。
因此,我们需要提出一种描述工具链的标准化格式,其中应该包括:
所使用的编译器。
编译器标志。
链接器标志。
系统。
交叉编译。
构建类型(debug或release)。
软件库类型(共享库还是静态库)。
头文件目录。
预处理定义。
编译中使用的选项。
链接共享、静态或可执行中使用的选项。
寻找依赖关系的路径列表。
交叉编译中使用的根路径(即sysroots)。
这里可以使用很简单的格式,例如“变量=赋值”的形式。进一步,每个变量应都可在软件包文件中访问,这样可基于工具链确定可选依赖关系。
在整个工具链和构建系统中,标准化的工具链有助于实现一致的构建和安装。也有助于确保构建系统足以处理软件包管理器所需的构建场景。
一旦构建系统支持工具链文件,这时编写包装器就是一件相对简化的事情,并由包装器实现标准化格式转换为原生的构建工具。当然,并非每个选项都能被所有的构建工具理解。因此,如果能向用户给出警告,说明某个选项不被某个构建工具所支持,这将十分有帮助的。
进一步考虑
作为cget软件包管理器的作者,我也提出了自己的软件包依赖关系描述格式。但是标准化的C++软件包规范,有助于实现在不同的构建和软件包工具间的协同和互操作。此外,如果力图去构建一种通用构建工具和软件包管理器(例如build2),这无疑将是一场艰苦的战斗,并人们也不会很快地采用该工具。因此,我们聚焦于如何尽可能地实现现有实践的标准化,这样用户也不必重写他们的构建文件。
作者:PaulFultzII
译者:盖磊
来源:infoq
【免责声明】:本内容转载于网络,转载目的在于传递最新信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。