Skip to content

Rust: env-dep values (OUT_DIR) and CARGO_MANIFEST_DIR are hashed verbatim, so basedirs cannot make crates that include! build-script output, or path dependencies, hit across checkouts #2870

Description

@ghoulspa

sccache 0.18.0, local disk cache, rustc 1.98 stable (x86_64-pc-windows-gnu), cargo. basedirs lists several checkouts (git worktrees) of one workspace.

With basedirs configured, a second checkout hits on everything except crates that evaluate env!("OUT_DIR") at compile time — the Cargo-book pattern for including build-script output, used by e.g. serde_core and serde 1.0.229 (include!(concat!(env!("OUT_DIR"), "/private.rs"))). Those two miss in every new checkout, their rlibs then contain the checkout's path, and every crate taking them as an --extern misses behind them. In a Bevy project that is 80 of 329 crates, about 3 minutes per fresh checkout. Crates whose build scripts only emit --cfg (proc-macro2, syn, quote) hit fine.

Cause: rustc writes # env-dep:OUT_DIR=C:\...\<checkout>\target\debug\build\serde_core-<hash>\out into the dep-info, and src/compiler/rust.rs hashes each env-dep as var=value as-is; the base-dir stripping applied to --out-dir, -L and the dep-info file list is not applied to env-dep values.

The same applies to CARGO_MANIFEST_DIR for path dependencies ([patch.crates-io] pointing at a vendored crate): the CARGO_* environment is hashed verbatim, and that variable holds the checkout path, so a path dependency never hits across checkouts either. Vendoring serde with the include! spelled out moved the miss from OUT_DIR to CARGO_MANIFEST_DIR.

Repro: two checkouts of any project depending on serde 1.0.229, both listed in basedirs; build in A, then in B. sccache --show-stats shows serde_core and serde as misses in B, and target/debug/deps/serde_core-*.d in each checkout shows the differing env-dep:OUT_DIR line. For the second case, add [patch.crates-io] serde_core = { path = "vendor/serde_core" } with a copy of the crate: cargo build -p serde_core in a fresh checkout is a miss with no env-dep line in its dep-info.

Suggested fix: run env-dep values and the CARGO_* path variables through the same base-dir normalisation before hashing. The included file's content is already hashed through the dep-info file list, so these values carry no information beyond the checkout path. #2813 looks like it covers both; filing so the cases are on record with a repro.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions