当库名称与包名称不同时如何导入 crate 依赖项?

How to import a crate dependency when the library name is different from the package name?

我有一个直接从 GitHub 进口的板条箱,根据 Cargo 的 documentation:

[dependencies]
libfoo = { git = "ssh://git@github.com/me/libfoo", branch = "dev" }

[lib]
path = "src/rust/lib.rs"
name = "myprj"
crate-type = ["cdylib"]

运行 cargo build 在这里工作正常,Cargo 获取 libfoo 并将其构建在 ~/.cargo 目录中。当我尝试在 lib.rs:

中使用(导入)它时
extern crate libfoo;   //also tried foo

货物扼流圈:

error[E0463]: can't find crate for `libfoo`
 --> src/rust/lib.rs:1:1
  |
1 | extern crate libfoo;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate

有趣的是,当我在 lib.rs 中单击它时,IntelliJ 的 Rust 插件确实找到了箱子——它导航到 ~/.cargo 中下载的源...

在依赖项 libfoo 中,Cargo.toml 文件的 lib 部分指定为:

[package]
name = "libfoo"
[lib]
name = "foo"
crate-type = ["cdylib"]

我已经尝试了 libfoo 和 foo 的所有排列,看看 Cargo 是否混淆了 lib 名称和 package/directory 名称。

如果我指定依赖项的本地路径,它也会失败。 (Cargo 编译依赖项,但随后声称在 lib.rs 中为 declared/imported 时找不到它。)

[dependencies]
libfoo = { path = "/Users/me/dev/libfoo" }

如果我包含来自 git 的 crate 或具有与 [package] 名称相同的 [lib] 名称的文件系统,它工作正常。因此,问题似乎出在具有与包 ([package]) 名称不同的库 ([lib]) 名称的板条箱上。

如果我从依赖项的 Cargo.toml 文件中删除 [lib] 部分,它会起作用。

更新:如果从 libfoo 中删除 crate-type = ["cdylib"],这与导入的 foo 一起使用。如果存在,我会得到与 extern crate foo;.

相同的错误

Cargo 对包名感兴趣,而编译器(rustc)对库名[=61]感兴趣=] 当谈到加载他们的元数据并与他们链接时。

让我们再看一下这个Cargo.toml摘录:

[package]
name = "libfoo"

[lib]
name = "foo"

这里,包名libfoo库名foo.

当你想在项目中声明对libfoo的依赖时,需要在[=]中写上包名(libfoo) 20=] table。例如:

[dependencies]
libfoo = { git = "ssh://git@github.com/me/libfoo", branch = "dev" }

这是你已有的,而且是正确的。

但是,当你想在你的crate中导入库时,你需要在extern crate项中写上库名,即

extern crate foo;

我是怎么想出来的?首先,如您所述,我在 Cargo.tomlextern crate 项中都写了 libfoo。当我 运行 cargo build 时,我注意到 libfoo 构建成功,表明 Cargo 正确解决了依赖关系。但我也注意到编译器无法找到 libfoo,如您所见。

然后我检查了 运行 cargo build --verbose 传递给 rustc 的命令行。这是我看到的(无关部分省略):

Running `rustc [...] --extern foo=/[path]/target/debug/deps/libfoo-5cf876c5c8ac1bfb.rlib`                                                                 

--extern name=path 参数告诉 rustc 名为 name 的板条箱位于 path。这里的名字是foo,所以我们必须在代码中写extern crate foo;来引用它。