11
11
use std:: env;
12
12
use std:: ffi:: OsString ;
13
13
use std:: fs:: { self , File } ;
14
+ use std:: io;
14
15
use std:: path:: { Path , PathBuf } ;
15
16
use std:: process:: Command ;
16
17
@@ -54,7 +55,6 @@ impl Step for Llvm {
54
55
}
55
56
}
56
57
57
- let llvm_info = & builder. in_tree_llvm_info ;
58
58
let root = "src/llvm-project/llvm" ;
59
59
let out_dir = builder. llvm_out ( target) ;
60
60
let mut llvm_config_ret_dir = builder. llvm_out ( builder. config . build ) ;
@@ -65,40 +65,35 @@ impl Step for Llvm {
65
65
66
66
let build_llvm_config =
67
67
llvm_config_ret_dir. join ( exe ( "llvm-config" , & * builder. config . build ) ) ;
68
- let done_stamp = out_dir. join ( "llvm-finished-building" ) ;
69
68
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 ( ) ) ;
79
71
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
+ }
82
80
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 ( ) {
89
83
builder. info (
90
84
"Could not determine the LLVM submodule commit hash. \
91
85
Assuming that an LLVM rebuild is not necessary.",
92
86
) ;
93
87
builder. info ( & format ! (
94
88
"To force LLVM to rebuild, remove the file `{}`" ,
95
- done_stamp . display( )
89
+ stamp . path . display( )
96
90
) ) ;
97
- return build_llvm_config;
98
91
}
92
+ return build_llvm_config;
99
93
}
100
94
101
95
builder. info ( & format ! ( "Building LLVM for {}" , target) ) ;
96
+ t ! ( stamp. remove( ) ) ;
102
97
let _time = util:: timeit ( & builder) ;
103
98
t ! ( fs:: create_dir_all( & out_dir) ) ;
104
99
@@ -271,7 +266,7 @@ impl Step for Llvm {
271
266
272
267
cfg. build ( ) ;
273
268
274
- t ! ( fs :: write( & done_stamp , llvm_info . sha ( ) . unwrap_or ( "" ) ) ) ;
269
+ t ! ( stamp . write( ) ) ;
275
270
276
271
build_llvm_config
277
272
}
@@ -584,17 +579,21 @@ impl Step for Sanitizers {
584
579
return runtimes;
585
580
}
586
581
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
+ }
594
592
return runtimes;
595
593
}
596
594
597
595
builder. info ( & format ! ( "Building sanitizers for {}" , self . target) ) ;
596
+ t ! ( stamp. remove( ) ) ;
598
597
let _time = util:: timeit ( & builder) ;
599
598
600
599
let mut cfg = cmake:: Config :: new ( & compiler_rt_dir) ;
@@ -623,8 +622,7 @@ impl Step for Sanitizers {
623
622
cfg. build_target ( & runtime. cmake_target ) ;
624
623
cfg. build ( ) ;
625
624
}
626
-
627
- t ! ( fs:: write( & done_stamp, b"" ) ) ;
625
+ t ! ( stamp. write( ) ) ;
628
626
629
627
runtimes
630
628
}
@@ -689,3 +687,41 @@ fn supported_sanitizers(
689
687
}
690
688
result
691
689
}
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