外部库作为对本地库的依赖

Extern libraries as dependency to local libs

在像 C 这样的语言中,我们处理三种不同的翻译单元:目标文件、库和可执行文件。如果我没理解错的话,Rust 已经跳过了第一个。也就是说,如果我想将我的项目分成几个翻译单元,我必须使用本地板条箱,如此 blog.

所示

如果在代码中几乎所有地方都使用 extern crate (E)(即我的本地 lib crate 和二进制 crate),那么必须在所有 Cargo.toml 依赖项中包含 E。

问题:

我知道使用动态库是部分解决方案;但是,我的项目是嵌入式项目,不支持动态库。

1 这是我的个人印象;对不起,如果我在这里错了。

I want to divide my project into several translation units

你没有解释为什么你想这样做。如果是出于编译性能原因,那么您可能只想等待更好的增量编译支持。根据所涉及的代码类型,拆分成 crate 可能会或可能不会有助于编译时间 — 例如,具有高度通用 API 的 crate 将获得较少的好处。

我认为语义/组织原因是拆分的最佳理由。

Does this mean that E's code is included several times in the final binary?

没有。当 Cargo 执行依赖解析时,它会尝试解析每个依赖的单个版本。如果您的依赖树有冲突的版本要求,那么可能会包含多个版本,但无论如何这是编译此类代码的唯一方法。使用像 cargo-tree 这样的工具可以帮助您找到强制包含多个版本的 crate。

I have to change all Cargo.toml files.

您的 Cargo.toml 文件不需要更改 除非 您需要升级到一个 semver 不兼容的版本箱。您的 Cargo.lockonly exists for your final binary 是唯一需要更改的文件。

Is the cited approach idiomatic? While possible, the Rust community seems not to advocate sub-crates beside of in workspaces

我看到的主要缺点是,如果您想做类似的事情,您将需要 发布 多个 crate。如果您只是构建一个二进制文件,我认为没有理由不这样做。 Parity 是一个较大的二进制项目的示例,它由许多较小的 crate 组成。