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
- Set
SCCACHE_BASEDIRS to a list of absolute base directories.
- 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.
- 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).
Summary
SCCACHE_BASEDIRShas no effect on Windows. The same source compiled fromtwo different checkout directories produces different cache keys, so cache
entries are never shared across roots — the feature silently does nothing.
Environment
cl) and clang both affectedSCCACHE_BASEDIRSset to the absolute checkout rootsSteps to reproduce
SCCACHE_BASEDIRSto a list of absolute base directories.(e.g.
D:\dev\user1\projectandE:\work\user2\checkout), as CMake/Ninjado when they pass absolute source paths.
output (any
#line/linemarker,__FILE__, orassert()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
#linedirectives and clang GNU linemarkers quote themwith escaped backslash separators:
normalize_win_path(src/util.rs) converts every backslash to a forwardslash, so each escaped separator
\\becomes a double forward slash:But the normalized basedir uses single slashes (
c:/users/me/project/), sostrip_basedirsnever finds a boundary match and the absolute path survivesinto the hash input.
Fix
PR #2736 makes
strip_basedirsalso search for a doubled-separator variantof 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).