Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ This is most useful when using sccache for Rust compilation, as rustc supports u

---

Normalizing Paths with `SCCACHE_BASEDIRS`
Normalizing paths with `SCCACHE_BASEDIRS`
-----------------------------------------

By default, sccache requires absolute paths to match for cache hits. To enable cache sharing across different build directories, you can set `SCCACHE_BASEDIRS` to strip a base directory from paths before hashing:
Expand All @@ -344,6 +344,11 @@ export SCCACHE_BASEDIRS="/home/user/project:/home/user/workspace"

Path matching is **case-insensitive** on Windows and **case-sensitive** on other operating systems.

For Rust compilations, sccache normalizes matching absolute source arguments,
the source side of `--remap-path-prefix`, Cargo path variables, tracked
environment dependency values that are absolute paths, and the current working
directory before computing the cache key.

This is similar to ccache's `CCACHE_BASEDIR` and helps when:
* Building the same project from different directories
* Sharing cache between CI jobs with different checkout paths
Expand All @@ -352,6 +357,12 @@ This is similar to ccache's `CCACHE_BASEDIR` and helps when:

**Note:** Only absolute paths are supported. Relative paths will prevent server from starting.

**Rust note:** This setting normalizes cache-key inputs; it does not rewrite
paths embedded in compiled artifacts. If a crate deliberately embeds an
absolute path, for example with `env!("CARGO_MANIFEST_DIR")`, a cache hit from
another checkout can contain the path from the compilation that populated the
cache. Use this opt-in setting only when that behavior is acceptable.

You can also configure this in the sccache config file:

```toml
Expand Down
19 changes: 18 additions & 1 deletion benches/sccache_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use divan::{Bencher, black_box};
use sccache::cache::{CacheRead, CacheWrite};
use sccache::lru_disk_cache::LruCache;
use sccache::util::{Digest, TimeMacroFinder, strip_basedirs};
use sccache::util::{Digest, TimeMacroFinder, strip_basedirs, strip_path_basedirs};
use std::io::Cursor;

// =============================================================================
Expand Down Expand Up @@ -867,6 +867,23 @@ fn strip_basedirs_multiple(bencher: Bencher) {
bencher.bench(|| black_box(strip_basedirs(black_box(&output), black_box(&basedirs))));
}

#[divan::bench(args = [0, 1, 8, 32])]
fn rust_path_basedirs(bencher: Bencher, root_count: usize) {
let basedirs = (0..root_count)
.map(|index| {
format!("/Users/example/workspaces/project/checkouts/worktree-{index:02}/").into_bytes()
})
.collect::<Vec<_>>();
let hit = b"/Users/example/workspaces/project/checkouts/worktree-00/src/lib.rs".as_slice();
let miss = b"/Users/example/.cargo/registry/src/package/src/lib.rs".as_slice();
bencher.bench(|| {
for index in 0..100 {
let value = if index % 10 == 0 { hit } else { miss };
black_box(strip_path_basedirs(black_box(value), black_box(&basedirs)));
}
});
}

fn main() {
divan::main();
}
2 changes: 1 addition & 1 deletion docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ Note that some env variables may need sccache server restart to take effect.

* `SCCACHE_ALLOW_CORE_DUMPS` to enable core dumps by the server
* `SCCACHE_CONF` configuration file path
* `SCCACHE_BASEDIRS` base directory (or directories) to strip from paths for cache key computation. This is similar to ccache's `CCACHE_BASEDIR` and enables cache hits across different absolute paths when compiling the same source code. Multiple directories can be separated by `;` on Windows hosts and by `:` on any other operating system. When multiple directories are specified, the longest matching prefix is used. Path matching is **case-insensitive** on Windows and **case-sensitive** on other operating systems. Environment variable takes precedence over file configuration. Only absolute paths are supported; relative paths will cause an error and prevent the server from start.
* `SCCACHE_BASEDIRS` base directory (or directories) to strip from paths for cache key computation. This is similar to ccache's `CCACHE_BASEDIR` and enables cache hits across different absolute paths when compiling the same source code. Multiple directories can be separated by `;` on Windows hosts and by `:` on any other operating system. When multiple directories are specified, the longest matching prefix is used. Path matching is **case-insensitive** on Windows and **case-sensitive** on other operating systems. For Rust, sccache normalizes matching absolute source arguments, the source side of `--remap-path-prefix`, Cargo path variables, tracked environment dependency values that are absolute paths, and the current working directory. Environment variable takes precedence over file configuration. Only absolute paths are supported; relative paths will cause an error and prevent the server from starting. This setting changes cache keys but does not rewrite paths embedded in artifacts; a Rust artifact can retain an absolute path from the compilation that populated the cache.
* `SCCACHE_CACHED_CONF`
* `SCCACHE_IDLE_TIMEOUT` how long the local daemon process waits for more client requests before exiting, in seconds. Set to `0` to run sccache permanently
* `SCCACHE_STARTUP_NOTIFY` specify a path to a socket which will be used for server completion notification
Expand Down
1 change: 1 addition & 0 deletions docs/Rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ sccache includes support for caching Rust compilation. This includes many caveat
* Procedural macros that read files from the filesystem may not be cached properly.
* `rustc`'s incremental compilation needs to be disabled. See [The Cargo Book](https://doc.rust-lang.org/cargo/reference/profiles.html#incremental)
* Crates that invoke the system linker cannot be cached. Examples are `bin`, `dylib`, `cdylib`, and `proc-macro` crates.
* `SCCACHE_BASEDIRS` normalizes matching paths in cache-key inputs, but it does not rewrite paths embedded in artifacts. For example, a crate that uses `env!("CARGO_MANIFEST_DIR")` can retain the path from the compilation that populated a shared cache entry.

If you are using Rust 1.18 or later, you can ask cargo to wrap all compilation with sccache by setting `RUSTC_WRAPPER=sccache` in your build environment.
Loading