Reputation: 145
I am learning Rust and decided to write a simple client/server program. Both the client and the server will be using a very simple module I've already written. Knowing that this code might grow, I decided to compartmentalize my source for clarity. Right now my current hierarchy looks as follows:
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│ ├── client
│ │ └── main.rs
│ ├── common
│ │ ├── communicate.rs
│ │ └── mod.rs
│ ├── lib.rs
│ └── server
│ └── main.rs
Many of the examples I found on Stack Overflow and the net provide great samples for when the main.rs
is in the project root directory. Unfortunately I'm trying to do something different as shown above.
communicate.rs
contains all of the network code I have written. Eventually I will add other Rust files here and include their public mod
statement in mod.rs
. Currently common/mod.rs
all I have is
pub mod communicate;
Focusing on just the client
folder, all I have is main.rs
as shown. The file "header" lists
extern crate common;
use std::thread;
use std::time;
use std::net;
use std::mem;
use common::communicate;
pub fn main() {
// ...
}
Besides the fundamental [package]
section, all I have in Cargo.toml
is
[[bin]]
name = "server"
path = "src/server/main.rs"
[[bin]]
name = "client"
path = "src/client/main.rs"
When I try to build the client binary, the compiler complains that the common
crate could not be found.
$ 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.
I think this is because it is looking for a common crate within the client/
folder. I had this same problem when I tried the mod
statement instead of extern crate
statement.
use std::thread;
use std::time;
use std::net;
use std::mem;
mod common;
Gave me:
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"
I also tried (using the extern crate...
) adding a lib.rs
in the client
whose contents are pub mod common;
but I still get the same error as the first.
One potential solution I found to model it like this project, but this would require a Cargo.toml
in every folder, something which I'd like to avoid.
I feel like I am close but am missing something.
Upvotes: 3
Views: 1019
Reputation: 65752
You are not building common
as a crate right now. The crates being built are the library clientserver
(the default name for the library is the package name) and the binaries client
and server
.
Normally, extern crate clientserver;
should work. However, if you want to name your library differently, you can do so by specifying a different name in a [lib]
section in Cargo.toml. In this section, you can also specify a different source path for the library's main source file. In your case, it will probably be better, otherwise you'll end up with a crate named common
and all of its contents would be in a module named common
, so you'd have to access everything as common::common::foo
. For example, by adding this to your Cargo.toml:
[lib]
name = "common"
path = "src/common/lib.rs"
you could combine src/lib.rs
and src/common/mod.rs
into src/common/lib.rs
. Then, extern crate common;
should work in your binaries.
Upvotes: 1