Rollup merge of #69735 - tmiasko:bootstrap-sanitizers-hash, r=Mark-Simulacrum
bootstrap: Use hash to determine if sanitizers needs to be rebuilt * Rebuild sanitizers runtimes when LLVM submodule commit changes. * When rebuilding LLVM / sanitizers, remove the stamp file before starting the build process to invalidate previous build output.
This commit is contained in:
commit
c4a900f57c
@ -11,6 +11,7 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
@ -54,7 +55,6 @@ impl Step for Llvm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let llvm_info = &builder.in_tree_llvm_info;
|
|
||||||
let root = "src/llvm-project/llvm";
|
let root = "src/llvm-project/llvm";
|
||||||
let out_dir = builder.llvm_out(target);
|
let out_dir = builder.llvm_out(target);
|
||||||
let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
|
let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
|
||||||
@ -65,10 +65,11 @@ impl Step for Llvm {
|
|||||||
|
|
||||||
let build_llvm_config =
|
let build_llvm_config =
|
||||||
llvm_config_ret_dir.join(exe("llvm-config", &*builder.config.build));
|
llvm_config_ret_dir.join(exe("llvm-config", &*builder.config.build));
|
||||||
let done_stamp = out_dir.join("llvm-finished-building");
|
|
||||||
|
|
||||||
if done_stamp.exists() {
|
let stamp = out_dir.join("llvm-finished-building");
|
||||||
if builder.config.llvm_skip_rebuild {
|
let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha());
|
||||||
|
|
||||||
|
if builder.config.llvm_skip_rebuild && stamp.path.exists() {
|
||||||
builder.info(
|
builder.info(
|
||||||
"Warning: \
|
"Warning: \
|
||||||
Using a potentially stale build of LLVM; \
|
Using a potentially stale build of LLVM; \
|
||||||
@ -77,28 +78,22 @@ impl Step for Llvm {
|
|||||||
return build_llvm_config;
|
return build_llvm_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(llvm_commit) = llvm_info.sha() {
|
if stamp.is_done() {
|
||||||
let done_contents = t!(fs::read(&done_stamp));
|
if stamp.hash.is_none() {
|
||||||
|
|
||||||
// If LLVM was already built previously and the submodule's commit didn't change
|
|
||||||
// from the previous build, then no action is required.
|
|
||||||
if done_contents == llvm_commit.as_bytes() {
|
|
||||||
return build_llvm_config;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
builder.info(
|
builder.info(
|
||||||
"Could not determine the LLVM submodule commit hash. \
|
"Could not determine the LLVM submodule commit hash. \
|
||||||
Assuming that an LLVM rebuild is not necessary.",
|
Assuming that an LLVM rebuild is not necessary.",
|
||||||
);
|
);
|
||||||
builder.info(&format!(
|
builder.info(&format!(
|
||||||
"To force LLVM to rebuild, remove the file `{}`",
|
"To force LLVM to rebuild, remove the file `{}`",
|
||||||
done_stamp.display()
|
stamp.path.display()
|
||||||
));
|
));
|
||||||
return build_llvm_config;
|
|
||||||
}
|
}
|
||||||
|
return build_llvm_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.info(&format!("Building LLVM for {}", target));
|
builder.info(&format!("Building LLVM for {}", target));
|
||||||
|
t!(stamp.remove());
|
||||||
let _time = util::timeit(&builder);
|
let _time = util::timeit(&builder);
|
||||||
t!(fs::create_dir_all(&out_dir));
|
t!(fs::create_dir_all(&out_dir));
|
||||||
|
|
||||||
@ -271,7 +266,7 @@ impl Step for Llvm {
|
|||||||
|
|
||||||
cfg.build();
|
cfg.build();
|
||||||
|
|
||||||
t!(fs::write(&done_stamp, llvm_info.sha().unwrap_or("")));
|
t!(stamp.write());
|
||||||
|
|
||||||
build_llvm_config
|
build_llvm_config
|
||||||
}
|
}
|
||||||
@ -584,17 +579,21 @@ impl Step for Sanitizers {
|
|||||||
return runtimes;
|
return runtimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
let done_stamp = out_dir.join("sanitizers-finished-building");
|
let stamp = out_dir.join("sanitizers-finished-building");
|
||||||
if done_stamp.exists() {
|
let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha());
|
||||||
|
|
||||||
|
if stamp.is_done() {
|
||||||
|
if stamp.hash.is_none() {
|
||||||
builder.info(&format!(
|
builder.info(&format!(
|
||||||
"Assuming that sanitizers rebuild is not necessary. \
|
"Rebuild sanitizers by removing the file `{}`",
|
||||||
To force a rebuild, remove the file `{}`",
|
stamp.path.display()
|
||||||
done_stamp.display()
|
|
||||||
));
|
));
|
||||||
|
}
|
||||||
return runtimes;
|
return runtimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.info(&format!("Building sanitizers for {}", self.target));
|
builder.info(&format!("Building sanitizers for {}", self.target));
|
||||||
|
t!(stamp.remove());
|
||||||
let _time = util::timeit(&builder);
|
let _time = util::timeit(&builder);
|
||||||
|
|
||||||
let mut cfg = cmake::Config::new(&compiler_rt_dir);
|
let mut cfg = cmake::Config::new(&compiler_rt_dir);
|
||||||
@ -623,8 +622,7 @@ impl Step for Sanitizers {
|
|||||||
cfg.build_target(&runtime.cmake_target);
|
cfg.build_target(&runtime.cmake_target);
|
||||||
cfg.build();
|
cfg.build();
|
||||||
}
|
}
|
||||||
|
t!(stamp.write());
|
||||||
t!(fs::write(&done_stamp, b""));
|
|
||||||
|
|
||||||
runtimes
|
runtimes
|
||||||
}
|
}
|
||||||
@ -689,3 +687,41 @@ fn supported_sanitizers(
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct HashStamp {
|
||||||
|
path: PathBuf,
|
||||||
|
hash: Option<Vec<u8>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HashStamp {
|
||||||
|
fn new(path: PathBuf, hash: Option<&str>) -> Self {
|
||||||
|
HashStamp { path, hash: hash.map(|s| s.as_bytes().to_owned()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_done(&self) -> bool {
|
||||||
|
match fs::read(&self.path) {
|
||||||
|
Ok(h) => self.hash.as_deref().unwrap_or(b"") == h.as_slice(),
|
||||||
|
Err(e) if e.kind() == io::ErrorKind::NotFound => false,
|
||||||
|
Err(e) => {
|
||||||
|
panic!("failed to read stamp file `{}`: {}", self.path.display(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&self) -> io::Result<()> {
|
||||||
|
match fs::remove_file(&self.path) {
|
||||||
|
Ok(()) => Ok(()),
|
||||||
|
Err(e) => {
|
||||||
|
if e.kind() == io::ErrorKind::NotFound {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(&self) -> io::Result<()> {
|
||||||
|
fs::write(&self.path, self.hash.as_deref().unwrap_or(b""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user