当库名与包名不同时如何导入 crate 依赖项? [英] How to import a crate dependency when the library name is different from the package name?

查看:34
本文介绍了当库名与包名不同时如何导入 crate 依赖项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 Cargo 的 文档:

I have a crate that is imported straight off of GitHub, as per Cargo's 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 中使用(导入)它时:

Running cargo build works fine here, Cargo fetches libfoo and builds it in the ~/.cargo directory. When I try to use (import) it in 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 插件确实找到了 crate——它导航到 ~/.cargo 中的下载源...

Interestingly, IntelliJ's Rust plugin does find the crate when I click on it in lib.rs – it navigates to the downloaded source in ~/.cargo...

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

In the dependency libfoo, the lib section of the Cargo.toml file is specified as:

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

我已经尝试了 libfoo 和 foo 的所有排列,以查看 Cargo 是否在 lib 名称和包/目录名称之间混淆.

I have tried all permutations of libfoo and foo to see if Cargo is getting confused between the lib name and the package/directory name.

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

It also fails if I specify a local path to the dependency. (Cargo compiles the dependency but then claims not to find it when it is declared/imported in lib.rs.)

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

如果我从 git 或文件系统中包含一个与 [package] 名称相同的 [lib] 名称的 crate,它可以正常工作.因此,问题似乎出在库 ([lib]) 名称与包 ([package]) 名称不同的 crate 上.

If I include a crate from git or the file system that has the same [lib] name as the [package] name, it works fine. So it appears the problem is with crates that have a have a library ([lib]) name that is different from the package ([package]) name.

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

If I remove the [lib] section from the dependency's Cargo.toml file, it works.

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

Update: if crate-type = ["cdylib"] is removed from libfoo, this works with foo imported. If that is there, I get the same error with extern crate foo;.

推荐答案

Cargo 对 包名 感兴趣,而编译器 (rustc) 是对库名称感兴趣,以便加载元数据并与之链接.

Cargo is interested in package names when it comes to dependencies, while the compiler (rustc) is interested in library names when it comes to loading their metadata and linking with them.

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

Let's take a look again at this Cargo.toml excerpt:

[package]
name = "libfoo"

[lib]
name = "foo"

这里,包名libfoo库名foo.

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

When you want to declare a dependency on libfoo in your project, you need to write the package name (libfoo) in the [dependencies] table. For example:

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

这是你已经拥有的,而且是正确的.

This is what you already have, and it's correct.

然而,当你想在你的 crate 中导入库时,你需要在 extern crate 项中写入 library name,即

However, when you want to import the library in your crate, you need to write the library name in the extern crate item, i.e.

extern crate foo;

<小时>

我是怎么想出来的?首先,我在 Cargo.tomlextern crate 项中都编写了 libfoo,正如您所描述的.当我运行cargo build时,发现libfoo构建成功,说明Cargo正确解析了依赖.但我也注意到编译器找不到 libfoo,正如您所经历的那样.


How did I figure this out? First, I wrote libfoo in both Cargo.toml and the extern crate item, as you described. When I ran cargo build, I noticed that libfoo was built successfully, indicating that Cargo correctly resolved the dependency. But I also noticed that the compiler couldn't find libfoo, as you experienced.

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

I then inspected the command line passed to rustc by running cargo build --verbose. This is what I saw (irrelevant parts omitted):

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

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

The --extern name=path argument tells rustc that the crate named name is located in path. The name here is foo, so we must write extern crate foo; in the code to reference it.

这篇关于当库名与包名不同时如何导入 crate 依赖项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