@@ -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