1111use std:: env;
1212use std:: ffi:: OsString ;
1313use std:: fs:: { self , File } ;
14+ use std:: io;
1415use std:: path:: { Path , PathBuf } ;
1516use std:: process:: Command ;
1617
@@ -54,7 +55,6 @@ impl Step for Llvm {
5455 }
5556 }
5657
57- let llvm_info = & builder. in_tree_llvm_info ;
5858 let root = "src/llvm-project/llvm" ;
5959 let out_dir = builder. llvm_out ( target) ;
6060 let mut llvm_config_ret_dir = builder. llvm_out ( builder. config . build ) ;
@@ -65,40 +65,35 @@ impl Step for Llvm {
6565
6666 let build_llvm_config =
6767 llvm_config_ret_dir. join ( exe ( "llvm-config" , & * builder. config . build ) ) ;
68- let done_stamp = out_dir. join ( "llvm-finished-building" ) ;
6968
70- if done_stamp. exists ( ) {
71- if builder. config . llvm_skip_rebuild {
72- builder. info (
73- "Warning: \
74- Using a potentially stale build of LLVM; \
75- This may not behave well.",
76- ) ;
77- return build_llvm_config;
78- }
69+ let stamp = out_dir. join ( "llvm-finished-building" ) ;
70+ let stamp = HashStamp :: new ( stamp, builder. in_tree_llvm_info . sha ( ) ) ;
7971
80- if let Some ( llvm_commit) = llvm_info. sha ( ) {
81- let done_contents = t ! ( fs:: read( & done_stamp) ) ;
72+ if builder. config . llvm_skip_rebuild && stamp. path . exists ( ) {
73+ builder. info (
74+ "Warning: \
75+ Using a potentially stale build of LLVM; \
76+ This may not behave well.",
77+ ) ;
78+ return build_llvm_config;
79+ }
8280
83- // If LLVM was already built previously and the submodule's commit didn't change
84- // from the previous build, then no action is required.
85- if done_contents == llvm_commit. as_bytes ( ) {
86- return build_llvm_config;
87- }
88- } else {
81+ if stamp. is_done ( ) {
82+ if stamp. hash . is_none ( ) {
8983 builder. info (
9084 "Could not determine the LLVM submodule commit hash. \
9185 Assuming that an LLVM rebuild is not necessary.",
9286 ) ;
9387 builder. info ( & format ! (
9488 "To force LLVM to rebuild, remove the file `{}`" ,
95- done_stamp . display( )
89+ stamp . path . display( )
9690 ) ) ;
97- return build_llvm_config;
9891 }
92+ return build_llvm_config;
9993 }
10094
10195 builder. info ( & format ! ( "Building LLVM for {}" , target) ) ;
96+ t ! ( stamp. remove( ) ) ;
10297 let _time = util:: timeit ( & builder) ;
10398 t ! ( fs:: create_dir_all( & out_dir) ) ;
10499
@@ -271,7 +266,7 @@ impl Step for Llvm {
271266
272267 cfg. build ( ) ;
273268
274- t ! ( fs :: write( & done_stamp , llvm_info . sha ( ) . unwrap_or ( "" ) ) ) ;
269+ t ! ( stamp . write( ) ) ;
275270
276271 build_llvm_config
277272 }
@@ -584,17 +579,21 @@ impl Step for Sanitizers {
584579 return runtimes;
585580 }
586581
587- let done_stamp = out_dir. join ( "sanitizers-finished-building" ) ;
588- if done_stamp. exists ( ) {
589- builder. info ( & format ! (
590- "Assuming that sanitizers rebuild is not necessary. \
591- To force a rebuild, remove the file `{}`",
592- done_stamp. display( )
593- ) ) ;
582+ let stamp = out_dir. join ( "sanitizers-finished-building" ) ;
583+ let stamp = HashStamp :: new ( stamp, builder. in_tree_llvm_info . sha ( ) ) ;
584+
585+ if stamp. is_done ( ) {
586+ if stamp. hash . is_none ( ) {
587+ builder. info ( & format ! (
588+ "Rebuild sanitizers by removing the file `{}`" ,
589+ stamp. path. display( )
590+ ) ) ;
591+ }
594592 return runtimes;
595593 }
596594
597595 builder. info ( & format ! ( "Building sanitizers for {}" , self . target) ) ;
596+ t ! ( stamp. remove( ) ) ;
598597 let _time = util:: timeit ( & builder) ;
599598
600599 let mut cfg = cmake:: Config :: new ( & compiler_rt_dir) ;
@@ -623,8 +622,7 @@ impl Step for Sanitizers {
623622 cfg. build_target ( & runtime. cmake_target ) ;
624623 cfg. build ( ) ;
625624 }
626-
627- t ! ( fs:: write( & done_stamp, b"" ) ) ;
625+ t ! ( stamp. write( ) ) ;
628626
629627 runtimes
630628 }
@@ -689,3 +687,41 @@ fn supported_sanitizers(
689687 }
690688 result
691689}
690+
691+ struct HashStamp {
692+ path : PathBuf ,
693+ hash : Option < Vec < u8 > > ,
694+ }
695+
696+ impl HashStamp {
697+ fn new ( path : PathBuf , hash : Option < & str > ) -> Self {
698+ HashStamp { path, hash : hash. map ( |s| s. as_bytes ( ) . to_owned ( ) ) }
699+ }
700+
701+ fn is_done ( & self ) -> bool {
702+ match fs:: read ( & self . path ) {
703+ Ok ( h) => self . hash . as_deref ( ) . unwrap_or ( b"" ) == h. as_slice ( ) ,
704+ Err ( e) if e. kind ( ) == io:: ErrorKind :: NotFound => false ,
705+ Err ( e) => {
706+ panic ! ( "failed to read stamp file `{}`: {}" , self . path. display( ) , e) ;
707+ }
708+ }
709+ }
710+
711+ fn remove ( & self ) -> io:: Result < ( ) > {
712+ match fs:: remove_file ( & self . path ) {
713+ Ok ( ( ) ) => Ok ( ( ) ) ,
714+ Err ( e) => {
715+ if e. kind ( ) == io:: ErrorKind :: NotFound {
716+ Ok ( ( ) )
717+ } else {
718+ Err ( e)
719+ }
720+ }
721+ }
722+ }
723+
724+ fn write ( & self ) -> io:: Result < ( ) > {
725+ fs:: write ( & self . path , self . hash . as_deref ( ) . unwrap_or ( b"" ) )
726+ }
727+ }
0 commit comments