Skip to main content
Cargo provides the fastest iteration cycle for Rust development. While Bazel is NativeLink’s primary build system, Cargo offers a more traditional Rust development experience with excellent IDE integration.

Why Use Cargo?

Cargo is ideal when you need:
  • Fast Iteration - Quick compile-test cycles
  • IDE Support - Native rust-analyzer integration
  • Standard Workflow - Familiar Rust development patterns
  • Direct Dependencies - Transparent dependency management
  • Debugging - Better debugger integration
For production builds and CI, use Bazel to ensure reproducibility.

Setup

Prerequisites

1

Install Rust

Install Rust using rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Verify you have the required version:
rustc --version
# Must be >= 1.87.0 (see Cargo.toml:12)
2

Install System Dependencies

sudo apt install pkg-config libssl-dev build-essential
3

Install Development Tools

# rust-analyzer for IDE support
rustup component add rust-analyzer

# rustfmt for code formatting
rustup component add rustfmt

# clippy for linting
rustup component add clippy

Building

Basic Build Commands

1

Build Main Binary

# Debug build (fast compile, slower runtime)
cargo build

# Release build (slow compile, fast runtime)
cargo build --release

# Run the binary
./target/release/nativelink --help
2

Build All Workspace Crates

cargo build --workspace

# Or use --all (alias)
cargo build --all
3

Build Specific Crate

cargo build -p nativelink-config
cargo build -p nativelink-store
cargo build -p nativelink-worker
4

Build with Features

# Enable Nix features
cargo build --features nix

# Build worker with Nix support
cargo build -p nativelink-worker --features nix

Build Profiles

NativeLink defines custom build profiles in Cargo.toml:
# Default dev build
cargo build

# Fast compile, includes debug symbols
# Output: target/debug/nativelink

Testing

Running Tests

1

Run All Tests

# Run all tests in workspace
cargo test --all

# Run with output
cargo test --all -- --nocapture
2

Run Specific Crate Tests

cargo test -p nativelink-store
cargo test -p nativelink-scheduler
cargo test -p nativelink-worker
3

Run Specific Test

# Run test by name
cargo test test_function_name

# Run tests matching pattern
cargo test cache --all
4

Run Doc Tests

cargo test --doc --all

Test Configuration

# Run tests with multiple threads
cargo test --all -- --test-threads=4

# Run tests sequentially
cargo test --all -- --test-threads=1

# Show test output
cargo test --all -- --nocapture

# Run ignored tests
cargo test --all -- --ignored

# Run all tests including ignored
cargo test --all -- --include-ignored

Code Quality

Formatting

1

Check Formatting

cargo fmt --all -- --check
2

Fix Formatting

cargo fmt --all

Linting with Clippy

1

Run Clippy

# Run clippy on all crates
cargo clippy --all

# Run clippy with warnings as errors
cargo clippy --all -- -D warnings
2

Run Clippy on Tests

cargo clippy --all --tests
3

Fix Clippy Warnings

# Some issues can be auto-fixed
cargo clippy --all --fix

Lint Configuration

NativeLink enforces strict lints defined in Cargo.toml:96-213:
# Denied Rust lints (excerpt)
[workspace.lints.rust]
future-incompatible = "deny"
unsafe-op-in-unsafe-fn = "deny"
unused-imports = "deny"

# Clippy lints (excerpt)
[workspace.lints.clippy]
all = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
todo = "deny"
await-holding-lock = "deny"
See Cargo.toml for the complete list.

Documentation

Building Documentation

1

Build All Docs

# Build documentation for workspace
cargo doc --workspace --no-deps

# Open in browser
cargo doc --workspace --no-deps --open
2

Build Specific Crate Docs

cargo doc -p nativelink-config --open
cargo doc -p nativelink-store --open
3

Include Private Items

cargo doc --workspace --no-deps --document-private-items

Documentation Tests

# Run doc tests only
cargo test --doc --all

# Run doc tests for specific crate
cargo test --doc -p nativelink-util

Run with Cargo

1

