我有一个直接从GitHub导入的箱子,按照货物的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
中,lib
文件的Cargo.toml
部分指定为:
[package]
name = "libfoo"
[lib]
name = "foo"
crate-type = ["cdylib"]
我已经尝试了libfoo和foo的所有排列,看看Cargo是否在lib名称和包/目录名之间感到困惑。
如果我指定了依赖项的本地路径,它也会失败。 (Cargo编译依赖项,但声称在lib.rs
中声明/导入时不会找到它。)
[dependencies]
libfoo = { path = "/Users/me/dev/libfoo" }
如果我从git或与[lib]
名称具有相同[package]
名称的文件系统中包含一个包,它可以正常工作。因此,问题似乎是包含的库([lib]
)名称与包([package]
)名称不同。
如果我从依赖项的[lib]
文件中删除Cargo.toml
部分,它就可以正常工作。
更新:如果从crate-type = ["cdylib"]
移除了libfoo
,则可以使用已导入的foo
。如果那样,我在extern crate foo;
时会遇到同样的错误。
答案 0 :(得分:8)
当涉及到依赖关系时,Cargo对包名称感兴趣,而编译器(rustc
)在加载他们的库名时感兴趣元数据并与它们链接。
让我们再看看这个Cargo.toml
摘录:
[package]
name = "libfoo"
[lib]
name = "foo"
此处,包名称为libfoo
,库名称为foo
。
如果要在项目中声明对libfoo
的依赖关系,则需要在libfoo
表中编写包名称([dependencies]
)。例如:
[dependencies]
libfoo = { git = "ssh://git@github.com/me/libfoo", branch = "dev" }
这是你已经拥有的,这是正确的。
但是,如果要在包中导入库,则需要在extern crate
项中编写库名,即
extern crate foo;
我是怎么想出来的?首先,我在libfoo
和Cargo.toml
项中写了extern crate
,正如您所描述的那样。当我运行cargo build
时,我注意到libfoo
已成功构建,表明Cargo正确解决了依赖关系。但我也注意到,编译器无法找到libfoo
,正如您所经历的那样。
然后,我通过运行rustc
检查了传递给cargo build --verbose
的命令行。这就是我所看到的(省略了相关部分):
Running `rustc [...] --extern foo=/[path]/target/debug/deps/libfoo-5cf876c5c8ac1bfb.rlib`
--extern name=path
参数告诉rustc
名为name
的包位于path
。这里的名称是foo
,因此我们必须在代码中编写extern crate foo;
来引用它。