附录 G - Rust 如何构建以及“每日构建版 Rust”

本附录介绍 Rust 如何构建以及这对 Rust 开发人员有何影响。

在保持稳定的同时不失活力

作为一门语言,Rust 非常关心代码的稳定性。我们希望 Rust 成为您可以构建的坚实基础,如果事情不断变化,那将是不可能的。与此同时,如果我们不能尝试新功能,我们可能要到新功能发布后才能发现重要缺陷,而那时我们已经无法再进行更改。

我们解决这个问题的方法是“在保持稳定的同时不失活力”,我们的指导原则是:您永远不必担心升级到新版本的稳定版 Rust。每次升级都应该是轻松愉快的,但也应该为您带来新功能、更少的错误和更快的编译速度。

呜—呜!发布渠道和搭乘火车

Rust 开发按照火车时刻表进行。也就是说,所有开发都在 Rust 仓库的 master 分支上完成。发布遵循软件发布列车模型,该模型已被 Cisco IOS 和其他软件项目采用。Rust 有三个发布渠道:

  • 每日构建版
  • 测试版
  • 稳定版

大多数 Rust 开发人员主要使用稳定版渠道,但那些想要尝试实验性新功能的人可能会使用每日构建版或测试版。

以下是开发和发布过程如何运作的示例:假设 Rust 团队正在准备发布 Rust 1.5。该版本于 2015 年 12 月发布,但它将为我们提供真实的版本号。Rust 中添加了一个新功能:一个新的提交被合并到 master 分支。每天晚上,都会生成一个新的每日构建版 Rust。每天都是发布日,这些版本由我们的发布基础设施自动创建。因此,随着时间的推移,我们的发布版本每晚都会像这样更新:

nightly: * - - * - - *

每六周,就该准备一个新版本了!Rust 仓库的 beta 分支从每日构建版使用的 master 分支分支出来。现在,有两个发布版本:

nightly: * - - * - - *
                     |
beta:                *

大多数 Rust 用户不会积极使用测试版,而是在他们的 CI 系统中针对测试版进行测试,以帮助 Rust 发现可能的回归。与此同时,每天晚上仍然会有一个每日构建版发布:

nightly: * - - * - - * - - * - - *
                     |
beta:                *

假设发现了一个回归。好在我们在回归潜入稳定版之前有时间测试测试版!修复程序应用于 master,以便修复每日构建版,然后将修复程序反向移植到 beta 分支,并生成新的测试版:

nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *

第一个测试版创建六周后,就该发布稳定版了!stable 分支是从 beta 分支创建的:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *

万岁!Rust 1.5 完成了!但是,我们忘记了一件事:因为六周已经过去了,我们还需要下一个版本的 Rust,即 1.6 的测试版。因此,在 stablebeta 分支出来后,下一个版本的 beta 再次从 nightly 分支出来:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *

之所以称之为“火车模型”,是因为每隔六周,就会有一个版本“离开车站”,但在作为稳定版本到达之前,它仍然需要经过测试版的旅程。

Rust 每六周发布一次,像时钟一样准时。如果你知道一个 Rust 版本的日期,你就可以知道下一个版本的日期:六周后。每六周发布一次版本的一个好处是,下一班火车很快就会到来。如果一个功能碰巧错过了某个特定版本,也不必担心:另一个版本很快就会发布!这有助于减轻在接近发布截止日期时匆忙加入可能未经完善的功能的压力。

由于这个过程,你始终可以查看 Rust 的下一个版本,并亲自验证升级到该版本很容易:如果测试版没有按预期工作,你可以在下一个稳定版本发布之前向团队报告并修复它!测试版中的故障相对少见,但 rustc 仍然是一个软件,bug 确实存在。

维护时间

Rust 项目支持最新的稳定版本。当一个新的稳定版本发布时,旧版本就达到了它的生命周期结束(EOL)。这意味着每个版本都支持六周。

不稳定功能

这个发布模型还有一个问题:不稳定功能。Rust 使用一种称为“功能标志”的技术来确定在给定版本中启用了哪些功能。如果一个新功能正在积极开发中,它会出现在 master 分支上,因此也会出现在 nightly 版本中,但会隐藏在一个*功能标志*后面。如果你作为用户希望尝试正在开发中的功能,你可以这样做,但你必须使用 Rust 的 nightly 版本,并在你的源代码中使用适当的标志进行注释以选择加入。

如果你使用的是 Rust 的测试版或稳定版,则不能使用任何功能标志。这是允许我们在宣布新功能永久稳定之前实际使用它们的秘诀。那些希望选择最前沿功能的人可以这样做,而那些想要坚如磐石的体验的人可以坚持使用稳定版,并且知道他们的代码不会崩溃。稳定而不停滞。

本书只包含关于稳定功能的信息,因为正在开发的功能仍在变化,而且从本书编写到它们在稳定版本中启用,它们肯定会发生变化。你可以在网上找到仅限 nightly 版本的功能文档。

Rustup 和 Rust Nightly 的作用

Rustup 可以轻松地在 Rust 的不同发布渠道之间切换,无论是全局的还是每个项目的。默认情况下,你将安装稳定的 Rust。例如,要安装 nightly 版本

$ rustup toolchain install nightly

你还可以使用 rustup 查看你已安装的所有*工具链*(Rust 版本和相关组件)。以下是你的一位作者在 Windows 计算机上的示例

> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

如你所见,稳定的工具链是默认的。大多数 Rust 用户大多数时候都使用稳定版。你可能希望大多数时候使用稳定版,但在特定项目中使用 nightly 版本,因为你关心的是一项前沿功能。为此,你可以在该项目的目录中使用 rustup override 将 nightly 工具链设置为你在该目录中时 rustup 应该使用的工具链

$ cd ~/projects/needs-nightly
$ rustup override set nightly

现在,每次你在 ~/projects/needs-nightly 中调用 rustccargo 时,rustup 都会确保你使用的是 nightly 版本的 Rust,而不是默认的稳定版 Rust。当你有很多 Rust 项目时,这非常方便!

RFC 流程和团队

那么你如何了解这些新功能呢?Rust 的开发模型遵循*征求意见稿(RFC)流程*。如果你想改进 Rust,你可以写一份提案,称为 RFC。

任何人都可以编写 RFC 来改进 Rust,这些提案由 Rust 团队审查和讨论,该团队由许多主题小组组成。在Rust 网站上有完整的团队列表,其中包括项目每个领域的团队:语言设计、编译器实现、基础设施、文档等等。相应的团队会阅读提案和评论,写下他们自己的评论,最终,就会达成接受或拒绝该功能的共识。

如果该功能被接受,则会在 Rust 存储库中打开一个问题,然后有人可以实现它。实现它的人很可能不是最初提出该功能的人!当实现完成后,它会出现在 master 分支上,隐藏在一个功能门控后面,正如我们在“不稳定功能”部分中讨论的那样。

一段时间后,一旦使用 nightly 版本的 Rust 开发人员能够试用新功能,团队成员将讨论该功能,它在 nightly 版本中的工作方式,并决定是否应该将其纳入稳定的 Rust 版本。如果决定继续推进,则删除功能门控,该功能现在被认为是稳定的!它会随着火车进入新的 Rust 稳定版本。