Skip to content

Conversation

@avikivity
Copy link
Contributor

@avikivity avikivity commented Dec 20, 2025

On Linux, ccache is typically installed in $PATH as /usr/lib64/ccache/g++
or similar. If we keep it there, all compilations will be cached by both
ccache and sccache.

While the user could easily disable ccache with CCACHE_DISABLE, it's
reasonable to assume many will forget and will have their disk space
doubly consumed by both caches. Better to recognize this and disable
ccache under sccache.

This patch does this resolving the input compiler name to an absolute
path, with these rules:

  • if a directory in PATH contains a component ccache, it is skipped
  • if the compiler exists in a directory in PATH, but is a symlink
    to a target ccache, it is skipped

These two tests will catch most ccache masquerade directories.

Fixes #2519

@codecov-commenter
Copy link

codecov-commenter commented Dec 20, 2025

Codecov Report

❌ Patch coverage is 92.90780% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.12%. Comparing base (e454f4e) to head (83fc260).

Files with missing lines Patch % Lines
src/compiler/nvcc.rs 52.94% 8 Missing ⚠️
src/util.rs 98.29% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2524      +/-   ##
==========================================
+ Coverage   72.04%   72.12%   +0.07%     
==========================================
  Files          66       66              
  Lines       36953    37085     +132     
==========================================
+ Hits        26623    26746     +123     
- Misses      10330    10339       +9     

☔ View full report in Codecov by Sentry.
📢 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.

@avikivity
Copy link
Contributor Author

update: fix rustfmt error

@avikivity
Copy link
Contributor Author

@sylvestre please review

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 10, 2026

CodSpeed Performance Report

Merging this PR will not alter performance

Comparing avikivity:disable-ccache (83fc260) with main (e454f4e)

Summary

✅ 54 untouched benchmarks
⏩ 2 skipped benchmarks1

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@sylvestre sylvestre force-pushed the disable-ccache branch 2 times, most recently from 1fe7bb9 to 4bb5579 Compare January 13, 2026 15:33
@avikivity
Copy link
Contributor Author

@sylvestre can I help in any way to push this along?

src/util.rs Outdated
use std::env;
use std::path::Path;

const CCACHE_DIRS: &[&str] = &["/usr/lib/ccache", "/usr/lib64/ccache"];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CCACHE_DIRS list only contains Linux paths. Consider adding macOS Homebrew paths (/usr/local/opt/ccache/libexec, /opt/homebrew/opt/ccache/libexec) or adding a comment explaining why they're omitted

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, it would be nice to be able to configure things somewhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can generalize it to any path that contains a component ccache.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About configuration, is it still needed if we just filter out directories with ccache components?

src/util.rs Outdated
/// This prevents double-caching when ccache is installed and has
/// /usr/lib/ccache or /usr/lib64/ccache in PATH, since those directories
/// contain wrapper scripts that would call ccache.
pub fn filter_ccache_from_path(env_vars: Vec<(OsString, OsString)>) -> Vec<(OsString, OsString)> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function allocates a new Vec even when no ccache dirs are present in PATH. Consider short-circuiting to return the input Vec unchanged when filtering is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

} = self;
// Filter out ccache directories from PATH to avoid double-caching
// when ccache is also installed on the system.
let env_vars = filter_ccache_from_path(env_vars.to_vec());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filter is only applied to SingleCompileCommand but NvccCompileCommand (in nvcc.rs) also implements CompileCommandImpl and may need the same treatment it is intentional ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not intentional, I'll take a look.

@sylvestre
Copy link
Collaborator

sorry for the latency

@avikivity
Copy link
Contributor Author

v2:

  • filter out any directory with a ccache component, so it also works on MacOS
  • avoid allocations if no ccache directories are present
  • apply to detect_c_compiler
  • apply to nvcc

@avikivity
Copy link
Contributor Author

v3:

  • apply rustfmt

@avikivity
Copy link
Contributor Author

v4:

  • use slice instead of Vec

@avikivity
Copy link
Contributor Author

I believe the performance regression report is spurious, the code doesn't touch the macro finder code.

@ahartmetz
Copy link
Collaborator

So I'm not the maintainer here and this is merely a suggestion. I'm a bit uncomfortable with the brittleness of this approach to recognizing ccache. An additional, somewhat - perhaps less - brittle heuristic that could be added on POSIX platforms is to recognize when gcc, g++, clang, clang++ [...] is a symlink to a binary called "ccache". Assuming that ccache works like icecream and sccache (which btw supports symlinks compiler -> sccache now).

