Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a798d960 authored by Chris Parsons's avatar Chris Parsons
Browse files

find bazel-related files and add them to bazel.list and ninja deps

This retriggers soong_build whenever a new bzl, WORKSPACE, or
BUILD.bazel file is changed or added.

Test: Manually verified on bionic/libc genrules with manual changes to
related BUILD/bzl/WORKSPACE files -- these all retrigger builds.
Test: Updated finder_test.go

Change-Id: I634384f88781a6b6db32f5d6bf9c07e179e14c39
parent 19bc60ab
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -18,11 +18,15 @@ import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"sync"

	"github.com/google/blueprint/bootstrap"
)

// Map key to describe bazel cquery requests.
@@ -237,3 +241,28 @@ func (context *bazelContext) InvokeBazel() error {
	context.requests = map[cqueryKey]bool{}
	return nil
}

// Singleton used for registering BUILD file ninja dependencies (needed
// for correctness of builds which use Bazel.
func BazelSingleton() Singleton {
	return &bazelSingleton{}
}

type bazelSingleton struct{}

func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) {
	if ctx.Config().BazelContext.BazelEnabled() {
		bazelBuildList := absolutePath(filepath.Join(
			filepath.Dir(bootstrap.ModuleListFile), "bazel.list"))
		ctx.AddNinjaFileDeps(bazelBuildList)

		data, err := ioutil.ReadFile(bazelBuildList)
		if err != nil {
			ctx.Errorf(err.Error())
		}
		files := strings.Split(strings.TrimSpace(string(data)), "\n")
		for _, file := range files {
			ctx.AddNinjaFileDeps(file)
		}
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -104,6 +104,8 @@ func (ctx *Context) Register() {

	registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)

	ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(BazelSingleton))

	// Register phony just before makevars so it can write out its phony rules as Make rules
	ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory))

+20 −7
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ type CacheParams struct {

	// IncludeFiles are file names to include as matches
	IncludeFiles []string

	// IncludeSuffixes are filename suffixes to include as matches.
	IncludeSuffixes []string
}

// a cacheConfig stores the inputs that determine what should be included in the cache
@@ -1310,6 +1313,20 @@ func (f *Finder) statDirSync(path string) statResponse {
	return stats
}

func (f *Finder) shouldIncludeFile(fileName string) bool {
	for _, includedName := range f.cacheMetadata.Config.IncludeFiles {
		if fileName == includedName {
			return true
		}
	}
	for _, includeSuffix := range f.cacheMetadata.Config.IncludeSuffixes {
		if strings.HasSuffix(fileName, includeSuffix) {
			return true
		}
	}
	return false
}

