为什么选择构建系统?

本页讨论了什么是构建系统、其作用、为何应使用构建系统,以及编译器和构建脚本为何不是在组织开始扩展时的最佳选择。它适用于没有构建系统经验丰富的开发者。

什么是构建系统?

从根本上来说,所有构建系统都有一个简单的目标:它们将工程师编写的源代码转换为机器可读取的可执行二进制文件。构建系统不仅适用于用户编写的代码;它们还允许机器自动创建 build,无论是用于测试还是发布到生产环境。在具有数千工程师的组织中,大多数构建通常是自动触发的,而不是直接由工程师触发的。

不能只使用编译器?

构建系统的需求可能并不明显。大多数工程师在学习代码时都不会使用构建系统:首先,直接从命令行调用 gccjavac 等工具,或集成开发环境 (IDE)。只要所有源代码都位于同一目录中,类似如下的命令就可以:

javac *.java

这会指示 Java 编译器接受当前目录中的所有 Java 源文件并将其转换为二进制类文件。在最简单的情况下,您只需要这些即可。

不过,一旦代码展开,复杂功能就会立即开始。javac 非常智能,可以在当前目录的子目录中查找要导入的代码。但是,它无法找到在文件系统其他部分中存储的代码(可能是由多个项目共享的库)。它还知道如何构建 Java 代码。大型系统通常涉及使用各种编程语言编写的不同部分,并且这些部分之间存在相互依赖的网络,这意味着单个语言的任何编译器都无法构建整个系统。

处理来自多种语言或多个编译单元的代码后,构建代码不再是一步到位的过程。现在,您必须评估代码所依赖的内容,并按照正确的顺序构建这些内容,并可能针对这些内容使用不同的工具。如果任何依赖项发生更改,则必须重复此过程,以避免依赖于过时的二进制文件。对于中等规模的代码库,此过程会很快变得繁琐且容易出错。

编译器也不知道如何处理外部依赖项,例如 Java 中的第三方 JAR 文件。如果没有构建系统,您可以管理互联网,方法是从互联网下载依赖项,将其粘贴到硬盘上的 lib 文件夹中,并将编译器配置为从该目录中读取库中披露政府所要求信息的数量和类型。随着时间的推移,很难维护这些外部依赖项的更新、版本和来源。

支持 Shell 脚本吗?

假设您的爱好项目开始就足够简单,您只需使用编译器来构建该项目,但您会开始遇到之前所述的一些问题。也许您仍然认为自己不需要构建构建系统,并且可以使用一些简单的 Shell 脚本(按正确顺序构建)来自动处理繁琐的部分。这样做可以解决问题一段时间,但很快您会遇到更多问题:

  • 非常繁琐。随着系统变得越来越复杂,您将开始在构建脚本上花费的时间与处理实际代码几乎一样。调试 shell 脚本非常令人头痛,因为越来越多的黑客入侵另一个应用。

  • 速度很慢。为避免意外依赖于过时的库,您可以让构建脚本在每次运行时按顺序构建每个依赖项。您可以考虑添加一些逻辑来检测哪些部分需要重新构建,但对于脚本来说,听起来非常复杂,容易出错。或者,您需要考虑每次都指定要重新构建哪些部分,然后返回到方形第一部分。

  • 好消息!是时候发布新版本了!最好弄清楚需要将哪些参数传递给 jar 命令才能进行最终构建。还要记得如何上传它并将其推送到中央代码库。构建并推送文档更新,然后向用户发送通知。may,可能还需要调用另一个脚本...

  • 灾难来了!硬盘驱动器崩溃了,现在您需要重新创建整个系统。您非常智能,可以将所有源文件保存在版本控制中,但是您下载的库呢?您是否可以再次找到它们,并确保它们与您首次下载它们时的版本相同?您的脚本可能依赖于在特定位置安装的特定工具 - 您能否恢复相同的环境以使脚本再次运行?那么,您早些时候设置的所有环境变量都可让编译器恰到好处地运行,却忘记吗?

  • 尽管遇到了问题,但您的项目已经足够成功,可以开始招募更多工程师了。现在,您认识到前面的问题不会带来灾难 - 每次新开发者加入您的团队时,您都需要经历相同的痛苦引导过程。虽然您已经竭尽全力,但每个人的系统仍存在细微差异。通常,一个人计算机上的内容不适合另一个人,并且每次都需要花费数小时的调试工具路径或库版本来确定差异所在。

  • 您决定需要自动化构建系统。理论上,这很简单,只需获取一台新计算机,并将其设置为每晚使用 Cron 运行构建脚本即可。您仍然需要经历令人痛苦的设置过程,但现在您没有人脑能够检测到并解决不小问题的优势。现在,当您每天早上上班时,会看到昨天的构建失败,因为昨天开发者进行了一项更改,该更改适用于他们的系统,但不适用于自动化构建系统。每次但这都是简单的修复,但这种情况经常发生,导致您每天花费大量时间来发现和应用这些简单修复。

  • 随着项目的增大,构建速度会减慢。某天,在等待构建工作完成后,您将 着目光 your 着正在休假的同事的空闲桌面,希望有办法利用这些不必要的计算资源电源。

您遇到了一个传统的规模问题。对于一位开发者在一到两周内最多只运行几百行代码(这个代码可能在刚刚从大学毕业的初级开发者那里就获得了完整的体验),您只需使用编译器即可。脚本也许需要您多做一些。但是,只要您需要跨多个开发者及其机器进行协调,即使是完美的构建脚本也是不够的,因为很难考虑到这些机器之间的细微差异。从现在开始,这种方法非常简单,接下来该投资真正的构建系统了。