Skip to content

Commit 1a93d03

Browse files
committed
Workspaces
1 parent 13ce5dc commit 1a93d03

40 files changed

Lines changed: 257 additions & 184 deletions

File tree

β€Žcontent/en/docs/d5.workspaces.mdβ€Ž

Lines changed: 135 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,78 +3,154 @@ title: Workspaces
33
slug: workspaces
44
---
55

6-
> [!caution]
7-
> This needs a refresh!
8-
9-
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.
10-
11-
⭐️ 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.
12-
13-
Let's create a library crate with a simple hello world function and a binary crate which uses the library crate.
14-
15-
Assume we run,
16-
```bash
17-
mkdir greetings
18-
touch greetings/Cargo.toml
19-
cargo new greetings/lib --lib
20-
cargo new greetings/examples/hello
6+
## Rust Workspaces
7+
8+
- Rust workspaces provide a convenient way to manage multiple related crates together as a single project or monorepo.
9+
- A Rust workspace uses a shared `Cargo.lock` file and a common `target` directory to efficiently build and manage shared dependencies, reducing build times.
10+
- Cargo commands such as `cargo test`, `cargo build`, `cargo check`, `cargo fmt`, `cargo clippy`, and `cargo clean` can be run once from the workspace root to apply to all workspace members.
11+
12+
## Simple
13+
14+
Let's build a sample Rust workspace with two simple crates.
15+
16+
> [!lab]
17+
> ```shell
18+
> mkdir my_project && cd my_project
19+
> echo -e "[workspace]\nresolver = \"3\"" > ./Cargo.toml
20+
> cargo new app_bar && cargo new app_buzz
21+
> cargo add uuid -F v7 -p app_bar && cargo add uuid -F v7 -p app_buzz
22+
>
23+
> echo 'fn main() {
24+
> \tprintln!("Bar ID: {}", uuid::Uuid::now_v7());
25+
> }' > app_bar/src/main.rs
26+
>
27+
> echo 'fn main() {
28+
> \tprintln!("Buzz ID: {}", uuid::Uuid::now_v7());
29+
> }' > app_buzz/src/main.rs
30+
> ```
31+
32+
```shell {title="Folder Structure"}
33+
my_project
34+
β”œβ”€β”€ app_bar
35+
β”‚ β”œβ”€β”€ Cargo.toml
36+
β”‚ └── src
37+
β”‚ └── main.rs
38+
β”œβ”€β”€ app_buzz
39+
β”‚ β”œβ”€β”€ Cargo.toml
40+
β”‚ └── src
41+
β”‚ └── main.rs
42+
β”œβ”€β”€ Cargo.lock
43+
└── Cargo.toml
2144
```
2245
23-
That generates,
24-
```bash
25-
greetings
26-
β”œβ”€β”€ Cargo.toml
27-
β”œβ”€β”€ examples
28-
β”‚ └── hello
29-
β”‚ β”œβ”€β”€ Cargo.toml
30-
β”‚ └── src
31-
β”‚ └── main.rs
32-
└── lib
33-
β”œβ”€β”€ Cargo.toml
34-
└── src
35-
└── lib.rs
46+
{{< tabs count=3 label="Select File" >}}
47+
{{< tab label="app_bar β†’ main.rs" >}}
48+
```rust {title="my_project/app_bar/src/main.rs"}
49+
fn main() {
50+
println!("Bar ID: {}", uuid::Uuid::now_v7());
51+
}
3652
```
37-
38-
We have to modify the following files,
39-
```rust
40-
// 01. greetings/Cargo.toml to mark as a workspace and to add members
53+
{{< /tab >}}
54+
{{< tab label="app_buzz β†’ main.rs" >}}
55+
```rust {title="my_project/app_buzz/src/main.rs"}
56+
fn main() {
57+
println!("Buzz ID: {}", uuid::Uuid::now_v7());
58+
}
59+
```
60+
{{< /tab >}}
61+
{{< tab label="Cargo.toml" >}}
62+
```toml {title="my_project/Cargo.toml"}
4163
[workspace]
42-
members = [
43-
"lib",
44-
"examples/hello"
45-
]
64+
resolver = "3"
65+
members = ["app_bar", "app_buzz"]
66+
```
67+
{{< /tab >}}
68+
{{< /tabs >}}
69+
70+
As you can see,
71+
- Cargo commands can automatically add workspace members to the `Cargo.toml` file in the workspace root(`my_project`).
72+
- Try running `cargo build` and observe how each dependency is compiled only once through the shared `target` directory in the workspace root.
73+
74+
> [!assignment]
75+
> - Examine the `Cargo.toml` files in the workspace root and in each crate, and identify the main tables(sections) they contain.
76+
> - Examine the `Cargo.lock` file in the workspace root and identify how the `app_buzz` and `app_bar` crates record their dependencies.
77+
> - Run `cargo run -p app_bar` and `cargo run -p app_buzz` commands from the workspace root.
78+
79+
## Advanced
80+
81+
> [!lab]
82+
> ```
83+
> mkdir my_project2 && cd my_project2
84+
> echo -e "[workspace]\nresolver = \"3\"\nmembers = [\"crates/*\"]" > ./Cargo.toml
85+
> cargo new crates/bar && cargo new crates/buzz
86+
> cargo new crates/common --lib
87+
> ```
88+
89+
```shell {title="Folder Structure"}
90+
my_project
91+
β”œβ”€β”€ crates
92+
β”‚ β”œβ”€β”€ bar
93+
β”‚ β”‚ β”œβ”€β”€ Cargo.toml
94+
β”‚ β”‚ └── src
95+
β”‚ β”‚ └── main.rs
96+
β”‚ β”œβ”€β”€ buzz
97+
β”‚ β”‚ β”œβ”€β”€ Cargo.toml
98+
β”‚ β”‚ └── src
99+
β”‚ β”‚ └── main.rs
100+
β”‚ └── common
101+
β”‚ β”œβ”€β”€ Cargo.toml
102+
β”‚ └── src
103+
β”‚ └── lib.rs
104+
β”œβ”€β”€ Cargo.toml
105+
└── Cargo.lock
106+
```
46107
47-
// 02.1 greetings/lib/Cargo.toml to change the package name to greetings
108+
- To use the `common` crate from `crates/bar` and `crates/buzz`,
109+
- We have to add `common` crate as a dependency in both `crates/bar/Cargo.toml` and `crates/buzz/Cargo.toml`.
110+
```toml
111+
[dependencies]
112+
common = { path = "../common" }
113+
```
114+
- Then, we can use the `common` crate like any other dependency in `crates/bar` and `crates/buzz`.
115+
```rust
116+
fn main() {
117+
let x = common::add(1, 1);
118+
println!("{x}");
119+
}
120+
```
121+
122+
{{< tabs count=3 label="Select File" >}}
123+
{{< tab label="bar β†’ Cargo.toml" >}}
124+
```toml {title="my_project2/crates/bar/Cargo.toml"}
48125
[package]
49-
name = "greetings"
126+
name = "bar"
50127
version = "0.1.0"
51-
authors = ["Dumindu Madunuwan"]
128+
edition = "2024"
52129

