Cargo:Rust 的社区包管理器

2014 年 11 月 20 日 · Alex Crichton

今天我很高兴地宣布 crates.io 已经上线并准备投入使用。该网站是发现/下载 Rust 包的中心位置,Cargo 今天已经准备好开始向其发布。在接下来的几个月里,我们希望勇敢的早期采用者 帮助我们 对注册表进行实战测试。

在 Rust 本身稳定之前(明年年初),注册表依赖项需要经常更新。生产用户可能希望在此之前继续使用 git 依赖项。

什么是 Cargo?

Cargo 是一个 Rust 的包管理器,用 Rust 编写。管理依赖项是一个从根本上来说很困难的问题,但幸运的是,在过去十年中,包管理器的设计取得了很大进展。Cargo 由 Carl Lerche 和 Yehuda Katz 设计,遵循了像 BundlerNPM 这样的成功案例的传统。

  1. Cargo 利用 crates.io 来培养一个繁荣的社区,这些社区可以轻松地相互操作并持续多年。

  2. Cargo 使开发人员免于担心管理依赖项,并确保所有协作者都在构建相同的代码。

  3. Cargo 允许您的依赖项说明它们应该如何构建,并为您管理整个构建过程。

Cargo 上的社区

为了了解 Cargo 如何实现其目标,让我们看一下它的一些核心机制。

声明依赖项

Cargo 使依赖第三方代码与依赖标准库一样容易。使用 Cargo 时,每个包都将有一个关联的 清单 来描述自身及其依赖项。添加新的依赖项现在就像在清单中添加一行一样简单,这种简便性使 Cargo 在短短几个月内就能够实现一个庞大且不断增长的 Rust 项目和库网络,而这些网络在以前是不可行的。

然而,Cargo 本身并不是完整的解决方案。发现依赖项仍然很困难,而且也不能保证这些依赖项在未来几年内始终可用。

crates.io

为了与 Cargo 配合使用,中央 crates.io 网站充当发布和发现库的单一位置。此存储库充当包版本随时间的永久存储,以确保项目始终可以使用相同版本进行构建,即使是几年后。到目前为止,Cargo 的用户主要直接从源 GitHub 存储库下载依赖项,但现在主要来源将转移到 crates.io。

其他编程语言社区在使用这种中央存储库方面取得了很大成功。例如,rubygems.org 是您的一站式商店,用于 Bundler 依赖项,而 npmjs.org 在本月仅下载量就超过了 6 亿次!我们希望 crates.io 为 Rust 扮演类似的角色,作为 Rust 在 1.0 版本时的长期稳定性故事 的关键基础设施。

版本控制和可重复构建

在过去几年中,语义版本控制 的概念已成为库开发人员与用户轻松清晰地沟通何时进行重大更改的一种方式。语义版本控制的核心思想很简单:每个新版本都被归类为次要版本或主要版本,只有主要版本才能引入重大更改。Cargo 允许您为您的依赖项指定版本范围,默认含义为“兼容”。

在指定版本范围时,应用程序通常会请求单个包的多个版本,Cargo 通过选择每个主要版本(“稳定代码”)中请求的最高版本来解决此问题。这极大地鼓励使用稳定发行版,同时仍然允许不稳定代码的副本(例如 1.0 之前的版本和 git)。

计算出依赖项集及其版本后,Cargo 会生成一个 Cargo.lock 来对这些信息进行编码。然后,此“锁定文件”将分发给应用程序的协作者,以确保构建的包从一次构建到另一次构建,跨越时间、机器和环境保持一致。

构建代码

到目前为止,我们已经了解了 Cargo 如何促进社区项目的发现和重用,同时管理要使用的版本。现在,Cargo 只需要处理实际编译所有这些代码的问题!

由于对它正在构建的 Rust 代码有深入的了解,Cargo 能够提供一些不错的标准功能以及一些特定于 Rust 的功能。

  • 默认情况下,Cargo 会尽可能多地并行构建包。这不仅适用于并行构建上游依赖项,也适用于本地包的项目,例如测试套件、二进制文件和单元测试。

  • Cargo 本身支持单元测试,既适用于包本身,也适用于集成测试的形式。这甚至包括示例程序,以确保它们不会腐烂。

  • Cargo 为依赖关系图中的所有包生成文档,它甚至可以运行 Rust 的文档测试,以确保文档中的示例保持最新。

  • Cargo 可以在编译任何包之前运行 构建脚本,以执行诸如代码生成、编译本机依赖项或检测本地系统上的本机依赖项等任务。

  • Cargo 本身支持交叉编译。交叉编译只需指定一个 --target 选项,Cargo 将管理诸如为正确平台编译插件和其他构建依赖项等任务。

还有什么计划?

crates.io 的发布是推动 Cargo 生态系统向前发展的一个关键步骤,但故事并没有到此结束。crates.io 的使用架构假设了一个稳定的编译器,这应该 很快就会到来!crates.io 还有一些扩展,例如托管文档服务或 CI 构建基础设施钩子,可以使用 crates.io API 构建。

这仅仅是 crates.io 的开始,我很高兴能够从一个位置找到所有 Rust 包。我迫不及待地想看看 1.0 版本的注册表是什么样子,我只能想象 1.0 版本之后的注册表会是什么样子!