Isolating Cargo target dirs to avoid build contention

Two related techniques for keeping concurrent Rust builds from fighting over the same target/ dir.

PyO3 envvar churn

For PyO3 projects, cargo fingerprints depend on PyO3 env vars (interpreter, ABI flags, etc.). When two builds with different envs share target/, they invalidate each other’s artifacts and force redundant full rebuilds.

The case I hit: make build from a terminal vs. cargo commands issued by Claude Code running inside nvim — subtly different envs, constant thrash.

Fix in repo root .lazy.lua:

vim.env.CARGO_TARGET_DIR = "target/claude"
return {}

Sets the env var on the nvim process itself, inherited by :!, :terminal, LSP, Claude Code, etc. Builds from that nvim session land in target/claude/ and can’t collide with terminal builds. Costs disk + no artifact sharing, which is the trade I want. Requires vim.o.exrc = true (or lazy.nvim’s project-local feature); nvim prompts to trust on first load.

General: rust-analyzer vs. build lock

rust-analyzer runs cargo check automatically on edit. Sharing target/ with manual builds → “waiting for file lock on build directory” stalls. Same root cause (shared target), different symptom (lock contention vs. fingerprint churn), applies to any Rust project.

Fix in ~/.config/nvim/lua/plugins/rust.lua:

return {
  {
    "mrcjkb/rustaceanvim",
    opts = {
      server = {
        default_settings = {
          ["rust-analyzer"] = {
            cargo = { targetDir = true },
          },
        },
      },
    },
  },
}

targetDir = true makes RA use its own dir (typically target/rust-analyzer/) for background checks. Global across all Rust projects I open in nvim.

Both techniques: give the “other” build context its own target/. Different failure modes.