// pruneCacheCandidates removes the items that we don't want to include in our persistent cache
func (f *Finder) pruneCacheCandidates(items *DirEntries) {

@@ -1326,13 +1343,9 @@ func (f *Finder) pruneCacheCandidates(items *DirEntries) {
	// remove any files that aren't the ones we want to include
	writeIndex := 0
	for _, fileName := range items.FileNames {
		// include only these files
		for _, includedName := range f.cacheMetadata.Config.IncludeFiles {
			if fileName == includedName {
		if f.shouldIncludeFile(fileName) {
			items.FileNames[writeIndex] = fileName
			writeIndex++
				break
			}
		}
	}
	// resize
+56 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import (
	"os"
	"path/filepath"
	"sort"
	"strings"
	"testing"

	"android/soong/finder/fs"
@@ -92,6 +93,7 @@ func runSimpleTest(t *testing.T, existentPaths []string, expectedMatches []strin
			nil,
			nil,
			[]string{"findme.txt", "skipme.txt"},
			nil,
		},
	)
	defer finder.Shutdown()
@@ -104,6 +106,46 @@ func runSimpleTest(t *testing.T, existentPaths []string, expectedMatches []strin
	fs.AssertSameResponse(t, foundPaths, absoluteMatches)
}

// runTestWithSuffixes creates a few files, searches for findme.txt or any file
// with suffix `.findme_ext` and checks for the expected matches
func runTestWithSuffixes(t *testing.T, existentPaths []string, expectedMatches []string) {
	filesystem := newFs()
	root := "/tmp"
	filesystem.MkDirs(root)
	for _, path := range existentPaths {
		fs.Create(t, filepath.Join(root, path), filesystem)
	}

	finder := newFinder(t,
		filesystem,
		CacheParams{
			"/cwd",
			[]string{root},
			nil,
			nil,
			[]string{"findme.txt", "skipme.txt"},
			[]string{".findme_ext"},
		},
	)
	defer finder.Shutdown()

	foundPaths := finder.FindMatching(root,
		func(entries DirEntries) (dirs []string, files []string) {
			matches := []string{}
			for _, foundName := range entries.FileNames {
				if foundName == "findme.txt" || strings.HasSuffix(foundName, ".findme_ext") {
					matches = append(matches, foundName)
				}
			}
			return entries.DirNames, matches
		})
	absoluteMatches := []string{}
	for i := range expectedMatches {
		absoluteMatches = append(absoluteMatches, filepath.Join(root, expectedMatches[i]))
	}
	fs.AssertSameResponse(t, foundPaths, absoluteMatches)
}

// testAgainstSeveralThreadcounts runs the given test for each threadcount that we care to test
func testAgainstSeveralThreadcounts(t *testing.T, tester func(t *testing.T, numThreads int)) {
	// test singlethreaded, multithreaded, and also using the same number of threads as
@@ -135,6 +177,13 @@ func TestIncludeFiles(t *testing.T) {
	)
}

func TestIncludeFilesAndSuffixes(t *testing.T) {
	runTestWithSuffixes(t,
		[]string{"findme.txt", "skipme.txt", "alsome.findme_ext"},
		[]string{"findme.txt", "alsome.findme_ext"},
	)
}

func TestNestedDirectories(t *testing.T) {
	runSimpleTest(t,
		[]string{"findme.txt", "skipme.txt", "subdir/findme.txt", "subdir/skipme.txt"},
@@ -142,6 +191,13 @@ func TestNestedDirectories(t *testing.T) {
	)
}

func TestNestedDirectoriesWithSuffixes(t *testing.T) {
	runTestWithSuffixes(t,
		[]string{"findme.txt", "skipme.txt", "subdir/findme.txt", "subdir/skipme.txt", "subdir/alsome.findme_ext"},
		[]string{"findme.txt", "subdir/findme.txt", "subdir/alsome.findme_ext"},
	)
}

func TestEmptyDirectory(t *testing.T) {
	runSimpleTest(t,
		[]string{},
+19 −0
Original line number Diff line number Diff line
@@ -63,10 +63,13 @@ func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) {
			"AndroidProducts.mk",
			"Android.bp",
			"Blueprints",
			"BUILD.bazel",
			"CleanSpec.mk",
			"OWNERS",
			"TEST_MAPPING",
			"WORKSPACE",
		},
		IncludeSuffixes: []string{".bzl"},
	}
	dumpDir := config.FileListDir()
	f, err = finder.New(cacheParams, filesystem, logger.New(ioutil.Discard),
@@ -77,6 +80,16 @@ func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) {
	return f
}

func findBazelFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
	matches := []string{}
	for _, foundName := range entries.FileNames {
		if foundName == "BUILD.bazel" || foundName == "WORKSPACE" || strings.HasSuffix(foundName, ".bzl") {
			matches = append(matches, foundName)
		}
	}
	return entries.DirNames, matches
}

// FindSources searches for source files known to <f> and writes them to the filesystem for
// use later.
func FindSources(ctx Context, config Config, f *finder.Finder) {
@@ -99,6 +112,12 @@ func FindSources(ctx Context, config Config, f *finder.Finder) {
		ctx.Fatalf("Could not export product list: %v", err)
	}

	bazelFiles := f.FindMatching(".", findBazelFiles)
	err = dumpListToFile(ctx, config, bazelFiles, filepath.Join(dumpDir, "bazel.list"))
	if err != nil {
		ctx.Fatalf("Could not export bazel BUILD list: %v", err)
	}

	cleanSpecs := f.FindFirstNamedAt(".", "CleanSpec.mk")
	err = dumpListToFile(ctx, config, cleanSpecs, filepath.Join(dumpDir, "CleanSpec.mk.list"))
	if err != nil {