Skip to content

Strip basedirs from the compiler arguments too - #2840

Open
avikivity wants to merge 1 commit into
mozilla:mainfrom
avikivity:basedirs-arguments
Open

Strip basedirs from the compiler arguments too#2840
avikivity wants to merge 1 commit into
mozilla:mainfrom
avikivity:basedirs-arguments

Conversation

@avikivity

Copy link
Copy Markdown
Contributor

SCCACHE_BASEDIRS strips the base directories from the preprocessed source, but the compiler arguments are hashed verbatim. That leaves out the one thing that most reliably ties a cache entry to a single checkout: a flag that names the tree it is building.

-ffile-prefix-map=/home/user/project=.

The flag exists precisely so the object file does not depend on where the tree lives - every path it records is rewritten to . - so two checkouts of the same commit produce identical objects. They just never agree on the hash, because the flag itself spells the path out, and so they never share an entry. Which is the case basedirs is for.

Strip basedirs from each argument before hashing it, at the places where an argument is expected to spell a pathname, and only there: the whole argument, as in a source file or the path of a separated option; the value of an option written with an =, which covers either half of a prefix map; and the value glued to a short option such as -I. A basedir appearing anywhere else is left alone, so -DROOT="/home/user/project", which the compiler bakes into the output verbatim, still counts towards the hash.

Basedirs carry a trailing slash so that they only match whole path components; in an argument a component can also end at the = of a prefix map, or at the end of the argument, so accept those two as well. A sibling /home/user/project-docs is still not a match. The longest basedir wins.

Bump CACHE_VERSION and the preprocessor cache's FORMAT_VERSION, since the arguments now reach the hash as bytes rather than through OsString's Hash impl.

@codecov-commenter

codecov-commenter commented Sep 5, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.90210% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.96%. Comparing base (05aafc8) to head (35175d2).

Files with missing lines Patch % Lines
src/util.rs 97.74% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2840      +/-   ##
==========================================
+ Coverage   73.84%   75.96%   +2.11%     
==========================================
  Files          72       72              
  Lines       38178    39526    +1348     
==========================================
+ Hits        28194    30027    +1833     
+ Misses       9984     9499     -485     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@AJIOB

AJIOB commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Hi @avikivity ,

Thanks for your PR.

Please, fix the CI build

@avikivity

Copy link
Copy Markdown
Contributor Author

Update: apply cargo fmt

SCCACHE_BASEDIRS strips the base directories from the preprocessed
source, but the compiler arguments are hashed verbatim.  That leaves out
the one thing that most reliably ties a cache entry to a single checkout:
a flag that names the tree it is building.

  -ffile-prefix-map=/home/user/project=.

The flag exists precisely so the object file does not depend on where the
tree lives - every path it records is rewritten to `.` - so two checkouts
of the same commit produce identical objects.  They just never agree on
the hash, because the flag itself spells the path out, and so they never
share an entry.  Which is the case basedirs is for.

Strip basedirs from each argument before hashing it, at the places where
an argument is expected to spell a pathname, and only there: the whole
argument, as in a source file or the path of a separated option; the
value of an option written with an `=`, which covers either half of a
prefix map; and the value glued to a short option such as -I.  A basedir
appearing anywhere else is left alone, so -DROOT="/home/user/project",
which the compiler bakes into the output verbatim, still counts towards
the hash.

Basedirs carry a trailing slash so that they only match whole path
components; in an argument a component can also end at the `=` of a
prefix map, or at the end of the argument, so accept those two as well.
A sibling /home/user/project-docs is still not a match.  The longest
basedir wins.

Bump CACHE_VERSION and the preprocessor cache's FORMAT_VERSION, since the
arguments now reach the hash as bytes rather than through OsString's Hash
impl.
@avikivity

Copy link
Copy Markdown
Contributor Author

Update: increase test coverage

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants