Skip to content

Commit 310cd79

Browse files
committed
initial version of checksum based freshness
1 parent d899ce7 commit 310cd79

File tree

13 files changed

+3552
-119
lines changed

13 files changed

+3552
-119
lines changed

Cargo.lock

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ unicode-width.workspace = true
204204
url.workspace = true
205205
walkdir.workspace = true
206206
supports-unicode = "3.0.0"
207+
md-5 = "0.10.6"
207208

208209
[target.'cfg(target_has_atomic = "64")'.dependencies]
209210
tracing-chrome.workspace = true

src/cargo/core/compiler/build_config.rs

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ pub struct BuildConfig {
4646
pub future_incompat_report: bool,
4747
/// Which kinds of build timings to output (empty if none).
4848
pub timing_outputs: Vec<TimingOutput>,
49+
/// Use checksums rather than mtimes to determine if a crate is fresh.
50+
pub checksum_freshness: bool,
4951
}
5052

5153
fn default_parallelism() -> CargoResult<u32> {
@@ -117,6 +119,7 @@ impl BuildConfig {
117119
export_dir: None,
118120
future_incompat_report: false,
119121
timing_outputs: Vec::new(),
122+
checksum_freshness: false,
120123
})
121124
}
122125

src/cargo/core/compiler/build_runner/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use jobserver::Client;
1616

1717
use super::build_plan::BuildPlan;
1818
use super::custom_build::{self, BuildDeps, BuildScriptOutputs, BuildScripts};
19-
use super::fingerprint::Fingerprint;
19+
use super::fingerprint::{Checksum, Fingerprint};
2020
use super::job_queue::JobQueue;
2121
use super::layout::Layout;
2222
use super::lto::Lto;
@@ -50,6 +50,8 @@ pub struct BuildRunner<'a, 'gctx> {
5050
pub fingerprints: HashMap<Unit, Arc<Fingerprint>>,
5151
/// Cache of file mtimes to reduce filesystem hits.
5252
pub mtime_cache: HashMap<PathBuf, FileTime>,
53+
/// Cache of file checksums to reduce filesystem reads.
54+
pub checksum_cache: HashMap<PathBuf, Checksum>,
5355
/// A set used to track which units have been compiled.
5456
/// A unit may appear in the job graph multiple times as a dependency of
5557
/// multiple packages, but it only needs to run once.
@@ -113,6 +115,7 @@ impl<'a, 'gctx> BuildRunner<'a, 'gctx> {
113115
build_script_outputs: Arc::new(Mutex::new(BuildScriptOutputs::default())),
114116
fingerprints: HashMap::new(),
115117
mtime_cache: HashMap::new(),
118+
checksum_cache: HashMap::new(),
116119
compiled: HashSet::new(),
117120
build_scripts: HashMap::new(),
118121
build_explicit_deps: HashMap::new(),

src/cargo/core/compiler/fingerprint/dirty_reason.rs

+44
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,13 @@ impl DirtyReason {
222222
format_args!("the file `{}` is missing", file.display()),
223223
)
224224
}
225+
StaleItem::FailedToReadMetadata(file) => {
226+
let file = file.strip_prefix(root).unwrap_or(&file);
227+
s.dirty_because(
228+
unit,
229+
format_args!("couldn't read metadata for file `{}`", file.display()),
230+
)
231+
}
225232
StaleItem::ChangedFile {
226233
stale,
227234
stale_mtime,
@@ -235,6 +242,43 @@ impl DirtyReason {
235242
format_args!("the file `{}` has changed ({after})", file.display()),
236243
)
237244
}
245+
StaleItem::ChangedChecksum {
246+
source,
247+
stored_checksum,
248+
new_checksum,
249+
} => {
250+
let file = source.strip_prefix(root).unwrap_or(&source);
251+
s.dirty_because(
252+
unit,
253+
format_args!(
254+
"the file `{}` has changed (checksum didn't match, {} != {})",
255+
file.display(),
256+
stored_checksum,
257+
new_checksum,
258+
),
259+
)
260+
}
261+
StaleItem::FileSizeChanged {
262+
path,
263+
old_size,
264+
new_size,
265+
} => {
266+
let file = path.strip_prefix(root).unwrap_or(&path);
267+
s.dirty_because(
268+
unit,
269+
format_args!(
270+
"file size changed ({old_size} != {new_size}) for `{}`",
271+
file.display()
272+
),
273+
)
274+
}
275+
StaleItem::MissingChecksum(path) => {
276+
let file = path.strip_prefix(root).unwrap_or(&path);
277+
s.dirty_because(
278+
unit,
279+
format_args!("the checksum for file `{}` is missing", file.display()),
280+
)
281+
}
238282
StaleItem::ChangedEnv { var, .. } => s.dirty_because(
239283
unit,
240284
format_args!("the environment variable {var} changed"),

0 commit comments

Comments
 (0)