Skip to content

SCCACHE_BASEDIRS has no effect on Windows (escaped backslashes in preprocessor output never match) #2737

@rconde01

Description

@rconde01

Summary

SCCACHE_BASEDIRS has no effect on Windows. The same source compiled from
two different checkout directories produces different cache keys, so cache
entries are never shared across roots — the feature silently does nothing.

Environment

  • Platform: Windows
  • Compilers: MSVC (cl) and clang both affected
  • SCCACHE_BASEDIRS set to the absolute checkout roots

Steps to reproduce

  1. Set SCCACHE_BASEDIRS to a list of absolute base directories.
  2. Build the same source tree from two different absolute directories
    (e.g. D:\dev\user1\project and E:\work\user2\checkout), as CMake/Ninja
    do when they pass absolute source paths.
  3. Compile a file that ends up with an absolute path in the preprocessed
    output (any #line/linemarker, __FILE__, or assert() expansion —
    which build systems routinely produce).

Expected: the second build is a cache hit; basedirs are stripped so the
hash is independent of the checkout root.

Actual: every build is a miss; basedirs are never stripped.

Root cause

On Windows, paths inside preprocessor output are emitted as C string
literals
. MSVC #line directives and clang GNU linemarkers quote them
with escaped backslash separators:

#line 1 "C:\\Users\\me\\project\\src\\main.c"

normalize_win_path (src/util.rs) converts every backslash to a forward
slash, so each escaped separator \\ becomes a double forward slash:

c://users//me//project//src//main.c

But the normalized basedir uses single slashes (c:/users/me/project/), so
strip_basedirs never finds a boundary match and the absolute path survives
into the hash input.

Fix

PR #2736 makes strip_basedirs also search for a doubled-separator variant
of each basedir, so escaped paths are stripped in addition to the plain
form (mixed and UNC cases covered). Non-Windows builds are unchanged
(cfg(target_os = "windows")-gated).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions