构建系统讨论
构建系统讨论 我之前的博客文章在permacomputing邮件列表上引起了一些兴趣,特别是与设计个人或permacomputing构建系统有关的内容。我想简要概述一下../lua/civ构建系统,并探讨与会参与者讨论的构建系统以及我脑海中关于civ包管理器的想法。作为参考,这里是所呈现的构建系统。大多数情况下,我不会给出有针对性的批评,而是阐明我认为优秀构建系统需要完成的目标。我大部分的批评将集中在bazel和Make上: https://bazel.build 谷歌的构建系统,可以实时增量或从零开始构建谷歌的所有软件。 ../lua/civ - 本项目的构建系统。 Kartik的方法 LM构建系统clib,这似乎主要是一些小型C库和脚本的集合,直接集成到您的源代码中。 Make - 不需要介绍。那么什么是构建系统或包管理器呢?在进入具体内容之前,回到基本事实是重要的:构建系统的作用是什么?我曾经有一个刚从大学毕业的工程师问我一些与他处理的CAD文件相关的问题。他花了5-10分钟尝试解释他特定CAD工具的所有细节,某些表示的部分如何难以编写脚本,以及他是如何应对的等等。我几乎对CAD一无所知,因此在技术细节上几乎没有提供帮助,但我问了他一个问题:你的输入是什么,输出是什么?通过这个问题,他完全重新构架了问题。他很快开始解开他形成的复杂网络,开始讨论技术细节,事情变得更干净、更简单、更容易,而不是他意识到的那样。对CAD一无所知,我只能微笑——但这已经足够了。那么,什么是构建系统?Civ的回答是,它是一个程序,接受源代码(文件)、二进制文件(编译器)和配置(标志、配置文件)作为输入,并根据特定的文件夹结构输出文件、二进制和配置,这些可以在目标平台上执行。因此,一个优秀构建系统的第一个原则是:每个构建阶段的所有输入和输出必须在某处显式。一个好的构建系统如何将输入转化为输出?第二个问题也许是更重要的:用户如何指定他们想要构建的内容,以及构建的不同部分(库、脚本、配置文件等)如何最终合成一个整体?这就是Make惨败的地方——Make实际上是一个集合,包含了一个晦涩、特定平台的语法的shell脚本。它将每个“规则”定义为输入和输出的集合,而未能提供整体的愿景来将它们串联在一起。这是一个优秀构建系统的下一个原则:必须能够以编程方式配置输入和输出,以适应不同的目标系统。实际上,一个好的构建系统为源代码和实际构建的程序之间提供了正确的抽象层——尽可能简单,但不简单到无法使用。Civ的答案是:将文件的去向和构建方式的决策委托给用户可以集中配置的东西——有效的构建库——它具有最小且定义良好的API,但其内部可以根据不同的平台进行替换。在civ中,这被称为系统中心。例如,cc.luk(luk是lua配置文件,一个沙盒lua进程,带有稍微不同的全局变量)包含了将用户的cc{hrd='foo.h'}转换为发送到sys/cc/build.lua的对象的逻辑,实际上这个脚本是用来构建程序的。这同时完成了两件事: 1.将用户对于构建内容的规范与在目标架构上执行所需的特定输出结构解耦。这使用户能够随意组织他们的源代码,同时在构建并安装后仍能从简洁的系统级标志(如LD_LIBRARY_PATH)中受益。 2.将需要构建的内容的配置与构建过程解耦——允许软件的构建扩展到多个线程,甚至多个机器(如果您重写civ协议以扩展,例如企业)。这实际上是Bazel(谷歌的构建系统)做得非常好的事情,但虽然Bazel是一个庞大且复杂的软件整体,它决定为其配置语言分叉python,而civ则是用1000行cmd实用程序库编写的,该库生成一个密闭的lua来解释使用约100行的lua库进行的配置。 包管理 一个优秀构建系统的最终特质是其能够简单地与一个包管理器相结合,而这正是我希望花更多时间的地方,因为它仍处于设计阶段。在civ(或Bazel)中,当您创建...
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