今天我很高兴地宣布,crates.io 已上线并准备就绪。该网站是发现/下载 Rust crate 的中心位置,并且 Cargo 今天就可以开始向其发布了。在接下来的几个月里,我们希望勇敢的早期采用者们能帮助我们测试这个注册表,使其久经考验。
在 Rust 本身明年年初稳定之前,注册表依赖项需要经常更新。生产环境用户可能希望在此之前继续使用 Git 依赖项。
什么是 Cargo?
Cargo 是一个面向 Rust 的、用 Rust 编写的包管理器。管理依赖项是一个根本性的难题,但幸运的是,在过去十年中,包管理器的设计取得了很大进展。Cargo 由 Carl Lerche 和 Yehuda Katz 设计,沿袭了 Bundler 和 NPM 等成功项目的传统。
-
Cargo 利用 crates.io 培养一个繁荣的 crate 社区,其中的 crate 可以轻松地相互协作,并能持续多年。
-
Cargo 使开发者摆脱了管理依赖项的烦恼,并确保所有协作者构建的是相同的代码。
-
Cargo 让你的依赖项能够指定如何构建它们,并为你管理整个构建过程。
Cargo 上的社区
为了感受 Cargo 如何实现其目标,让我们看看它的一些核心机制。
声明依赖项
Cargo 让依赖第三方代码就像依赖标准库一样简单。使用 Cargo 时,每个 crate 都有一个相关的清单(manifest)来描述自身及其依赖项。添加新的依赖项现在就像在清单中添加一行一样简单,这种便捷性使得 Cargo 在短短几个月内就促成了一个庞大且不断增长的 Rust 项目和库网络,这在以前是根本不可能的。
然而,仅靠 Cargo 并非完整的解决方案。发现依赖项仍然困难,并且无法保证这些依赖项在未来多年内都可用。
crates.io
为了与 Cargo 配合使用,中心化的 crates.io 网站作为发布和发现库的单一位置。这个仓库作为 crate 随时间推移发布的永久存储,以确保项目在多年后也能始终使用完全相同的版本进行构建。到目前为止,Cargo 用户主要只是直接从 GitHub 仓库下载依赖项,但现在主要来源将转移到 crates.io。
其他编程语言社区在采用这种中心化仓库形式方面取得了巨大成功。例如,rubygems.org 是你获取 Bundler 依赖项的一站式商店,而 npmjs.org 仅本月下载量就超过了 6 亿次!我们希望 crates.io 能在 Rust 生态系统中扮演类似的角色,作为 Rust 1.0 版本长期稳定的重要基础设施。
版本控制与可复现构建
在过去几年里,语义化版本(Semantic Versioning)的概念越来越受欢迎,作为库开发者在进行破坏性更改时,与用户轻松清晰沟通的一种方式。语义化版本的核心思想很简单:每个新版本被归类为次版本或主版本,只有主版本才能引入破坏性变更。Cargo 允许你为依赖项指定版本范围,默认含义是“兼容于”。
在指定版本范围时,应用程序通常会请求同一 crate 的多个版本,Cargo 通过选择每个请求的主版本的最高版本(“稳定代码”)来解决这个问题。这极大地鼓励使用稳定发布版本,同时仍然允许不稳定代码(例如 1.0 之前版本和 Git 版本)的重复存在。
一旦依赖项及其版本集被计算出来,Cargo 会生成一个Cargo.lock
文件来编码这些信息。然后这个“锁文件”会分发给应用程序的协作者,以确保跨时间、跨机器、跨环境的构建中,所构建的 crate 保持一致。
构建代码
到目前为止,我们已经了解了 Cargo 如何在管理使用哪个版本的同时,促进社区项目的发现和重用。现在 Cargo 只需解决实际编译所有这些代码的问题了!
由于对它正在构建的 Rust 代码有深入的了解,Cargo 能够提供一些不错的标准功能以及一些 Rust 特有的功能。
-
默认情况下,Cargo 会尽可能并行地构建多个 crate。这不仅适用于并行构建上游依赖项,也适用于本地 crate 的各种项,如测试套件、二进制文件和单元测试。
-
Cargo 提供开箱即用的单元测试支持,既支持 crate 本身的单元测试,也支持集成测试形式。这甚至包括示例程序,以确保它们不会失效。
-
Cargo 为依赖图中的所有 crate 生成文档,并且它甚至可以运行Rust 的文档测试,以确保文档中的示例保持最新。
-
Cargo 可以在编译任何 crate 之前运行构建脚本(build script),以执行诸如代码生成、编译原生依赖项或检测本地系统上的原生依赖项等任务。
-
Cargo 提供开箱即用的交叉编译支持。交叉编译只需简单地指定
--target
选项即可完成,Cargo 将管理诸如为正确平台编译插件及其他构建依赖项等任务。
还有哪些计划?
crates.io 的发布是推动 Cargo 生态系统向前发展的关键一步,但故事并未就此结束。crates.io 的使用架构是基于稳定的编译器(stable compiler)的,这应该很快就会到来!此外,还有一些 crates.io 的扩展,例如托管文档服务或 CI 构建基础设施钩子,这些都可以使用 crates.io API 构建出来。
这仅仅是 crates.io 的开始,我很高兴能开始从一个地方找到所有的 Rust crate。我迫不及待地想看到注册表在 1.0 版本时的样子,我只能想象 1.0 版本之后会是什么样子!