Setup#

Rust’s toolchain installer rustup covers the whole story, the compiler (rustc), the package manager / build tool (cargo), the formatter (rustfmt), the linter (clippy), and toolchain channels (stable, beta, nightly).

Install#

1. Install rustup.

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ source $HOME/.cargo/env

2. Install toolchains.

$ rustup toolchain install stable
$ rustup default stable
$ rustup component add rustfmt clippy rust-analyzer

3. Verify.

$ rustc --version
$ cargo --version
$ rustup show

Setup project#

1. Bootstrap.

$ cargo new my-tool                  # binary crate
$ cd my-tool
$ cargo new --lib my-lib              # library crate (in a subdir)

For a workspace with multiple crates,

$ cargo new operator-workspace --vcs none
$ cd operator-workspace
# edit Cargo.toml to declare [workspace] members

2. Add dependencies.

$ cargo add tokio --features full
$ cargo add reqwest --features rustls-tls,json
$ cargo add clap --features derive
$ cargo add anyhow

3. Lay out the source.

my-tool/
├── Cargo.toml
├── Cargo.lock
├── src/
│   ├── main.rs
│   └── lib.rs
├── tests/
│   └── integration.rs
├── benches/
│   └── bench_main.rs
└── examples/
    └── usage.rs

4. Build, run, test.

$ cargo run                        # debug build, run
$ cargo build --release            # optimized
$ cargo test                       # run tests
$ cargo clippy -- -D warnings      # lint (warnings as errors)
$ cargo fmt                        # format

Cross-compile#

$ rustup target add x86_64-unknown-linux-musl
$ rustup target add aarch64-unknown-linux-gnu
$ cargo build --release --target x86_64-unknown-linux-musl

For a fully static binary (no glibc), musl is the operator’s target.

For more complex cross-compilation, cross wraps cargo and uses Docker images per target.

$ cargo install cross --git https://github.com/cross-rs/cross
$ cross build --target armv7-unknown-linux-gnueabihf --release

Toolchains#

  • stable, the default.

  • beta, the next stable.

  • nightly, unstable features. Required for some libraries (rocket for years, miri, wasm-bindgen-test).

  • MSRV (minimum supported Rust version) pins what an old toolchain can still build.

$ rustup install nightly
$ rustup run nightly cargo build
$ rustup override set nightly      # per-directory pin

Common Tasks#

Add a crate by name.

$ cargo add serde --features derive

Audit dependencies for advisories.

$ cargo install cargo-audit
$ cargo audit

Generate a flamegraph of a release build.

$ cargo install flamegraph
$ cargo flamegraph --bin my-tool

Watch and rebuild on save.

$ cargo install cargo-watch
$ cargo watch -x test

Strip and shrink the release binary.

# Cargo.toml
[profile.release]
strip = true
lto = true
codegen-units = 1
opt-level = "z"

References#