@@ -19,13 +19,12 @@ use fbuild_core::{Platform, Result};
1919use serde:: Serialize ;
2020
2121use crate :: build_fingerprint:: {
22- hash_watch_set_stamps_cached , save_json , stable_hash_json , FastPathInputs ,
23- PersistedBuildFingerprint , BUILD_FINGERPRINT_VERSION ,
22+ expected_fast_path_artifacts , stable_hash_json , FastPathCheckInputs , FastPathContract ,
23+ FastPathPersistInputs , BUILD_FINGERPRINT_VERSION ,
2424} ;
25- use crate :: compile_database:: { CompileDatabase , TargetArchitecture } ;
25+ use crate :: compile_database:: TargetArchitecture ;
2626use crate :: compiler:: Compiler as _;
2727use crate :: pipeline;
28- use crate :: zccache:: FingerprintWatch ;
2928use crate :: { BuildOrchestrator , BuildParams , BuildResult , SourceScanner } ;
3029
3130use super :: avr_compiler:: AvrCompiler ;
@@ -67,33 +66,6 @@ fn profile_label(profile: fbuild_core::BuildProfile) -> &'static str {
6766 }
6867}
6968
70- fn build_fingerprint_path ( build_dir : & Path ) -> PathBuf {
71- build_dir. join ( "build_fingerprint.json" )
72- }
73-
74- /// Build the watch set for the AVR fast-path check.
75- ///
76- /// Covers the project directory (sketch + local `lib/`) and the
77- /// resolved libraries directory if present. Mirrors the ESP32
78- /// orchestrator's policy — any directory that can produce a source
79- /// file consumed by the build must be watched, or we risk reusing
80- /// stale artifacts.
81- fn collect_fast_path_watches ( build_dir : & Path , project_dir : & Path ) -> Vec < FingerprintWatch > {
82- let mut watches = Vec :: new ( ) ;
83- if let Some ( watch) =
84- crate :: build_fingerprint:: fast_path_watch ( "project" , build_dir, project_dir)
85- {
86- watches. push ( watch) ;
87- }
88- let resolved_libs_dir = build_dir. join ( "libs" ) ;
89- if let Some ( watch) =
90- crate :: build_fingerprint:: fast_path_watch ( "dep_libs" , build_dir, & resolved_libs_dir)
91- {
92- watches. push ( watch) ;
93- }
94- watches
95- }
96-
9769impl BuildOrchestrator for AvrOrchestrator {
9870 fn platform ( & self ) -> Platform {
9971 Platform :: AtmelAvr
@@ -150,7 +122,6 @@ impl BuildOrchestrator for AvrOrchestrator {
150122 // This lives here rather than before `ensure_installed` so the hashed
151123 // toolchain/framework paths reflect the real install location.
152124 let build_dir = & ctx. build_dir ;
153- let fingerprint_path = build_fingerprint_path ( build_dir) ;
154125 let metadata_hash = stable_hash_json ( & AvrFingerprintMetadata {
155126 version : BUILD_FINGERPRINT_VERSION ,
156127 env_name : params. env_name . clone ( ) ,
@@ -168,31 +139,29 @@ impl BuildOrchestrator for AvrOrchestrator {
168139 max_flash : ctx. board . max_flash ,
169140 max_ram : ctx. board . max_ram ,
170141 } ) ?;
171- let fingerprint_watches = {
142+ let ( fast_elf, [ fast_hex] , fast_compile_db) =
143+ expected_fast_path_artifacts ( build_dir, & params. project_dir , [ "firmware.hex" ] ) ;
144+ let fast_path = {
172145 let _g = perf. phase ( "fp-watches-collect" ) ;
173- collect_fast_path_watches ( build_dir, & params. project_dir )
146+ FastPathContract :: for_project_outputs (
147+ build_dir,
148+ & params. project_dir ,
149+ [ fast_elf. clone ( ) , fast_hex. clone ( ) , fast_compile_db. clone ( ) ] ,
150+ )
174151 } ;
175152
176153 if !params. compiledb_only
177154 && !params. symbol_analysis
178155 && params. symbol_analysis_path . is_none ( )
179156 {
180157 let _fast_path_phase = perf. phase ( "fast-path-check" ) ;
181- let fast_elf = build_dir. join ( "firmware.elf" ) ;
182- let fast_hex = build_dir. join ( "firmware.hex" ) ;
183- let fast_compile_db =
184- CompileDatabase :: expected_output_path ( build_dir, & params. project_dir ) ;
185- let required_artifacts = [ fast_elf. clone ( ) , fast_hex. clone ( ) , fast_compile_db. clone ( ) ] ;
186- let inputs = FastPathInputs {
187- fingerprint_path : & fingerprint_path,
158+ let inputs = FastPathCheckInputs {
188159 metadata_hash : & metadata_hash,
189- watches : & fingerprint_watches,
190- required_artifacts : & required_artifacts,
191160 extra_artifact_ok : None ,
192161 watch_set_cache : params. watch_set_cache . as_deref ( ) ,
193162 compiler_cache : compiler_cache. as_deref ( ) ,
194163 } ;
195- if let Some ( hit) = crate :: build_fingerprint:: fast_path_check ( & inputs) ? {
164+ if let Some ( hit) = crate :: build_fingerprint:: fast_path_check ( & fast_path , & inputs) ? {
196165 ctx. build_log
197166 . push ( "No-op fingerprint matched; reusing existing AVR artifacts." . to_string ( ) ) ;
198167 let elapsed = start. elapsed ( ) . as_secs_f64 ( ) ;
@@ -315,35 +284,15 @@ impl BuildOrchestrator for AvrOrchestrator {
315284 && !params. symbol_analysis
316285 && params. symbol_analysis_path . is_none ( )
317286 {
318- let persisted_fingerprint = PersistedBuildFingerprint {
319- version : BUILD_FINGERPRINT_VERSION ,
320- metadata_hash : metadata_hash. clone ( ) ,
321- file_set_hash : match hash_watch_set_stamps_cached (
322- & fingerprint_watches,
323- params. watch_set_cache . as_deref ( ) ,
324- ) {
325- Ok ( hash) => Some ( hash) ,
326- Err ( e) => {
327- tracing:: warn!( "failed to hash watched inputs for fingerprint save: {}" , e) ;
328- None
329- }
287+ crate :: build_fingerprint:: persist_fast_path_success (
288+ & fast_path,
289+ & FastPathPersistInputs {
290+ metadata_hash : & metadata_hash,
291+ size_info : build_result. size_info . clone ( ) ,
292+ watch_set_cache : params. watch_set_cache . as_deref ( ) ,
293+ compiler_cache : compiler_cache. as_deref ( ) ,
330294 } ,
331- size_info : build_result. size_info . clone ( ) ,
332- } ;
333- if let Err ( e) = save_json ( & fingerprint_path, & persisted_fingerprint) {
334- tracing:: warn!( "failed to write build fingerprint: {}" , e) ;
335- }
336- if let Some ( ref zcc) = compiler_cache {
337- for watch in & fingerprint_watches {
338- if let Err ( e) = crate :: zccache:: mark_fingerprint_success ( zcc, watch) {
339- tracing:: warn!(
340- "failed to mark zccache fingerprint success for {}: {}" ,
341- watch. root. display( ) ,
342- e
343- ) ;
344- }
345- }
346- }
295+ ) ;
347296 }
348297
349298 Ok ( build_result)
0 commit comments