| title | Crates and Packages |
|---|---|
| slug | crates-and-Packages |
-
A crate is the smallest unit of compilation in Rust.
-
A crate compiles as a single unit. If it contains modules in separate files, the compiler builds an isolated module tree starting from the crate root before compilation.
-
Each crate maintains its own module tree rooted at the crate root:
- Binary crates:
src/main.rsor a.rsfile in thesrc/bin/directory - Library crates: Usually
src/lib.rs
- Binary crates:
-
Main crate types are,
Type Description binExecutable program libLet the compiler decide the library type. Defaults to rlibrlibStatic library for linking into other Rust crates. staticlibStatic library for linking into non-Rust programs dylibRust dynamic library (rarely used) cdylibDynamic library for C/FFI and other non-Rust programs proc-macroLibrary crate that defines procedural macros [!tip] To configure the library crate type/ types, we can use the
[lib]section ofCargo.toml.[lib] crate-type = ["rlib", "cdylib"] // Rust library + C-compatible dynamic library
- A package is a Cargo project containing one or more crates, described by a
Cargo.tomlmanifest. - A Cargo package can contain:
- Zero or more binary crates
- Zero or one library crate
- Typical package layouts are,
src/main.rs: A package with single binary crate.src/lib.rs: A package with single library crate.src/bin/*.rs: A package with multiple binary crates.src/main.rs+src/lib.rs: A package with 1 binary crate + 1 library crate.src/bin/*.rs+src/lib.rs: A package with multiple binary crates + 1 library crate.
my_app
├── Cargo.toml
└── src
└── main.rs[!lab]
cargo new my_app cd my_app && cargo run
my_app
├── Cargo.toml
└── src
└── lib.rs[!lab]
cargo new my_app --lib cd my_app && cargo test
my_app
├── Cargo.toml
└── src
├── lib.rs
└── main.rs{{< tabs count=3 label="Select File" >}} {{< tab label="lib.rs" >}}
pub fn greet() {
println!("Hello Lib!");
}{{< /tab >}} {{< tab label="main.rs" >}}
fn main() {
my_app::greet();
}{{< /tab >}} {{< tab label="Cargo.toml" >}}
[package]
name = "my_app"
version = "0.1.0"
edition = "2024"
[dependencies]{{< /tab >}} {{< /tabs >}}
[!lab]
cargo new my_app cd my_app && touch src/lib.rs $copy above file content cargo run
my_app
├── Cargo.toml
└── src
└── bin
├── app.rs
└── cli.rs{{< tabs count=3 label="Select File" >}} {{< tab label="app.rs" >}}
pub fn greet() {
println!("Hello App!");
}{{< /tab >}} {{< tab label="cli.rs" >}}
pub fn greet() {
println!("Hello Cli!");
}{{< /tab >}} {{< tab label="Cargo.toml" >}}
[package]
name = "my_app"
version = "0.1.0"
edition = "2024"
default-run = "app"
[[bin]]
name = "app"
path = "src/bin/app.rs"
[[bin]]
name = "cli"
path = "src/bin/cli.rs"
[dependencies]{{< /tab >}} {{< /tabs >}}
[!lab]
cargo new my_app && cd my_app mkdir src/bin && mv src/main.rs src/bin/app.rs && cp src/bin/app.rs src/bin/cli.rs $copy above file content
- Run
appbinary crate:cargo run --bin app/cargo run(asCargo.toml->default-run = "app")- Run
clibinary crate:cargo run --bin cli
my_app
├── Cargo.toml
└── src
├── bin
│ ├── app.rs
│ └── cli.rs
└── lib.rs[!assignment]
cargo new my_app --lib && cd my_app mkdir -p src/bin && touch src/bin/app.rs src/bin/cli.rs $write sample file content
- A project dependency can be added from:
- crates.io - Rust's official package registry
- A Git repository
- A folder path
[!tip] Tip:
cargo add <PACKAGE>
-n/--dry-run: Preview changes without modifyingCargo.toml. Ex:cargo add uuid -n-F/--features <FEATURES>: Enable specific features. Ex:cargo add uuid -F v7,fast-rng
uuid = { version = "1.23.4", features = ["v7", "fast-rng"] }(💡Cargo.toml [dependencies])--rename <NAME>: Rename the dependency. Ex.cargo add uuid --rename id
id = { version = "1.23.4", package = "uuid" }(💡Cargo.toml [dependencies])- Source: A Git repository
--git <URI>: Git repository location.--branch <BRANCH>: Git branch to download the crate from--tag <TAG>: Git tag to download the crate from.--rev <REV>: Git reference to download the crate from- Ex.
cargo add uuid --git https://github.com/uuid-rs/uuidcargo add uuid --git https://github.com/uuid-rs/uuid --tag v1.23.4- Source: A local crate
--path <PATH>: Filesystem path to local crate to add- Ex.
cargo add foo --path foo(💡my_app/foo/)
[!lab]
cargo new my_app && cd my_app cargo add uuid -F v7 $copy main.rs file content cargo run
{{< tabs count=2 label="Select File" >}} {{< tab label="main.rs" >}}
use uuid::Uuid;
fn main() {
println!("{}", Uuid::now_v7());
}{{< /tab >}} {{< tab label="Cargo.toml" >}}
[package]
name = "my_app"
version = "0.1.0"
edition = "2024"
[dependencies]
uuid = { version = "1.23.4", features = ["v7"] }{{< /tab >}} {{< /tabs >}}
[!lab]
cargo new my_app && cd my_app cargo add uuid --git https://github.com/uuid-rs/uuid --tag v1.23.4 -F v7 $copy main.rs file content cargo run
{{< tabs count=2 label="Select File" >}} {{< tab label="main.rs" >}}
use uuid::Uuid;
fn main() {
println!("{}", Uuid::now_v7());
}{{< /tab >}} {{< tab label="Cargo.toml" >}}
[package]
name = "my_app"
version = "0.1.0"
edition = "2024"
[dependencies]
uuid = { git = "https://github.com/uuid-rs/uuid", tag = "v1.23.4", version = "1.23.4", features = ["v7"] }{{< /tab >}} {{< /tabs >}}
[!lab]
cargo new my_app && cd my_app cargo new foo --lib cargo add foo --path foo $copy my_app/foo/src/lib.rs and my_app/src/main.rs file content cargo run
{{< tabs count=3 label="Select File" >}} {{< tab label="foo/src/lib.rs" >}}
pub fn greet() {
println!("Hello Foo");
}{{< /tab >}} {{< tab label="src/main.rs" >}}
use foo;
fn main() {
foo::greet();
}{{< /tab >}} {{< tab label="Cargo.toml" >}}
[package]
name = "my_app6"
version = "0.1.0"
edition = "2024"
[dependencies]
foo = { version = "0.1.0", path = "foo" }{{< /tab >}} {{< /tabs >}}