• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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