1 // Copyright 2017 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package build 16 17 import ( 18 "android/soong/finder" 19 "android/soong/finder/fs" 20 "android/soong/ui/logger" 21 "bytes" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 "strings" 26 ) 27 28 // This file provides an interface to the Finder for use in Soong UI 29 // This file stores configuration information about which files to find 30 31 // NewSourceFinder returns a new Finder configured to search for source files. 32 // Callers of NewSourceFinder should call <f.Shutdown()> when done 33 func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) { 34 ctx.BeginTrace("find modules") 35 defer ctx.EndTrace() 36 37 dir, err := os.Getwd() 38 if err != nil { 39 ctx.Fatalf("No working directory for module-finder: %v", err.Error()) 40 } 41 filesystem := fs.OsFs 42 43 // if the root dir is ignored, then the subsequent error messages are very confusing, 44 // so check for that upfront 45 pruneFiles := []string{".out-dir", ".find-ignore"} 46 for _, name := range pruneFiles { 47 prunePath := filepath.Join(dir, name) 48 _, statErr := filesystem.Lstat(prunePath) 49 if statErr == nil { 50 ctx.Fatalf("%v must not exist", prunePath) 51 } 52 } 53 54 cacheParams := finder.CacheParams{ 55 WorkingDirectory: dir, 56 RootDirs: []string{"."}, 57 ExcludeDirs: []string{".git", ".repo"}, 58 PruneFiles: pruneFiles, 59 IncludeFiles: []string{"Android.mk", "Android.bp", "Blueprints", "CleanSpec.mk", "TEST_MAPPING"}, 60 } 61 dumpDir := config.FileListDir() 62 f, err = finder.New(cacheParams, filesystem, logger.New(ioutil.Discard), 63 filepath.Join(dumpDir, "files.db")) 64 if err != nil { 65 ctx.Fatalf("Could not create module-finder: %v", err) 66 } 67 return f 68 } 69 70 // FindSources searches for source files known to <f> and writes them to the filesystem for 71 // use later. 72 func FindSources(ctx Context, config Config, f *finder.Finder) { 73 // note that dumpDir in FindSources may be different than dumpDir in NewSourceFinder 74 // if a caller such as multiproduct_kati wants to share one Finder among several builds 75 dumpDir := config.FileListDir() 76 os.MkdirAll(dumpDir, 0777) 77 78 androidMks := f.FindFirstNamedAt(".", "Android.mk") 79 err := dumpListToFile(androidMks, filepath.Join(dumpDir, "Android.mk.list")) 80 if err != nil { 81 ctx.Fatalf("Could not export module list: %v", err) 82 } 83 84 cleanSpecs := f.FindFirstNamedAt(".", "CleanSpec.mk") 85 dumpListToFile(cleanSpecs, filepath.Join(dumpDir, "CleanSpec.mk.list")) 86 if err != nil { 87 ctx.Fatalf("Could not export module list: %v", err) 88 } 89 90 testMappings := f.FindNamedAt(".", "TEST_MAPPING") 91 err = dumpListToFile(testMappings, filepath.Join(dumpDir, "TEST_MAPPING.list")) 92 if err != nil { 93 ctx.Fatalf("Could not find modules: %v", err) 94 } 95 96 androidBps := f.FindNamedAt(".", "Android.bp") 97 androidBps = append(androidBps, f.FindNamedAt("build/blueprint", "Blueprints")...) 98 if len(androidBps) == 0 { 99 ctx.Fatalf("No Android.bp found") 100 } 101 err = dumpListToFile(androidBps, filepath.Join(dumpDir, "Android.bp.list")) 102 if err != nil { 103 ctx.Fatalf("Could not find modules: %v", err) 104 } 105 } 106 107 func dumpListToFile(list []string, filePath string) (err error) { 108 desiredText := strings.Join(list, "\n") 109 desiredBytes := []byte(desiredText) 110 actualBytes, readErr := ioutil.ReadFile(filePath) 111 if readErr != nil || !bytes.Equal(desiredBytes, actualBytes) { 112 err = ioutil.WriteFile(filePath, desiredBytes, 0777) 113 } 114 return err 115 } 116