Cargo and Package Management

Binary Crates

A binary crate compiles into a standalone executable program containing an entrypoint function fn main(). A single Cargo package can define one default binary (src/main.rs) as well as any number of additional binary targets inside src/bin/ or via explicit [[bin]] sections in Cargo.toml.

Multi-Binary Package Structure:
my_service/
├── Cargo.toml               (name = "my_service", default-run = "my_service")
└── src/
    ├── lib.rs               (Shared library code: `use my_service::...`)
    ├── main.rs              --> Binary #1: `my_service`
    └── bin/
        ├── migrate.rs       --> Binary #2: `migrate` (single-file binary)
        └── admin/
            ├── main.rs      --> Binary #3: `admin`   (multi-file binary)
            └── commands.rs

Running and Building Specific Binary Targets

When a package defines more than one binary target, cargo run requires either the --bin <name> flag on the command line or the default-run key under [package] in Cargo.toml:

Command Behavior
cargo run Runs the single binary target, or the binary specified by default-run in Cargo.toml.
cargo run --bin migrate Compiles and runs the migrate binary (src/bin/migrate.rs).
cargo run --bin migrate -- --dry-run Passes --dry-run as a command-line argument to migrate.
cargo build --bins Compiles all binary targets in the package.
cargo install --path . Compiles all binary targets in --release mode and copies them into ~/.cargo/bin/.

Configuring Explicit [[bin]] Targets in Cargo.toml

By default, Cargo automatically discovers src/main.rs and src/bin/*.rs (autobins = true). Adding explicit [[bin]] array-of-tables entries in Cargo.toml lets you customize a binary's path, rename its output executable, or gate a binary behind optional Cargo features (required-features):

[package]
name = "cloud_toolkit"
version = "0.1.0"
edition = "2024"
default-run = "cloud-cli"

[[bin]]
name = "cloud-cli"
path = "src/main.rs"

[[bin]]
name = "cloud-tui"
path = "src/bin/tui.rs"
required-features = ["tui-dashboard"]

When required-features = ["tui-dashboard"] is set on cloud-tui, Cargo only builds cloud-tui when --features tui-dashboard (or --all-features) is enabled.

Sharing Code Across Multiple Binaries

Because two binary files (src/main.rs and src/bin/migrate.rs) cannot import modules directly from each other, place all shared types, configuration parsers, and database clients in src/lib.rs. Every binary in src/bin/ can then import the shared library crate cleanly:

// Shared module in `src/lib.rs` (crate `cloud_toolkit`):
pub mod shared_config {
    #[derive(Debug)]
    pub struct EnvConfig {
        pub endpoint: &'static str,
        pub timeout_secs: u64,
    }

    pub const DEFAULT_CONFIG: EnvConfig = EnvConfig {
        endpoint: "https://api.example.com",
        timeout_secs: 30,
    };
}

// Binary entrypoint in `src/bin/migrate.rs`:
fn main() {
    let cfg = shared_config::DEFAULT_CONFIG;
    println!(
        "Migration tool using endpoint {} (timeout={}s)",
        cfg.endpoint, cfg.timeout_secs
    );
}
Migration tool using endpoint https://api.example.com (timeout=30s)