Cargo and Package Management
Cargo Fundamentals
Cargo is Rust's official build system, package manager, dependency resolver, and test/documentation orchestrator. Instead of invoking rustc manually with long lists of --extern library paths and compiler flags, developers interact with cargo, which reads a declarative manifest (Cargo.toml), downloads and compiles dependencies in topological order, and caches build artifacts inside the target/ directory.
+-------------------------------------------------------------------+
| Cargo Workflow |
| |
| Cargo.toml (Manifest) + Cargo.lock (Exact Versions) |
| | |
| v |
| [ Dependency Resolver ] ---> Downloads crates from crates.io |
| | |
| v |
| [ Build Graph Planner ] ---> Invokes `rustc` / `rustdoc` |
| | |
| v |
| target/debug/ or target/release/ (Cached Artifacts) |
+-------------------------------------------------------------------+
Standard Cargo Package Layout
When you run cargo new my_app (or cargo new --lib my_lib), Cargo scaffolds a standardized directory layout that follows convention over configuration:
my_package/
├── .gitignore
├── Cargo.toml <-- Package manifest (metadata, dependencies, profiles)
├── Cargo.lock <-- Exact resolved dependency versions (generated by Cargo)
├── build.rs <-- Optional custom pre-build script
├── src/
│ ├── lib.rs <-- Default library crate root (at most 1 per package)
│ ├── main.rs <-- Default binary crate root
│ └── bin/ <-- Additional binary crate roots (`src/bin/*.rs`)
├── examples/ <-- Runnable example programs (`cargo run --example <name>`)
├── tests/ <-- Integration test suites (`cargo test`)
└── benches/ <-- Benchmark suites (`cargo bench`)
Core Responsibilities of Cargo
| Responsibility | What Cargo Does Automatically |
|---|---|
| Project Scaffolding | Creates a new package (cargo new) or initializes an existing directory (cargo init) with Git configuration. |
| Dependency Resolution | Resolves SemVer-compatible crate graphs (using the MSRV-aware Resolver v3 in edition = "2024"), downloads archives, and records exact SHA-256 checksums in Cargo.lock. |
| Incremental Compilation | Tracks source file modification timestamps, feature flags, and environment variables so cargo check and cargo build only recompile changed crates. |
| Target Orchestration | Passes exact --crate-type, --edition, -C opt-level, and --cfg flags to rustc and rustdoc. |
Inspecting Metadata Injected by Cargo at Compile Time
Whenever Cargo invokes rustc, it injects compile-time CARGO_* environment variables that code can inspect via env!:
fn main() {
let pkg_name = option_env!("CARGO_PKG_NAME").unwrap_or("standalone_bin");
let pkg_version = option_env!("CARGO_PKG_VERSION").unwrap_or("0.1.0");
println!("Package: {pkg_name} v{pkg_version}");
}
Package: standalone_bin v0.1.0