当库名与包名不同时如何导入 crate 依赖项? [英] How to import a crate dependency when the library name is different from the package name?
问题描述
根据 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.toml
和 extern 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屋!