【问题标题】:How to import a crate dependency when the library name is different from the package name?当库名称与包名称不同时,如何导入 crate 依赖项?
【发布时间】:2017-06-26 23:06:40
【问题描述】:

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

[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 名称和包/目录名称。

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

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

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

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

更新:如果从libfoo 中删除crate-type = ["cdylib"],则这适用于导入的foo。如果存在,我会收到与 extern crate foo; 相同的错误。

【问题讨论】:

  • try to use it 是什么意思?依赖项目是否真的如上句所说的那样构建好?
  • 另请注意,docs 实际上建议指定来自 GitHub 存储库的依赖项,例如 { git = "https://github.com/rust-lang-nursery/rand" }
  • @E_net4 适用于公共存储库,但对于私有存储库,您必须使用 ssh url。它的那部分工作正常。 ssh url 没有记录。
  • libmylib 很混乱...请​​使用更清晰的名称或真实姓名。你有没有试过libmy(我不知道只是一个想法)?

标签: rust rust-cargo


【解决方案1】:

当涉及到依赖项时,Cargo 对 包名称 感兴趣,而在加载元数据和与他们联系。

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

[package]
name = "libfoo"

[lib]
name = "foo"

这里,包名libfoo库名foo

当你想在你的项目中声明对libfoo的依赖时,你需要在[dependencies]表中写下包名libfoo)。例如:

[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;来引用它。

【讨论】:

  • 我确实尝试过extern crate foo。如果crate-type = ["cdylib"] 不存在,则进行更多挖掘,foo 有效。但如果它在那里,我会得到同样的错误。我假设出了点问题,所以我在货物项目上打开了一个问题。
  • 我认为这是完全正常的。 cdylib 代表一个库,它提供 C 接口,而不是 Rust 接口。 cdylib 不包含在其上使用 extern crate 所需的元数据,因此对于此类依赖项,Cargo 甚至不会将 --extern 传递给 rustc。如果你想要一个 C 接口一个 Rust 接口,请改用crate-type = ["cdylib", "lib"](或者如果你想要一个动态库,则使用crate-type = ["cdylib", "dylib"])。如果你只需要一个 Rust 接口,请省略 crate-type
猜你喜欢
  • 1970-01-01
  • 2021-09-26
  • 2019-11-19
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
相关资源
最近更新 更多