Cargo and Package Management

Cargo Environment Variables

Cargo sets and reads two distinct families of environment variables: variables that Cargo passes to your crate and build.rs during compilation (inspected via env!("CARGO_...") or std::env::var), and variables that configure Cargo itself from your shell or CI pipeline (CARGO_TARGET_DIR, RUSTFLAGS).

1. Shell / CI Environment ---> Configures Cargo (`CARGO_TARGET_DIR`, `RUSTFLAGS`)
                                     |
                                     v
2. Cargo Process ------------> Sets `CARGO_PKG_*`, `CARGO_MANIFEST_DIR` for `rustc`
                         ----> Sets `OUT_DIR`, `TARGET`, `HOST`, `OPT_LEVEL` for `build.rs`

Variables Set by Cargo for Crate Code (env!("..."))

When Cargo invokes rustc on your library, binary, or test target, it populates metadata variables from Cargo.toml that you can embed at zero runtime cost using the env! or option_env! macro:

Environment Variable Example Value Description
CARGO_PKG_NAME "my_service" Package name from Cargo.toml.
CARGO_PKG_VERSION "1.4.2" Full semantic version (MAJOR.MINOR.PATCH).
CARGO_PKG_VERSION_MAJOR / _MINOR / _PATCH "1", "4", "2" Individual version components.
CARGO_PKG_DESCRIPTION "Fast HTTP proxy" Package description from Cargo.toml.
CARGO_PKG_REPOSITORY "https://github.com/..." Package repository URL.
CARGO_PKG_RUST_VERSION "1.85" Minimum Supported Rust Version (rust-version).
CARGO_MANIFEST_DIR "/Users/dev/my_service" Directory containing the package's Cargo.toml (useful for loading test fixtures).
CARGO_CRATE_NAME "my_service" Name of the crate currently being compiled (hyphens converted to underscores).
CARGO_BIN_NAME "my-service" Name of the binary target being compiled (only set for binary targets).
CARGO_BIN_EXE_<name> "/.../target/debug/my-service" Path to compiled binary (set only during integration tests and benchmarks).
const VERSION_BANNER: &str = concat!(
    "v",
    // Using `option_env!` falls back cleanly even if compiled directly with `rustc` without Cargo:
    "0.1.0",
);

fn print_cargo_metadata() {
    let name = option_env!("CARGO_PKG_NAME").unwrap_or("direct_rustc_build");
    let version = option_env!("CARGO_PKG_VERSION").unwrap_or(VERSION_BANNER);
    let crate_name = option_env!("CARGO_CRATE_NAME").unwrap_or("main");

    println!("Package: {name} ({version}), crate: {crate_name}");
}

fn main() {
    print_cargo_metadata();
}
Package: direct_rustc_build (v0.1.0), crate: main

Variables Set Exclusively for build.rs

Inside build.rs, Cargo passes additional runtime environment variables (read via std::env::var):

  • OUT_DIR: The output directory where build.rs must place any generated files.
  • TARGET: The target triple for which the crate is being compiled (e.g., "aarch64-unknown-linux-gnu").
  • HOST: The host triple on which build.rs itself is running (e.g., "aarch64-apple-darwin").
  • PROFILE: "debug" or "release".
  • OPT_LEVEL: "0", "1", "2", "3", "s", or "z".
  • CARGO_FEATURE_<NAME>: Set for each enabled feature (uppercase, hyphens replaced by _, e.g., CARGO_FEATURE_CSV_EXPORT=1).
  • CARGO_CFG_TARGET_OS / CARGO_CFG_TARGET_ARCH: Target platform properties (use these inside build.rs instead of cfg!(target_os = ...) when cross-compiling, because cfg! in build.rs checks the HOST, whereas CARGO_CFG_TARGET_OS checks the TARGET!).

Variables That Configure Cargo from the Outside

Variable Effect on Cargo
CARGO_TARGET_DIR Overrides the location of the target/ build directory.
CARGO_BUILD_JOBS Overrides the maximum number of parallel rustc jobs (-j).
CARGO_INCREMENTAL=0 Disables incremental compilation (often used in CI to reduce cache size).
RUSTFLAGS Extra space-separated flags passed to every rustc invocation (e.g., RUSTFLAGS="-D warnings").
RUSTDOCFLAGS Extra flags passed to rustdoc (e.g., RUSTDOCFLAGS="-D warnings").