@avikivity
Copy link
Contributor Author

So I'm not the maintainer here and this is merely a suggestion. I'm a bit uncomfortable with the brittleness of this approach to recognizing ccache. An additional, somewhat - perhaps less - brittle heuristic that could be added on POSIX platforms is to recognize when gcc, g++, clang, clang++ [...] is a symlink to a binary called "ccache". Assuming that ccache works like icecream and sccache (which btw supports symlinks compiler -> sccache now).

I believe it's unnecessary - it's unlikely people will have directories in path named ccache that host the real compilers instead of ccache masquerades.

I'm happy to make that change if the maintainers think it is necessary though.

@ahartmetz
Copy link
Collaborator

ahartmetz commented Jan 27, 2026

I believe it's unnecessary - it's unlikely people will have directories in path named ccache that host the real compilers instead of ccache masquerades.

I'm happy to make that change if the maintainers think it is necessary though.

I don't mean ANDing the two conditions, I mean ORing. The false positive rate of a compiler binary linking to a binary called ccache, which is actually not ccache, should be negligible.

@avikivity
Copy link
Contributor Author

So I'm not the maintainer here and this is merely a suggestion. I'm a bit uncomfortable with the brittleness of this approach to recognizing ccache. An additional, somewhat - perhaps less - brittle heuristic that could be added on POSIX platforms is to recognize when gcc, g++, clang, clang++ [...] is a symlink to a binary called "ccache". Assuming that ccache works like icecream and sccache (which btw supports symlinks compiler -> sccache now).

I believe it's unnecessary - it's unlikely people will have directories in path named ccache that host the real compilers instead of ccache masquerades.
I'm happy to make that change if the maintainers think it is necessary though.

I don't mean ANDing the two conditions, I mean ORing

To clarify: IF the directory contains a path component ccache, OR if the looked-up compiler is a symlink to something named ccache, THEN skip this compiler executable?

Makes sense.

@ahartmetz
Copy link
Collaborator

I don't mean ANDing the two conditions, I mean ORing

To clarify: IF the directory contains a path component ccache, OR if the looked-up compiler is a symlink to something named ccache, THEN skip this compiler executable?

Makes sense.

That's what I meant, yes

@ahartmetz
Copy link
Collaborator

ahartmetz commented Jan 27, 2026

(Background: I MAY have had a distributed compiler, which I compiled myself, installed in [obscure]/local/bin at some point, but I have never renamed the distributed compiler binary to something else than its usual name - which would probably break something because it avoids calling itself by checking its binary name)
Edit: on second thought, I think such tools usually just eliminate their own binary name / path / inode, whatever it may be, from the compiler search - but still, the ccache / icecream / sccache binary is usually called exactly that, with the exception of sccache, which required hardlinks until recently.

On third thought, what the hell was I thinking, if it's not called gcc or g++ etc, it won't be found as a compiler at all, so you'd need to resolve the symlink to ccache, which is... doable but where this maybe gets a bit "too much".

@avikivity avikivity force-pushed the disable-ccache branch 2 times, most recently from d8913d5 to 6681201 Compare February 1, 2026 14:42
@avikivity
Copy link
Contributor Author

update:

  • rebased
  • changed approach - the utility function resolves relative compiler names to absolute paths, skipping over directories with ccache components or files that as symlinks that resolve to ccache.

On Linux, ccache is typically installed in $PATH as /usr/lib64/ccache/g++
or similar. If we keep it there, all compilations will be cached by both
ccache and sccache.

While the user could easily disable ccache with CCACHE_DISABLE, it's
reasonable to assume many will forget and will have their disk space
doubly consumed by both caches. Better to recognize this and disable
ccache under sccache.

This patch does this resolving the input compiler name to an absolute
path, with these rules:
 - if a directory in PATH contains a component `ccache`, it is skipped
 - if the compiler exists in a directory in PATH, but is a symlink
   to a target `ccache`, it is skipped

These two tests will catch most ccache masquerade directories.

Fixes mozilla#2519
@avikivity
Copy link
Contributor Author

update:

  • applied rustfmt

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.

Unwanted double-caching when ccache is also installed

4 participants