diff options
author | Scott Lobdell <slobdell@google.com> | 2021-03-11 19:08:45 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2021-03-16 00:44:22 +0000 |
commit | 85534c36f81cf1557ddaa01605199bfc3a9fd76c (patch) | |
tree | f9b65ea011ac58731bc866a621f526ea8fa7e39f /ui | |
parent | 5989878a55d2d34a1a8e5e16bb37349c4949758b (diff) | |
parent | edc1fc38c73698499b37c40435b25ef2a5ade887 (diff) |
Merge SP1A.210311.001
Change-Id: I28e9aad9ed4dd91092fd24efb136f0aac7bdb68e
Diffstat (limited to 'ui')
-rw-r--r-- | ui/build/cleanbuild.go | 2 | ||||
-rw-r--r-- | ui/build/environment.go | 13 | ||||
-rw-r--r-- | ui/build/paths/logs_test.go | 3 | ||||
-rw-r--r-- | ui/build/soong.go | 97 |
4 files changed, 82 insertions, 33 deletions
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go index b1f8551ed..6ba497c3f 100644 --- a/ui/build/cleanbuild.go +++ b/ui/build/cleanbuild.go @@ -124,7 +124,7 @@ func installClean(ctx Context, config Config) { productOut("obj/PACKAGING"), productOut("ramdisk"), productOut("debug_ramdisk"), - productOut("vendor-ramdisk"), + productOut("vendor_ramdisk"), productOut("vendor_debug_ramdisk"), productOut("test_harness_ramdisk"), productOut("recovery"), diff --git a/ui/build/environment.go b/ui/build/environment.go index 6d8a28fdf..50d059f8d 100644 --- a/ui/build/environment.go +++ b/ui/build/environment.go @@ -33,6 +33,19 @@ func OsEnvironment() *Environment { return &env } +// Returns a copy of the environment as a map[string]string. +func (e *Environment) AsMap() map[string]string { + result := make(map[string]string) + + for _, envVar := range *e { + if k, v, ok := decodeKeyValue(envVar); ok { + result[k] = v + } + } + + return result +} + // Get returns the value associated with the key, and whether it exists. // It's equivalent to the os.LookupEnv function, but with this copy of the // Environment. diff --git a/ui/build/paths/logs_test.go b/ui/build/paths/logs_test.go index 3b1005fb5..067f3f3fe 100644 --- a/ui/build/paths/logs_test.go +++ b/ui/build/paths/logs_test.go @@ -26,6 +26,9 @@ import ( ) func TestSendLog(t *testing.T) { + if testing.Short() { + t.Skip("skipping in short mode, sometimes hangs") + } t.Run("Short name", func(t *testing.T) { d, err := ioutil.TempDir("", "s") if err != nil { diff --git a/ui/build/soong.go b/ui/build/soong.go index 899ab5da5..5f4a203f7 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -19,7 +19,8 @@ import ( "os" "path/filepath" "strconv" - "strings" + + "android/soong/shared" soong_metrics_proto "android/soong/ui/metrics/metrics_proto" @@ -30,6 +31,15 @@ import ( "android/soong/ui/status" ) +func writeEnvironmentFile(ctx Context, envFile string, envDeps map[string]string) error { + data, err := shared.EnvFileContents(envDeps) + if err != nil { + return err + } + + return ioutil.WriteFile(envFile, data, 0644) +} + // This uses Android.bp files and various tools to generate <builddir>/build.ninja. // // However, the execution of <builddir>/build.ninja happens later in build/soong/ui/build/build.go#Build() @@ -47,6 +57,12 @@ func runSoong(ctx Context, config Config) { ctx.BeginTrace(metrics.RunSoong, "soong") defer ctx.EndTrace() + // We have two environment files: .available is the one with every variable, + // .used with the ones that were actually used. The latter is used to + // determine whether Soong needs to be re-run since why re-run it if only + // unused variables were changed? + envFile := filepath.Join(config.SoongOutDir(), "soong.environment.available") + // Use an anonymous inline function for tracing purposes (this pattern is used several times below). func() { ctx.BeginTrace(metrics.RunSoong, "blueprint bootstrap") @@ -61,6 +77,7 @@ func runSoong(ctx Context, config Config) { } cmd := Command(ctx, config, "blueprint bootstrap", "build/blueprint/bootstrap.bash", args...) + cmd.Environment.Set("BLUEPRINTDIR", "./build/blueprint") cmd.Environment.Set("BOOTSTRAP", "./build/blueprint/bootstrap.bash") cmd.Environment.Set("BUILDDIR", config.SoongOutDir()) @@ -74,34 +91,36 @@ func runSoong(ctx Context, config Config) { cmd.RunAndPrintOrFatal() }() + soongBuildEnv := config.Environment().Copy() + soongBuildEnv.Set("TOP", os.Getenv("TOP")) + // These two dependencies are read from bootstrap.go, but also need to be here + // so that soong_build can declare a dependency on them + soongBuildEnv.Set("SOONG_DELVE", os.Getenv("SOONG_DELVE")) + soongBuildEnv.Set("SOONG_DELVE_PATH", os.Getenv("SOONG_DELVE_PATH")) + soongBuildEnv.Set("SOONG_OUTDIR", config.SoongOutDir()) + // For Bazel mixed builds. + soongBuildEnv.Set("BAZEL_PATH", "./tools/bazel") + soongBuildEnv.Set("BAZEL_HOME", filepath.Join(config.BazelOutDir(), "bazelhome")) + soongBuildEnv.Set("BAZEL_OUTPUT_BASE", filepath.Join(config.BazelOutDir(), "output")) + soongBuildEnv.Set("BAZEL_WORKSPACE", absPath(ctx, ".")) + soongBuildEnv.Set("BAZEL_METRICS_DIR", config.BazelMetricsDir()) + + err := writeEnvironmentFile(ctx, envFile, soongBuildEnv.AsMap()) + if err != nil { + ctx.Fatalf("failed to write environment file %s: %s", envFile, err) + } + func() { ctx.BeginTrace(metrics.RunSoong, "environment check") defer ctx.EndTrace() - envFile := filepath.Join(config.SoongOutDir(), ".soong.environment") - envTool := filepath.Join(config.SoongOutDir(), ".bootstrap/bin/soong_env") - if _, err := os.Stat(envFile); err == nil { - if _, err := os.Stat(envTool); err == nil { - cmd := Command(ctx, config, "soong_env", envTool, envFile) - cmd.Sandbox = soongSandbox - - var buf strings.Builder - cmd.Stdout = &buf - cmd.Stderr = &buf - if err := cmd.Run(); err != nil { - ctx.Verboseln("soong_env failed, forcing manifest regeneration") - os.Remove(envFile) - } - - if buf.Len() > 0 { - ctx.Verboseln(buf.String()) - } - } else { - ctx.Verboseln("Missing soong_env tool, forcing manifest regeneration") - os.Remove(envFile) - } - } else if !os.IsNotExist(err) { - ctx.Fatalf("Failed to stat %f: %v", envFile, err) + envFile := filepath.Join(config.SoongOutDir(), "soong.environment.used") + getenv := func(k string) string { + v, _ := config.Environment().Get(k) + return v + } + if stale, _ := shared.StaleEnvFile(envFile, getenv); stale { + os.Remove(envFile) } }() @@ -151,14 +170,28 @@ func runSoong(ctx Context, config Config) { "--frontend_file", fifo, "-f", filepath.Join(config.SoongOutDir(), file)) - // For Bazel mixed builds. - cmd.Environment.Set("BAZEL_PATH", "./tools/bazel") - cmd.Environment.Set("BAZEL_HOME", filepath.Join(config.BazelOutDir(), "bazelhome")) - cmd.Environment.Set("BAZEL_OUTPUT_BASE", filepath.Join(config.BazelOutDir(), "output")) - cmd.Environment.Set("BAZEL_WORKSPACE", absPath(ctx, ".")) - cmd.Environment.Set("BAZEL_METRICS_DIR", config.BazelMetricsDir()) + var ninjaEnv Environment + + // This is currently how the command line to invoke soong_build finds the + // root of the source tree and the output root + ninjaEnv.Set("TOP", os.Getenv("TOP")) + ninjaEnv.Set("SOONG_OUTDIR", config.SoongOutDir()) + + // Needed for NonHermeticHostSystemTool() and that, only in tests. We should + // probably find a better way of running tests other than making $PATH + // available also to production builds. Note that this is not get same as + // os.Getenv("PATH"): config.Environment() contains the $PATH that redirects + // every binary through the path interposer. + configPath, _ := config.Environment().Get("PATH") + ninjaEnv.Set("PATH", configPath) + + // For debugging + if os.Getenv("SOONG_DELVE") != "" { + // SOONG_DELVE is already in cmd.Environment + ninjaEnv.Set("SOONG_DELVE_PATH", shared.ResolveDelveBinary()) + } - cmd.Environment.Set("SOONG_SANDBOX_SOONG_BUILD", "true") + cmd.Environment = &ninjaEnv cmd.Sandbox = soongSandbox cmd.RunAndStreamOrFatal() } |