根据Cargo的文档,我有一个直接从GitHub导入的箱子:
[dependencies]
libfoo = { git = "ssh://git@github.com/me/libfoo", branch = "dev" }
[lib]
path = "src/rust/lib.rs"
name = "myprj"
crate-type = ["cdylib"]
Run Code Online (Sandbox Code Playgroud)
运行cargo build正常,Cargo libfoo在~/.cargo目录中提取并构建它.当我尝试使用(导入)它时lib.rs:
extern crate libfoo; //also tried foo
Run Code Online (Sandbox Code Playgroud)
货物扼流圈:
error[E0463]: can't find crate for `libfoo`
--> src/rust/lib.rs:1:1
|
1 | extern crate libfoo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
Run Code Online (Sandbox Code Playgroud)
有趣的是,当我点击它时,IntelliJ的Rust插件确实找到了箱子lib.rs- 它导航到下载的源~/.cargo...
在依赖项中libfoo,文件的lib部分Cargo.toml指定为:
[package]
name = "libfoo"
[lib]
name = "foo"
crate-type = ["cdylib"]
Run Code Online (Sandbox Code Playgroud)
我已经尝试了libfoo和foo的所有排列,看看Cargo是否在lib名称和包/目录名称之间感到困惑.
如果我指定依赖项的本地路径,它也会失败.(Cargo编译依赖项,但声称在声明/导入时不会找到它lib.rs.)
[dependencies]
libfoo = { path = "/Users/me/dev/libfoo" }
Run Code Online (Sandbox Code Playgroud)
如果我从git或与[lib]名称同名的文件系统中包含一个包[package],它可以正常工作.所以看来问题是crates的library([lib])名称与package([package])名称不同.
如果我[lib]从依赖项的Cargo.toml文件中删除该部分,它可以工作.
更新:如果crate-type = ["cdylib"]删除libfoo,则适用于foo导入.如果那样,我得到同样的错误extern crate foo;.
当涉及到依赖关系时,Cargo对包名称感兴趣,而在加载元数据和链接它们时,compiler(rustc)对库名称感兴趣.
让我们再来看看这段Cargo.toml摘录:
[package]
name = "libfoo"
[lib]
name = "foo"
Run Code Online (Sandbox Code Playgroud)
这里,包名是libfoo,库名是foo.
如果要libfoo在项目中声明依赖项,则需要在表中编写包名称(libfoo)[dependencies].例如:
[dependencies]
libfoo = { git = "ssh://git@github.com/me/libfoo", branch = "dev" }
Run Code Online (Sandbox Code Playgroud)
这就是你已经拥有的,这是正确的.
但是,如果要在包中导入库,则需要在项中编写库名extern crate,即
extern crate foo;
Run Code Online (Sandbox Code Playgroud)
我怎么知道这个?首先,正如你所描述的那样,我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`
Run Code Online (Sandbox Code Playgroud)
该--extern name=path参数告诉rustc名字的箱子name位于path.这里的名字是foo,所以我们必须extern crate foo;在代码中写入引用它.