为什么一个货物包只能有一个库目标?

31

根据其手册, Cargo包可以有多个可执行目标,但只允许一个库目标。

一个包可以包含零个或一个库crate和任意数量的二进制crate。包中必须至少有一个crate(库或二进制)。

为什么限制为一个?这样做的原因和好处是什么?


拥有多个库的好处是什么? - Shepmaster
4
好问题。这是否与拥有多个“可执行文件”的好处相同? - eonil
@Shepmaster 因为我想以这样的方式组织我的代码,使得每个库都有一个清晰明确的范围。 - DimanNe
@DimanNe,你仍然可以通过多个软件包实现这一点。 - Shepmaster
3个回答

29
Cargo主要是一个包管理器。因此,包的主要作用是定义一个库。
当我们将一个crate作为依赖项使用时,在我们的Cargo.toml中只需指定包名即可。由于最多只能有一个库,Cargo不需要您指定要使用哪个库。如果允许在同一个包中定义多个库,那么我们就需要指定一种定义它们之间依赖关系的方式,这样我们就会有两种声明依赖关系的方法(外部包与内部crate),从而使系统变得更复杂。
另一方面,添加一个不提供库的依赖是没有意义的,至少对于Cargo来说是如此,因为在这种情况下,Cargo只关心库目标。因此,没有理由将其他类型的目标(二进制文件、示例、测试等)限制为每个目标只能有一个。 Cargo工作区是Cargo提供的用于同时处理多个包的工具。

对于默认的 rlib crates 来说,这是有意义的,它们是用于组合的 Rust 模块。但为什么不允许生成多个 cdylib 呢?就像允许生成多个 bin 一样。它们与 bin 的入口语义相同,唯一的区别是它们直接被应用程序使用,而不是通过 HTTP、UI 或 CLI。 - kkolyan

2

我认为一个货物包只能有一个库目标,因为库箱根据定义是一组项目(函数、类型、特性、宏、值等),而二进制箱只有一个外部可见的东西,即主入口点。因此,虽然库箱的名称仅是层次结构中的根模块,但二进制箱的名称是唯一的。


0
当 Rust 文档表示一个 crate 只能有一个库和一个二进制文件时,这是指每个 crate 定义所产生的输出。
例如,如果你编写了一些代码,你可以只生成一个可执行文件,或者一个供其他代码链接的单独的库。
你可以将库产品(输出)分割成模块,以便你可以单独开发每个模块并在最后产生一个最终打包的库。
模块有点像内部库,在最后会被捆绑在一起生成一个大的外部库,或者直接生成一个完整的二进制可执行文件。
把 crate 看作是别人可以使用的成品,而模块则是组件。标准库是一个 crate,由许多不同的模块组成。你也可以有子模块,并且可以有任意数量。但它们最终会被 Cargo 编译成一个最终的(输出)库。
你还可以在一个包中包含任意数量的 crates,但你的 crate 通常只会产生一个可执行文件(大多数情况下)或一个单独的库。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接