@@ -7,6 +7,7 @@ use serde::Serialize;
77
88use crate :: CargoResult ;
99use crate :: core:: compiler:: BuildRunner ;
10+ use crate :: core:: compiler:: CompileKind ;
1011
1112/// Structure used to deal with Rustdoc fingerprinting
1213///
@@ -30,10 +31,17 @@ impl RustDocFingerprint {
3031 /// was the same as the one is currently being used in this `cargo doc` call.
3132 ///
3233 /// In case it's not,
33- /// it takes care of removing the `<artifact -dir>/doc/` folder
34+ /// it takes care of removing the `<build -dir>/doc/` folder
3435 /// as well as overwriting the rustdoc fingerprint info.
3536 /// This is to guarantee that we won't end up with mixed versions of the `js/html/css` files
3637 /// which `rustdoc` autogenerates without any versioning.
38+ ///
39+ /// Each requested target platform maintains its own fingerprint file.
40+ /// That is, if you run `cargo doc` and then `cargo doc --target wasm32-wasip1`,
41+ /// you will have two separate fingerprint files:
42+ ///
43+ /// * `<build-dir>/.rustdoc_fingerprint.json` for host
44+ /// * `<build-dir>/wasm32-wasip1/.rustdoc_fingerprint.json`
3745 pub fn check_rustdoc_fingerprint ( build_runner : & BuildRunner < ' _ , ' _ > ) -> CargoResult < ( ) > {
3846 if build_runner
3947 . bcx
@@ -43,68 +51,79 @@ impl RustDocFingerprint {
4351 {
4452 return Ok ( ( ) ) ;
4553 }
46- let actual_rustdoc_target_data = RustDocFingerprint {
54+ let new_fingerprint = RustDocFingerprint {
4755 rustc_vv : build_runner. bcx . rustc ( ) . verbose_version . clone ( ) ,
4856 } ;
4957
50- let fingerprint_path = build_runner
51- . files ( )
52- . host_build_root ( )
53- . join ( ".rustdoc_fingerprint.json" ) ;
54- let write_fingerprint = || -> CargoResult < ( ) > {
55- paths:: write (
56- & fingerprint_path,
57- serde_json:: to_string ( & actual_rustdoc_target_data) ?,
58- )
59- } ;
60- let Ok ( rustdoc_data) = paths:: read ( & fingerprint_path) else {
61- // If the fingerprint does not exist, do not clear out the doc
62- // directories. Otherwise this ran into problems where projects
63- // like bootstrap were creating the doc directory before running
64- // `cargo doc` in a way that deleting it would break it.
65- return write_fingerprint ( ) ;
66- } ;
67- match serde_json:: from_str :: < RustDocFingerprint > ( & rustdoc_data) {
68- Ok ( fingerprint) => {
69- if fingerprint. rustc_vv == actual_rustdoc_target_data. rustc_vv {
70- return Ok ( ( ) ) ;
71- } else {
72- tracing:: debug!(
73- "doc fingerprint changed:\n original:\n {}\n new:\n {}" ,
74- fingerprint. rustc_vv,
75- actual_rustdoc_target_data. rustc_vv
76- ) ;
77- }
78- }
79- Err ( e) => {
80- tracing:: debug!( "could not deserialize {:?}: {}" , fingerprint_path, e) ;
81- }
82- } ;
83- // Fingerprint does not match, delete the doc directories and write a new fingerprint.
84- tracing:: debug!(
85- "fingerprint {:?} mismatch, clearing doc directories" ,
86- fingerprint_path
87- ) ;
88- build_runner
89- . bcx
90- . all_kinds
91- . iter ( )
92- . map ( |kind| {
93- build_runner
94- . files ( )
95- . layout ( * kind)
96- . artifact_dir ( )
97- . expect ( "artifact-dir was not locked" )
98- . doc ( )
99- } )
100- . filter ( |path| path. exists ( ) )
101- . try_for_each ( |path| clean_doc ( path) ) ?;
102- write_fingerprint ( ) ?;
58+ for kind in & build_runner. bcx . build_config . requested_kinds {
59+ check_fingerprint ( build_runner, & new_fingerprint, * kind) ?;
60+ }
10361
10462 Ok ( ( ) )
10563 }
10664}
10765
66+ /// Checks rustdoc fingerprint file for a given [`CompileKind`].
67+ fn check_fingerprint (
68+ build_runner : & BuildRunner < ' _ , ' _ > ,
69+ new_fingerprint : & RustDocFingerprint ,
70+ kind : CompileKind ,
71+ ) -> CargoResult < ( ) > {
72+ let fingerprint_path = build_runner
73+ . files ( )
74+ . layout ( kind)
75+ . build_dir ( )
76+ . root ( )
77+ . join ( ".rustdoc_fingerprint.json" ) ;
78+
79+ let write_fingerprint = || -> CargoResult < ( ) > {
80+ paths:: write ( & fingerprint_path, serde_json:: to_string ( new_fingerprint) ?)
81+ } ;
82+
83+ let Ok ( rustdoc_data) = paths:: read ( & fingerprint_path) else {
84+ // If the fingerprint does not exist, do not clear out the doc
85+ // directories. Otherwise this ran into problems where projects
86+ // like bootstrap were creating the doc directory before running
87+ // `cargo doc` in a way that deleting it would break it.
88+ return write_fingerprint ( ) ;
89+ } ;
90+
91+ match serde_json:: from_str :: < RustDocFingerprint > ( & rustdoc_data) {
92+ Ok ( on_disk_fingerprint) => {
93+ if on_disk_fingerprint. rustc_vv == new_fingerprint. rustc_vv {
94+ return Ok ( ( ) ) ;
95+ } else {
96+ tracing:: debug!(
97+ "doc fingerprint changed:\n original:\n {}\n new:\n {}" ,
98+ on_disk_fingerprint. rustc_vv,
99+ new_fingerprint. rustc_vv
100+ ) ;
101+ }
102+ }
103+ Err ( e) => {
104+ tracing:: debug!( "could not deserialize {:?}: {}" , fingerprint_path, e) ;
105+ }
106+ } ;
107+ // Fingerprint does not match, delete the doc directories and write a new fingerprint.
108+ tracing:: debug!(
109+ "fingerprint {:?} mismatch, clearing doc directories" ,
110+ fingerprint_path
111+ ) ;
112+ let doc_dir = build_runner
113+ . files ( )
114+ . layout ( kind)
115+ . artifact_dir ( )
116+ . expect ( "artifact-dir was not locked" )
117+ . doc ( ) ;
118+ if doc_dir. exists ( ) {
119+ clean_doc ( doc_dir) ?;
120+ }
121+
122+ write_fingerprint ( ) ?;
123+
124+ Ok ( ( ) )
125+ }
126+
108127fn clean_doc ( path : & Path ) -> CargoResult < ( ) > {
109128 let entries = path
110129 . read_dir ( )
0 commit comments