Cargo

Project Creation

cargo new and init
cargo new myproject          # binary (src/main.rs)
cargo new mylib --lib        # library (src/lib.rs)
cargo init                   # initialize in existing directory
Cargo.toml structure
[package]
name = "netcheck"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = { version = "4.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
tokio = { version = "1", features = ["full"] }

[dev-dependencies]
assert_cmd = "2.0"
predicates = "3.0"

edition controls which Rust edition features are available. Always use the latest (2021 or 2024).

Essential Commands

Build, run, test, check
cargo build                  # debug build (target/debug/)
cargo build --release        # optimized build (target/release/)
cargo run                    # build and run
cargo run -- --help          # pass args to the binary
cargo check                  # type-check without building (fast)
cargo test                   # run all tests
cargo test -- --nocapture    # show println! output in tests
cargo clippy                 # linter — catches common mistakes
cargo fmt                    # format all code
cargo doc --open             # generate and open documentation

cargo check is faster than cargo build — use it during development for quick feedback. cargo clippy catches hundreds of patterns that compile but are suboptimal.

Dependency Management

Adding and managing dependencies
cargo add serde --features derive    # add to Cargo.toml
cargo add tokio -F full              # shorthand for --features
cargo remove serde                   # remove dependency
cargo update                         # update to latest compatible versions
cargo tree                           # dependency tree
cargo tree -d                        # show only duplicates
cargo tree -i serde                  # find why serde is included

cargo add modifies Cargo.toml for you. cargo tree is essential for debugging dependency conflicts.

Workspace

Multi-crate project
# Cargo.toml (workspace root)
[workspace]
members = [
    "netcheck-cli",
    "netcheck-lib",
    "netcheck-api",
]

[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
Member Cargo.toml
[dependencies]
serde = { workspace = true }        # inherit from workspace
netcheck-lib = { path = "../netcheck-lib" }

Workspaces share a single Cargo.lock and target/ directory. Shared dependencies are declared once at the workspace level.

Cross-Compilation

Build for different targets
# List installed targets
rustup target list --installed

# Add a target
rustup target add x86_64-unknown-linux-musl

# Build for musl (static binary)
cargo build --release --target x86_64-unknown-linux-musl

# Build for macOS from Linux (requires linker)
cargo build --release --target aarch64-apple-darwin

The musl target produces fully static binaries — no glibc dependency. Ideal for containers and distribution.

Profiles

Customize build settings
[profile.release]
opt-level = 3
lto = true           # link-time optimization
strip = true          # strip debug symbols
codegen-units = 1     # maximize optimization

[profile.dev]
opt-level = 0         # fast compilation
debug = true

[profile.dev.package."*"]
opt-level = 2         # optimize dependencies in dev mode

Release profile trades compilation time for runtime speed. The dev profile prioritizes fast compilation.