2016-09-25 70 views
1

我正在学习Rust并决定编写一个简单的客户端/服务器程序。客户端和服务器都将使用我已经编写的非常简单的模块。知道这个代码可能会增长,我决定将我的源代码清晰化。现在我目前的层次看起来如下:从多个非根二进制文件导入非根模块

├── Cargo.lock 
├── Cargo.toml 
├── README.md 
├── src 
│   ├── client 
│   │   └── main.rs 
│   ├── common 
│   │   ├── communicate.rs 
│   │   └── mod.rs 
│   ├── lib.rs 
│   └── server 
│    └── main.rs 

Manyofthe的例子,我对堆栈溢出发现和网提供当main.rs是在项目的根目录大样本。不幸的是,我试图做一些不同的东西,如上所示。

communicate.rs包含我写的所有网络代码。最终我会在这里添加其他Rust文件,并在mod.rs中包含它们的public mod声明。目前common/mod.rs我只有 pub mod communicate;

将注意力集中在了client文件夹,我只有main.rs如图所示。文件“头”列出

extern crate common; 

use std::thread; 
use std::time; 
use std::net; 
use std::mem; 

use common::communicate; 

pub fn main() { 
    // ... 
} 

除了基本[package]部分,所有我在Cargo.toml

[[bin]] 
name = "server" 
path = "src/server/main.rs" 

[[bin]] 
name = "client" 
path = "src/client/main.rs" 

当我尝试建立客户端二进制,编译器抱怨说,common箱不能被发现。

$ cargo build 
    Compiling clientserver v0.1.0 (file:///home/soplu/rust/RustClientServer) 
client/main.rs:1:1: 1:21 error: can't find crate for `common` [E0463] 
client/main.rs:1 extern crate common; 
       ^~~~~~~~~~~~~~~~~~~~ 
error: aborting due to previous error 
error: Could not compile `clientserver`. 

To learn more, run the command again with --verbose. 

我想这是因为它正在寻找client/文件夹中常见的箱。当我尝试使用mod声明而不是extern crate声明时,我遇到了同样的问题。

use std::thread; 
use std::time; 
use std::net; 
use std::mem; 

mod common; 

递给我:

client/main.rs:6:5: 6:11 error: file not found for module `common` 
client/main.rs:6 mod common; 
        ^~~~~~ 
client/main.rs:6:5: 12:11 help: name the file either common.rs or common/mod.rs inside the directory "client" 

我也尝试(使用extern crate...)中,其内容pub mod common;但我仍然得到同样的错误为先的client添加lib.rs

我发现将其建模为this project的一种潜在解决方案,但这需要在每个文件夹中有一个Cargo.toml,这是我想避免的。

我觉得我很接近但错过了一些东西。

回答

1

您现在没有将common作为箱子。正在构建的包装箱是库clientserver(库的默认名称是包名称)以及二进制文件clientserver

正常情况下,extern crate clientserver;应该工作。但是,如果要以不同的名称命名库,可以通过在[lib] section in Cargo.toml中指定不同的名称来完成。在本节中,您还可以为库的主源文件指定不同的源路径。在你的情况下,它可能会更好,否则你最终会得到一个名为common的箱子,它的所有内容都将存放在一个名为common的模块中,因此您必须访问所有内容,如common::common::foo。例如,通过添加以下内容到Cargo.toml:

[lib] 
name = "common" 
path = "src/common/lib.rs" 

你可以结合src/lib.rssrc/common/mod.rssrc/common/lib.rs。然后,extern crate common;应该在你的二进制文件中工作。

+0

完美,这解决了我的问题。你的第一个声明实际上帮助我清除了我试图产生的东西。谢谢。我可以使用相同的方法声明多个库吗?类似于 '[lib]' 'name =“otherlib”' 'path =“src/otherlib/lib.rs”' – soplu

+0

Cargo只支持每个包一个库。您可以使用[路径依赖项](http://doc.crates.io/specifying-dependencies.html#specifying-path-dependencies)在Cargo.toml中引用本地包。 –