Skip to content

Commit cdea62d

Browse files
committed
Optimize copy_src_dirs
1 parent 5107ac9 commit cdea62d

File tree

1 file changed

+42
-39
lines changed
  • src/bootstrap/src/core/build_steps

1 file changed

+42
-39
lines changed

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -916,79 +916,74 @@ fn copy_src_dirs(
916916
exclude_dirs: &[&str],
917917
dst_dir: &Path,
918918
) {
919+
// The src directories should be relative to `base`, we depend on them not being absolute
920+
// paths below.
921+
for src_dir in src_dirs {
922+
assert!(Path::new(src_dir).is_relative());
923+
}
924+
919925
// Iterating, filtering and copying a large number of directories can be quite slow.
920926
// Avoid doing it in dry run (and thus also tests).
921927
if builder.config.dry_run() {
922928
return;
923929
}
924930

925931
fn filter_fn(exclude_dirs: &[&str], dir: &str, path: &Path) -> bool {
932+
// The paths are relative, e.g. `llvm-project/...`.
926933
let spath = match path.to_str() {
927934
Some(path) => path,
928935
None => return false,
929936
};
930937
if spath.ends_with('~') || spath.ends_with(".pyc") {
931938
return false;
932939
}
940+
// Normalize slashes
941+
let spath = spath.replace("\\", "/");
933942

934-
const LLVM_PROJECTS: &[&str] = &[
943+
static LLVM_PROJECTS: &[&str] = &[
935944
"llvm-project/clang",
936-
"llvm-project\\clang",
937945
"llvm-project/libunwind",
938-
"llvm-project\\libunwind",
939946
"llvm-project/lld",
940-
"llvm-project\\lld",
941947
"llvm-project/lldb",
942-
"llvm-project\\lldb",
943948
"llvm-project/llvm",
944-
"llvm-project\\llvm",
945949
"llvm-project/compiler-rt",
946-
"llvm-project\\compiler-rt",
947950
"llvm-project/cmake",
948-
"llvm-project\\cmake",
949951
"llvm-project/runtimes",
950-
"llvm-project\\runtimes",
951952
"llvm-project/third-party",
952-
"llvm-project\\third-party",
953953
];
954-
if spath.contains("llvm-project")
955-
&& !spath.ends_with("llvm-project")
956-
&& !LLVM_PROJECTS.iter().any(|path| spath.contains(path))
957-
{
958-
return false;
959-
}
954+
if spath.starts_with("llvm-project") && spath != "llvm-project" {
955+
if !LLVM_PROJECTS.iter().any(|path| spath.starts_with(path)) {
956+
return false;
957+
}
960958

961-
// Keep only these third party libraries
962-
const LLVM_THIRD_PARTY: &[&str] =
963-
&["llvm-project/third-party/siphash", "llvm-project\\third-party\\siphash"];
964-
if (spath.starts_with("llvm-project/third-party")
965-
|| spath.starts_with("llvm-project\\third-party"))
966-
&& !(spath.ends_with("llvm-project/third-party")
967-
|| spath.ends_with("llvm-project\\third-party"))
968-
&& !LLVM_THIRD_PARTY.iter().any(|path| spath.contains(path))
969-
{
970-
return false;
971-
}
959+
// Keep siphash third-party dependency
960+
if spath.starts_with("llvm-project/third-party")
961+
&& spath != "llvm-project/third-party"
962+
&& !spath.starts_with("llvm-project/third-party/siphash")
963+
{
964+
return false;
965+
}
972966

973-
const LLVM_TEST: &[&str] = &["llvm-project/llvm/test", "llvm-project\\llvm\\test"];
974-
if LLVM_TEST.iter().any(|path| spath.contains(path))
975-
&& (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s"))
976-
{
977-
return false;
967+
if spath.starts_with("llvm-project/llvm/test")
968+
&& (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s"))
969+
{
970+
return false;
971+
}
978972
}
979973

980974
// Cargo tests use some files like `.gitignore` that we would otherwise exclude.
981-
const CARGO_TESTS: &[&str] = &["tools/cargo/tests", "tools\\cargo\\tests"];
982-
if CARGO_TESTS.iter().any(|path| spath.contains(path)) {
975+
if spath.starts_with("tools/cargo/tests") {
983976
return true;
984977
}
985978

986-
let full_path = Path::new(dir).join(path);
987-
if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
988-
return false;
979+
if !exclude_dirs.is_empty() {
980+
let full_path = Path::new(dir).join(path);
981+
if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
982+
return false;
983+
}
989984
}
990985

991-
let excludes = [
986+
static EXCLUDES: &[&str] = &[
992987
"CVS",
993988
"RCS",
994989
"SCCS",
@@ -1011,7 +1006,15 @@ fn copy_src_dirs(
10111006
".hgrags",
10121007
"_darcs",
10131008
];
1014-
!path.iter().map(|s| s.to_str().unwrap()).any(|s| excludes.contains(&s))
1009+
1010+
// We want to check if any component of `path` doesn't contain the strings in `EXCLUDES`.
1011+
// However, since we traverse directories top-down in `Builder::cp_link_filtered`,
1012+
// it is enough to always check only the last component:
1013+
// - If the path is a file, we will iterate to it and then check it's filename
1014+
// - If the path is a dir, if it's dir name contains an excluded string, we will not even
1015+
// recurse into it.
1016+
let last_component = path.iter().next_back().map(|s| s.to_str().unwrap()).unwrap();
1017+
!EXCLUDES.contains(&last_component)
10151018
}
10161019

10171020
// Copy the directories using our filter

0 commit comments

Comments
 (0)