summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorScott Lobdell <slobdell@google.com>2021-03-11 19:08:45 +0000
committerScott Lobdell <slobdell@google.com>2021-03-16 00:44:22 +0000
commit85534c36f81cf1557ddaa01605199bfc3a9fd76c (patch)
treef9b65ea011ac58731bc866a621f526ea8fa7e39f /ui
parent5989878a55d2d34a1a8e5e16bb37349c4949758b (diff)
parentedc1fc38c73698499b37c40435b25ef2a5ade887 (diff)
Merge SP1A.210311.001
Change-Id: I28e9aad9ed4dd91092fd24efb136f0aac7bdb68e
Diffstat (limited to 'ui')
-rw-r--r--ui/build/cleanbuild.go2
-rw-r--r--ui/build/environment.go13
-rw-r--r--ui/build/paths/logs_test.go3
-rw-r--r--ui/build/soong.go97
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()
}