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