Download Example Config

curl -O https://raw.githubusercontent.com/TraceMachina/nativelink/main/nativelink-config/examples/basic_cas.json5
2

Run Development Build

cargo run -- basic_cas.json5
3

Run Release Build

cargo run --release -- basic_cas.json5
4

Run with Environment Variables

RUST_LOG=debug cargo run --release -- basic_cas.json5

Binary Locations

# Debug binary
./target/debug/nativelink

# Release binary
./target/release/nativelink

# Smol profile binary
./target/smol/nativelink

Workspace Structure

NativeLink uses a Cargo workspace defined in Cargo.toml:2-7:
[workspace]
exclude = [
  "nativelink-config/generate-stores-config",
  "tools/generate-bazel-rc",
]
resolver = "2"

Workspace Crates

nativelink-config

Configuration parsing and validation

nativelink-error

Error types and handling

nativelink-scheduler

Task scheduling and execution

nativelink-service

gRPC service implementations

nativelink-store

Storage backends and caching

nativelink-util

Shared utilities and helpers

nativelink-worker

Remote execution worker

nativelink-macro

Procedural macros

nativelink-proto

Protocol buffer definitions

nativelink-metric

Metrics and telemetry

IDE Integration

rust-analyzer

rust-analyzer works out of the box with Cargo workspaces:
1

VS Code Setup

Install the rust-analyzer extension.Optional .vscode/settings.json:
{
  "rust-analyzer.check.command": "clippy",
  "rust-analyzer.cargo.features": "all"
}
2

Generate rust-project.json (Alternative)

For better integration with Bazel builds:
bazel run @rules_rust//tools/rust_analyzer:gen_rust_project
Then configure:
{
  "rust-analyzer.linkedProjects": ["rust-project.json"]
}

Debugging

Create .vscode/launch.json:
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "name": "Debug NativeLink",
      "cargo": {
        "args": ["build", "--bin=nativelink"]
      },
      "args": ["basic_cas.json5"],
      "cwd": "${workspaceFolder}"
    }
  ]
}
Install CodeLLDB extension.

Advanced Usage

Dependency Management

1

Update Dependencies

# Update to latest compatible versions
cargo update

# Update specific dependency
cargo update tokio
2

Check Outdated Dependencies

# Install cargo-outdated
cargo install cargo-outdated

# Check for updates
cargo outdated
3

Audit Dependencies

# Install cargo-audit
cargo install cargo-audit

# Check for security vulnerabilities
cargo audit

Build Performance

# Use all CPU cores (default)
cargo build --release

# Limit parallel jobs
cargo build --release -j 4

Cross-Compilation

# Install target
rustup target add x86_64-unknown-linux-musl
rustup target add aarch64-unknown-linux-musl

# Build for target
cargo build --release --target x86_64-unknown-linux-musl

# Static linking (musl)
cargo build --release --target x86_64-unknown-linux-musl

Troubleshooting

Install OpenSSL development headers:
# Ubuntu/Debian
sudo apt install libssl-dev

# Arch Linux
sudo pacman -S openssl

# macOS
brew install openssl
Or use vendored OpenSSL (if available):
cargo build --features vendored-openssl
Ensure Xcode Command Line Tools are installed:
xcode-select --install
Clean build artifacts:
cargo clean

# Or clean specific profile
rm -rf target/debug
rm -rf target/release
Clear incremental compilation cache:
rm -rf target/debug/incremental
rm -rf target/release/incremental
Update Rust toolchain:
rustup update
rustup component add clippy rustfmt

Cargo Tools

cargo-watch

Auto-rebuild on file changes
cargo install cargo-watch
cargo watch -x build

cargo-bloat

Find what takes space in binaries
cargo install cargo-bloat
cargo bloat --release

cargo-tree

Show dependency tree (built-in)
cargo tree

cargo-expand

Expand macros
cargo install cargo-expand
cargo expand

Next Steps

Development with Bazel

Production builds and remote execution

Development with Nix

Reproducible development environment

Build docs developers (and LLMs) love