12

我对 crates.io 上托管的确切内容有点困惑(“板条箱”是指代这些内容的正确方法)?我的理解是 crate 是 Rust 中的一个编译单元,但是 crates 和 crates.io 上的映射是什么?例如,关于宏的 Rust 编程语言附录说,因为每个 crate 只能有一个过程宏:

我们的两个 crate 紧密相关,所以我们在 crate 的目录中创建程序宏hello_macrocrate。如果我们更改 中的特征定义hello_macro,我们也必须更改程序宏的实现hello_macro_derive。这两个 crate 需要单独发布,使用这些 crate 的程序员需要将两者都添加为依赖项并将它们都纳入范围。我们可以将 hello_macro cratehello_macro_derive用作依赖项并重新导出过程宏代码。但是我们构建项目的方式使程序员hello_macro即使不想要该derive功能也可以使用。

它必须在 crates.io 上单独发布。这似乎很清楚: crates.io 上的 crate 与本地 crate 相同,并且映射是一对一的。

但是,当讨论同时包含可执行文件和库的项目时,这意味着它们是单独的 crate,但不需要单独发布。例如,sccache 存储库同时具有 main.rs 和 lib.rs。单独的二进制 crate 是否实际上并未存储在 crates.io 上并且仅驻留在 repo 中?那么 cargo install 是如何确定要安装什么的呢?

什么是“包”?

我尝试cargo package使用包含二进制和库目标的示例项目运行。两者都被添加到.cargo文件中(顺便说一下,.cargo 档案的确切格式是否记录在任何地方?)。这仍然让我感到困惑。我们可以将多个 crate 作为一个包的一部分发布吗?那么我们是否应该将 crates.io 上存储的内容称为?我是否可以假设每个包可以包含多个二进制包但只有一个库包?这是我目前的理解。

4

1 回答 1

7

crates.io 上托管的确切内容是包内的 crates。

crate是编译器的输出工件。

来自Rust 参考手册

编译模型以称为 crates 的工件为中心。每次编译都处理一个源代码形式的 crate,如果成功,则生成一个二进制形式的单个 crate:可执行文件或某种库。

是由 Rust 包管理器 Cargo 管理的工件。

Cargo.tomlmanifest 文件使用以下语法定义包:

[package]
name = "hello_world"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]  

一个包可能包含一个或多个 crate,例如一个库 crate,命名为包名称和零个或多个可执行 crate,每个包都[[bin]]在清单文件的一部分中显式定义,或者如果位于src/bin包目录中则隐式定义。

Cargo book使用术语 crate 作为 package 的别名。考虑以下语句以尝试找出一些意义:

通常*一个包的主要构件是一个库 crate,并且由于它是用包名称标识的,因此习惯上将包和 crate 视为同义词。

*:一个包可能只包含一个二进制文件,例如ripgrep

于 2018-08-29T07:46:17.257 回答