Procházet zdrojové kódy

Ignore bazel-generated paths in dangling rule test

Bazel is expected to generate some files and symlinks that will not be
created by aquery, we explicitly ignore files that are in bazel output
paths but are not in a generated file directory.

Test: $ m --bazel-mode-staging checkbuild and verify it gets past
   dangling rule test
Fixes: 258396112
Change-Id: I6dc45ea2613c9e1488ad3eda2313033c717217ff
Liz Kammer před 1 rokem
rodič
revize
2af5ea85b0
3 změnil soubory, kde provedl 39 přidání a 1 odebrání
  1. 4 0
      ui/build/config.go
  2. 1 1
      ui/build/soong.go
  3. 34 0
      ui/build/test_build.go

+ 4 - 0
ui/build/config.go

@@ -896,6 +896,10 @@ func (c *configImpl) BazelOutDir() string {
 	return filepath.Join(c.OutDir(), "bazel")
 }
 
+func (c *configImpl) bazelOutputBase() string {
+	return filepath.Join(c.BazelOutDir(), "output")
+}
+
 func (c *configImpl) SoongOutDir() string {
 	return filepath.Join(c.OutDir(), "soong")
 }

+ 1 - 1
ui/build/soong.go

@@ -418,7 +418,7 @@ func runSoong(ctx Context, config Config) {
 	// Bazel's HOME var is set to an output subdirectory which doesn't exist. This
 	// prevents Bazel from file I/O in the actual user HOME directory.
 	soongBuildEnv.Set("BAZEL_HOME", absPath(ctx, filepath.Join(config.BazelOutDir(), "bazelhome")))
-	soongBuildEnv.Set("BAZEL_OUTPUT_BASE", filepath.Join(config.BazelOutDir(), "output"))
+	soongBuildEnv.Set("BAZEL_OUTPUT_BASE", config.bazelOutputBase())
 	soongBuildEnv.Set("BAZEL_WORKSPACE", absPath(ctx, "."))
 	soongBuildEnv.Set("BAZEL_METRICS_DIR", config.BazelMetricsDir())
 	soongBuildEnv.Set("LOG_DIR", config.LogsDir())

+ 34 - 0
ui/build/test_build.go

@@ -18,14 +18,44 @@ import (
 	"bufio"
 	"fmt"
 	"path/filepath"
+	"regexp"
 	"runtime"
 	"sort"
 	"strings"
+	"sync"
 
 	"android/soong/ui/metrics"
 	"android/soong/ui/status"
 )
 
+var (
+	// bazel output paths are in __main__/bazel-out/<config-specific-path>/bin
+	bazelOutputPathRegexOnce sync.Once
+	bazelOutputPathRegexp    *regexp.Regexp
+)
+
+func bazelOutputPathPattern(config Config) *regexp.Regexp {
+	bazelOutputPathRegexOnce.Do(func() {
+		// Bazel output files are in <Bazel output base>/execroot/__main__/bazel-out/<config>/bin
+		bazelOutRoot := filepath.Join(regexp.QuoteMeta(config.bazelOutputBase()), "execroot", "__main__", "bazel-out")
+		bazelOutputPathRegexp = regexp.MustCompile(bazelOutRoot + "/[^/]+/bin")
+	})
+	return bazelOutputPathRegexp
+}
+
+func ignoreBazelPath(config Config, path string) bool {
+	bazelRoot := filepath.Join(config.bazelOutputBase(), "execroot")
+	// Don't check bazel output regexp unless it is Bazel path
+	if strings.HasPrefix(path, bazelRoot) {
+		bazelOutputRegexp := bazelOutputPathPattern(config)
+		// if the file is a bazel path that is _not_ a Bazel generated file output, we rely on Bazel to
+		// ensure the paths to exist. If it _is_ a Bazel output path, we expect that it should be built
+		// by Ninja.
+		return !bazelOutputRegexp.MatchString(path)
+	}
+	return false
+}
+
 // Checks for files in the out directory that have a rule that depends on them but no rule to
 // create them. This catches a common set of build failures where a rule to generate a file is
 // deleted (either by deleting a module in an Android.mk file, or by modifying the build system
@@ -97,6 +127,10 @@ func testForDanglingRules(ctx Context, config Config) {
 			// full build rules in the primary build.ninja file.
 			continue
 		}
+
+		if ignoreBazelPath(config, line) {
+			continue
+		}
 		danglingRules[line] = true
 	}