53130
[dependencies]
54-
55-
// 02.2 greetings/lib/src/lib.rs to add a simple hello world function
56-
pub fn hello() {
57-
println!("Hello, world!");
58-
}
59-
60-
// 03.1 greetings/examples/hello/Cargo.toml to add the `greetings` lib as a dependency
131+
common = { path = "../common" }
132+
```
133+
{{< /tab >}}
134+
{{< tab label="buzz β†’ Cargo.toml" >}}
135+
```toml {title="my_project2/crates/buzz/Cargo.toml"}
61136
[package]
62-
name = "hello"
137+
name = "buzz"
63138
version = "0.1.0"
64-
authors = ["Dumindu Madunuwan"]
139+
edition = "2024"
65140

66141
[dependencies]
67-
greetings = { path = "../../lib" }
68-
69-
// 03.2 greetings/examples/hello/src/main.rs to import the `greetings` lib and call its hello world function
70-
extern crate greetings;
71-
72-
fn main() {
73-
greetings::hello();
74-
}
142+
common = { path = "../common" }
75143
```
144+
{{< /tab >}}
145+
{{< tab label="my_project2 β†’ Cargo.toml" >}}
146+
```toml {title="my_project/Cargo.toml"}
147+
[workspace]
148+
resolver = "3"
149+
members = ["crates/*"]
150+
```
151+
{{< /tab >}}
152+
{{< /tabs >}}
76153

77-
πŸ’‘ 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.
154+
## πŸ‘¨β€πŸ« Before going to the next...
78155

79-
> [!assignment]
80-
> [rust-lang/rust library folder](https://github.com/rust-lang/rust/tree/main/library) is a good example for a workspace.
156+
- [rust-lang/rust library folder](https://github.com/rust-lang/rust/tree/main/library) is a good example for a workspace. Explore and identify Rust library workspace structure.

β€Ždocs/assets/js/docs.min.43f62ec3fea83ddf9f255731e2b5a0e9694fb8c3199634f3bfdafeefe9b720cc.jsβ€Ž

Lines changed: 0 additions & 1 deletion
This file was deleted.

β€Ždocs/assets/js/docs.min.e183be143fc7b87545ffa964089b780f9e8418abeaf311a1092975a438a6b1bb.jsβ€Ž

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

β€Ždocs/docs/borrowing/index.htmlβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,4 @@
417417
<svg height="20" viewBox="0 -960 960 960" width="20"><path d="M216-96q-29.7.0-50.85-21.5T144-168v-528q0-29 21.15-50.5T216-768h72v-60q0-15.3 10.29-25.65Q308.58-864 323.79-864t25.71 10.35Q360-843.3 360-828v60h240v-60q0-15.3 10.29-25.65Q620.58-864 635.79-864t25.71 10.35Q672-843.3 672-828v60h72q29.7.0 50.85 21.5T816-696v528q0 29-21.15 50.5T744-96H216zm0-72h528v-360H216v360zm0-432h528v-96H216v96zm0 0v-96 96z"/></svg>
418418
2016-2026
419419
<svg height="20" viewBox="0 -960 960 960" width="20"><path d="M319-521q14-28 30.5-54.5T384-628l-55-7-88 88 78 26zm455-270q-79 2-148 41t-125 96q-38 38-68 81t-54 91l102 102q48-24 91-54t81-68q57-57 97.5-129T791-775q0-3-1.5-6t-3.5-5q-2-3-5-4t-7-1zM528-6e2q0-30 21-51t51-21 51 21 21 51-21 51-51 21-51-21-21-51zm-7 281 26 78 88-88-7-55q-26 18-52.5 34.5T521-319zm340-504q13 104-31.5 198T710-456l-8.5 8.5Q698-444 694-439l12 101q2 17-3.5 33T685-278L552-145q-14 13-31.5 9.5T498-156l-51-155-135-136-156-53q-17-5-20-22.5t10-30.5l132-133q12-12 27.5-17.5T338-707l101 13q5-5 9.5-9t9.5-9q75-74 168-119t196-31q8 1 14.5 5t11.5 9 8.5 11 4.5 14zM178-331q31-32 75-30.5t76 33.5q31 31 32.5 74T332-181q-45 47-108.5 60.5T96-96q11-63 24-126.5T178-331zm45 57q-17 17-23 40l-12 46q23-6 45-12t39-23q13-11 14.5-27.5T277-278t-27-9.5T223-274z"/></svg>
420-
<a class="btn btn-primary" href=https://github.com/learning-rust/learning-rust.github.io target=_blank>GitHub</a></footer></div><div id=off-canvas-model></div><script src=/assets/js/docs.min.43f62ec3fea83ddf9f255731e2b5a0e9694fb8c3199634f3bfdafeefe9b720cc.js integrity></script><script src=https://learning-rust.github.io/pagefind/pagefind-component-ui.js type=module></script></body></html>
420+
<a class="btn btn-primary" href=https://github.com/learning-rust/learning-rust.github.io target=_blank>GitHub</a></footer></div><div id=off-canvas-model></div><script src=/assets/js/docs.min.e183be143fc7b87545ffa964089b780f9e8418abeaf311a1092975a438a6b1bb.js integrity></script><script src=https://learning-rust.github.io/pagefind/pagefind-component-ui.js type=module></script></body></html>

0 commit comments

Comments
Β (0)