1package build 2 3import ( 4 "compress/gzip" 5 "fmt" 6 "os" 7 "path/filepath" 8 "sort" 9 "strings" 10 11 "android/soong/shared" 12 "android/soong/ui/metrics" 13) 14 15func sortedStringSetKeys(m map[string]bool) []string { 16 result := make([]string, 0, len(m)) 17 for key := range m { 18 result = append(result, key) 19 } 20 sort.Strings(result) 21 return result 22} 23 24func addSlash(str string) string { 25 if len(str) == 0 { 26 return "" 27 } 28 if str[len(str)-1] == '/' { 29 return str 30 } 31 return str + "/" 32} 33 34func hasPrefixStrings(str string, prefixes []string) bool { 35 for _, prefix := range prefixes { 36 if strings.HasPrefix(str, prefix) { 37 return true 38 } 39 } 40 return false 41} 42 43// Output DIST_DIR/source_inputs.txt.gz, which will contain a listing of the files 44// in the source tree (not including in the out directory) that were declared as ninja 45// inputs to the build that was just done. 46func runSourceInputs(ctx Context, config Config) { 47 ctx.BeginTrace(metrics.RunSoong, "runSourceInputs") 48 defer ctx.EndTrace() 49 50 success := false 51 outputFilename := shared.JoinPath(config.RealDistDir(), "source_inputs.txt.gz") 52 53 outputFile, err := os.Create(outputFilename) 54 if err != nil { 55 fmt.Fprintf(os.Stderr, "source_files_used: unable to open file for write: %s\n", outputFilename) 56 return 57 } 58 defer func() { 59 outputFile.Close() 60 if !success { 61 os.Remove(outputFilename) 62 } 63 }() 64 65 output := gzip.NewWriter(outputFile) 66 defer output.Close() 67 68 // Skip out dir, both absolute and relative. There are some files 69 // generated during analysis that ninja thinks are inputs not intermediates. 70 absOut, _ := filepath.Abs(config.OutDir()) 71 excludes := []string{ 72 addSlash(config.OutDir()), 73 addSlash(absOut), 74 } 75 76 goals := config.NinjaArgs() 77 78 result := make(map[string]bool) 79 for _, goal := range goals { 80 inputs, err := runNinjaInputs(ctx, config, goal) 81 if err != nil { 82 fmt.Fprintf(os.Stderr, "source_files_used: %v\n", err) 83 return 84 } 85 86 for _, filename := range inputs { 87 if !hasPrefixStrings(filename, excludes) { 88 result[filename] = true 89 } 90 } 91 } 92 93 for _, filename := range sortedStringSetKeys(result) { 94 output.Write([]byte(filename)) 95 output.Write([]byte("\n")) 96 } 97 98 output.Flush() 99 success = true 100} 101