]>
Commit | Line | Data |
---|---|---|
7453a54e SL |
1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
a7813a04 XL |
11 | //! Implementation of `make clean` in rustbuild. |
12 | //! | |
13 | //! Responsible for cleaning out a build directory of all old and stale | |
14 | //! artifacts to prepare for a fresh build. Currently doesn't remove the | |
15 | //! `build/cache` directory (download cache) or the `build/$target/llvm` | |
16 | //! directory as we want that cached between builds. | |
17 | ||
7453a54e | 18 | use std::fs; |
c30ab7b3 | 19 | use std::io::{self, ErrorKind}; |
7453a54e SL |
20 | use std::path::Path; |
21 | ||
5bcae85e | 22 | use Build; |
7453a54e SL |
23 | |
24 | pub fn clean(build: &Build) { | |
3157f602 XL |
25 | rm_rf(build, "tmp".as_ref()); |
26 | rm_rf(build, &build.out.join("tmp")); | |
27 | ||
7453a54e | 28 | for host in build.config.host.iter() { |
c30ab7b3 SL |
29 | let entries = match build.out.join(host).read_dir() { |
30 | Ok(iter) => iter, | |
31 | Err(_) => continue, | |
32 | }; | |
7453a54e | 33 | |
c30ab7b3 SL |
34 | for entry in entries { |
35 | let entry = t!(entry); | |
36 | if entry.file_name().to_str() == Some("llvm") { | |
37 | continue | |
38 | } | |
39 | let path = t!(entry.path().canonicalize()); | |
40 | rm_rf(build, &path); | |
41 | } | |
42 | } | |
43 | } | |
7453a54e | 44 | |
c30ab7b3 SL |
45 | fn rm_rf(build: &Build, path: &Path) { |
46 | if !path.exists() { | |
47 | return | |
48 | } | |
7453a54e | 49 | |
c30ab7b3 SL |
50 | for file in t!(fs::read_dir(path)) { |
51 | let file = t!(file).path(); | |
52 | ||
53 | if file.is_dir() { | |
54 | rm_rf(build, &file); | |
55 | } else { | |
56 | // On windows we can't remove a readonly file, and git will | |
57 | // often clone files as readonly. As a result, we have some | |
58 | // special logic to remove readonly files on windows. | |
59 | do_op(&file, "remove file", |p| fs::remove_file(p)); | |
7453a54e SL |
60 | } |
61 | } | |
c30ab7b3 | 62 | do_op(path, "remove dir", |p| fs::remove_dir(p)); |
7453a54e SL |
63 | } |
64 | ||
c30ab7b3 SL |
65 | fn do_op<F>(path: &Path, desc: &str, mut f: F) |
66 | where F: FnMut(&Path) -> io::Result<()> | |
67 | { | |
68 | match f(path) { | |
69 | Ok(()) => {} | |
70 | Err(ref e) if cfg!(windows) && | |
71 | e.kind() == ErrorKind::PermissionDenied => { | |
72 | let mut p = t!(path.metadata()).permissions(); | |
73 | p.set_readonly(false); | |
74 | t!(fs::set_permissions(path, p)); | |
75 | f(path).unwrap_or_else(|e| { | |
76 | panic!("failed to {} {}: {}", desc, path.display(), e); | |
77 | }) | |
78 | } | |
79 | Err(e) => { | |
80 | panic!("failed to {} {}: {}", desc, path.display(), e); | |
81 | } | |
7453a54e SL |
82 | } |
83 | } |