Workspaces

When the code base is getting larger, you might need to work with multiple crates on the same project. Rust supports this via Workspaces. You can analyze (cargo check), build, run tests or generate docs for all crates at once by running cargo commands from the project root.

⭐️ When working on multiple crates same time, there is a higher possibility of having shared dependencies on crates. To prevent downloading and compiling the same dependency multiple times, Rust uses a shared build directory under the project root, while running cargo build from the project root.

Let’s create a library crate with a simple hello world function and a binary crate which uses the library crate.

Assume we run,

mkdir greetings
touch greetings/Cargo.toml
cargo new greetings/lib --lib
cargo new greetings/examples/hello

That generates,

greetings
 ├── Cargo.toml
 ├── examples
 │  └── hello
 │     ├── Cargo.toml
 │     └── src
 │        └── main.rs
 └── lib
    ├── Cargo.toml
    └── src
       └── lib.rs

We have to modify the following files,

// 01. greetings/Cargo.toml to mark as a workspace and to add members
[workspace]
members = [
    "lib",
    "examples/hello"
]

// 02.1 greetings/lib/Cargo.toml to change the package name to greetings
[package]
name = "greetings"
version = "0.1.0"
authors = ["Dumindu Madunuwan"]

[dependencies]

// 02.2 greetings/lib/src/lib.rs to add a simple hello world function
pub fn hello() {
    println!("Hello, world!");
}

// 03.1 greetings/examples/hello/Cargo.toml to add the `greetings` lib as a dependency
[package]
name = "hello"
version = "0.1.0"
authors = ["Dumindu Madunuwan"]

[dependencies]
greetings = { path = "../../lib" }

// 03.2 greetings/examples/hello/src/main.rs to import the `greetings` lib and call its hello world function
extern crate greetings;

fn main() {
    greetings::hello();
}

💡 On Linux and Mac, you can run cargo commands on each crate without changing the working directory all the times via Subshells (A command list embedded between parentheses). For example, if you are in the greetings directory, even you run (cd examples/hello && cargo run) your working directory will be kept as same in greetings folder.

🔎 rust-lang/rust source folder is a good example for a workspace.