Skip to content

Commit e18c79a

Browse files
committed
Work around various issues cleaning up bootstrap on Windows
1 parent f52caa7 commit e18c79a

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

src/bootstrap/clean.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ pub fn clean(build: &Build, all: bool) {
2121
} else {
2222
rm_rf(&build.out.join("tmp"));
2323
rm_rf(&build.out.join("dist"));
24-
// Only delete the bootstrap executable on non-Windows systems
25-
// Windows does not allow deleting a currently running executable
26-
#[cfg(not(windows))]
2724
rm_rf(&build.out.join("bootstrap"));
2825

2926
for host in &build.hosts {
@@ -54,14 +51,40 @@ fn rm_rf(path: &Path) {
5451
}
5552
Ok(metadata) => {
5653
if metadata.file_type().is_file() || metadata.file_type().is_symlink() {
57-
do_op(path, "remove file", |p| fs::remove_file(p));
54+
do_op(path, "remove file", |p| {
55+
fs::remove_file(p).or_else(|e| {
56+
// Work around the fact that we cannot
57+
// delete an executable while it runs on Windows.
58+
#[cfg(windows)]
59+
if e.kind() == std::io::ErrorKind::PermissionDenied
60+
&& p.file_name().and_then(std::ffi::OsStr::to_str)
61+
== Some("bootstrap.exe")
62+
{
63+
eprintln!("warning: failed to delete '{}'.", p.display());
64+
return Ok(());
65+
}
66+
Err(e)
67+
})
68+
});
5869
return;
5970
}
6071

6172
for file in t!(fs::read_dir(path)) {
6273
rm_rf(&t!(file).path());
6374
}
64-
do_op(path, "remove dir", |p| fs::remove_dir(p));
75+
do_op(path, "remove dir", |p| {
76+
fs::remove_dir(p).or_else(|e| {
77+
// Check for dir not empty on Windows
78+
#[cfg(windows)]
79+
if matches!(e.kind(), std::io::ErrorKind::Other)
80+
&& e.raw_os_error() == Some(145)
81+
{
82+
return Ok(());
83+
}
84+
85+
Err(e)
86+
})
87+
});
6588
}
6689
};
6790
}
@@ -80,8 +103,15 @@ where
80103
p.set_readonly(false);
81104
t!(fs::set_permissions(path, p));
82105
f(path).unwrap_or_else(|e| {
106+
// Deleting symlinked directories on Windows is non-trivial.
107+
// Skip doing so for now.
108+
#[cfg(windows)]
109+
if e.kind() == ErrorKind::PermissionDenied && path.is_dir() {
110+
eprintln!("warning: failed to delete '{}'.", path.display());
111+
return;
112+
}
83113
panic!("failed to {} {}: {}", desc, path.display(), e);
84-
})
114+
});
85115
}
86116
Err(e) => {
87117
panic!("failed to {} {}: {}", desc, path.display(), e);

0 commit comments

Comments
 (0)