Merge changes Ib3f4ee14,Iac22c9fd,Ibd78758c,I40d8696c,I2a2b10e4, ...

* changes:
  Fix InstallBypassMake symlink dependencies
  Add tests for ctx.InstallFile
  Fix OutDir vs SoongOutDir in tests
  Fix go vet error
  Add missing os.MkdirAll to WriteFileToOutputDir
  Use pathtools.WriteFileIfChanged in translateAndroidMk
diff --git a/android/Android.bp b/android/Android.bp
index 6450a06..cfa2be3 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -19,6 +19,9 @@
         "soong-ui-metrics_proto",
         "golang-protobuf-proto",
         "golang-protobuf-encoding-prototext",
+
+        // Only used for tests.
+        "androidmk-parser",
     ],
     srcs: [
         "androidmk.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index b6b04a6..9025a74 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -25,7 +25,6 @@
 	"bytes"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"reflect"
@@ -35,6 +34,7 @@
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/bootstrap"
+	"github.com/google/blueprint/pathtools"
 )
 
 func init() {
@@ -690,7 +690,7 @@
 	})
 }
 
-func translateAndroidMk(ctx SingletonContext, mkFile string, mods []blueprint.Module) error {
+func translateAndroidMk(ctx SingletonContext, absMkFile string, mods []blueprint.Module) error {
 	buf := &bytes.Buffer{}
 
 	fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))")
@@ -699,7 +699,7 @@
 	for _, mod := range mods {
 		err := translateAndroidMkModule(ctx, buf, mod)
 		if err != nil {
-			os.Remove(mkFile)
+			os.Remove(absMkFile)
 			return err
 		}
 
@@ -719,27 +719,7 @@
 		fmt.Fprintf(buf, "STATS.SOONG_MODULE_TYPE.%s := %d\n", mod_type, typeStats[mod_type])
 	}
 
-	// Don't write to the file if it hasn't changed
-	if _, err := os.Stat(absolutePath(mkFile)); !os.IsNotExist(err) {
-		if data, err := ioutil.ReadFile(absolutePath(mkFile)); err == nil {
-			matches := buf.Len() == len(data)
-
-			if matches {
-				for i, value := range buf.Bytes() {
-					if value != data[i] {
-						matches = false
-						break
-					}
-				}
-			}
-
-			if matches {
-				return nil
-			}
-		}
-	}
-
-	return ioutil.WriteFile(absolutePath(mkFile), buf.Bytes(), 0666)
+	return pathtools.WriteFileIfChanged(absMkFile, buf.Bytes(), 0666)
 }
 
 func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
diff --git a/android/config.go b/android/config.go
index b9a47f2..6f05565 100644
--- a/android/config.go
+++ b/android/config.go
@@ -334,10 +334,8 @@
 			ShippingApiLevel:                  stringPtr("30"),
 		},
 
-		outDir: buildDir,
-		// soongOutDir is inconsistent with production (it should be buildDir + "/soong")
-		// but a lot of tests assume this :(
-		soongOutDir:  buildDir,
+		outDir:       buildDir,
+		soongOutDir:  filepath.Join(buildDir, "soong"),
 		captureBuild: true,
 		env:          envCopy,
 
diff --git a/android/makevars.go b/android/makevars.go
index 20db65a..8825d1a 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -142,15 +142,19 @@
 
 var singletonMakeVarsProvidersKey = NewOnceKey("singletonMakeVarsProvidersKey")
 
+func getSingletonMakevarsProviders(config Config) *[]makeVarsProvider {
+	return config.Once(singletonMakeVarsProvidersKey, func() interface{} {
+		return &[]makeVarsProvider{}
+	}).(*[]makeVarsProvider)
+}
+
 // registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to
 // the list of MakeVarsProviders to run.
 func registerSingletonMakeVarsProvider(config Config, singleton SingletonMakeVarsProvider) {
 	// Singletons are registered on the Context and may be different between different Contexts,
 	// for example when running multiple tests.  Store the SingletonMakeVarsProviders in the
 	// Config so they are attached to the Context.
-	singletonMakeVarsProviders := config.Once(singletonMakeVarsProvidersKey, func() interface{} {
-		return &[]makeVarsProvider{}
-	}).(*[]makeVarsProvider)
+	singletonMakeVarsProviders := getSingletonMakevarsProviders(config)
 
 	*singletonMakeVarsProviders = append(*singletonMakeVarsProviders,
 		makeVarsProvider{pctx, singletonMakeVarsProviderAdapter(singleton)})
@@ -175,7 +179,9 @@
 	return &makeVarsSingleton{}
 }
 
-type makeVarsSingleton struct{}
+type makeVarsSingleton struct {
+	installsForTesting []byte
+}
 
 type makeVarsProvider struct {
 	pctx PackageContext
@@ -238,7 +244,7 @@
 	var katiSymlinks []katiInstall
 
 	providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
-	providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...)
+	providers = append(providers, *getSingletonMakevarsProviders(ctx.Config())...)
 
 	for _, provider := range providers {
 		mctx := &makeVarsContext{
@@ -313,6 +319,8 @@
 	if err := pathtools.WriteFileIfChanged(installsFile, installsBytes, 0666); err != nil {
 		ctx.Errorf(err.Error())
 	}
+
+	s.installsForTesting = installsBytes
 }
 
 func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
@@ -465,15 +473,19 @@
 
 	for _, symlink := range symlinks {
 		fmt.Fprintf(buf, "%s:", symlink.to.String())
+		if symlink.from != nil {
+			// The symlink doesn't need updating when the target is modified, but we sometimes
+			// have a dependency on a symlink to a binary instead of to the binary directly, and
+			// the mtime of the symlink must be updated when the binary is modified, so use a
+			// normal dependency here instead of an order-only dependency.
+			fmt.Fprintf(buf, " %s", symlink.from.String())
+		}
 		for _, dep := range symlink.implicitDeps {
 			fmt.Fprintf(buf, " %s", dep.String())
 		}
-		if symlink.from != nil || len(symlink.orderOnlyDeps) > 0 {
+		if len(symlink.orderOnlyDeps) > 0 {
 			fmt.Fprintf(buf, " |")
 		}
-		if symlink.from != nil {
-			fmt.Fprintf(buf, " %s", symlink.from.String())
-		}
 		for _, dep := range symlink.orderOnlyDeps {
 			fmt.Fprintf(buf, " %s", dep.String())
 		}
diff --git a/android/module.go b/android/module.go
index 3447f2b..c778078 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2953,6 +2953,10 @@
 				to:   fullInstallPath,
 			})
 		} else {
+			// The symlink doesn't need updating when the target is modified, but we sometimes
+			// have a dependency on a symlink to a binary instead of to the binary directly, and
+			// the mtime of the symlink must be updated when the binary is modified, so use a
+			// normal dependency here instead of an order-only dependency.
 			m.Build(pctx, BuildParams{
 				Rule:        Symlink,
 				Description: "install symlink " + fullInstallPath.Base(),
diff --git a/android/module_test.go b/android/module_test.go
index 9e2b0ca..8607a8d 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -15,7 +15,12 @@
 package android
 
 import (
+	"bytes"
+	"path/filepath"
+	"runtime"
 	"testing"
+
+	mkparser "android/soong/androidmk/parser"
 )
 
 func TestSrcIsModule(t *testing.T) {
@@ -199,17 +204,28 @@
 	}
 }
 
+func (m *depsModule) InstallBypassMake() bool {
+	return true
+}
+
 func (m *depsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+	outputFile := PathForModuleOut(ctx, ctx.ModuleName())
+	ctx.Build(pctx, BuildParams{
+		Rule:   Touch,
+		Output: outputFile,
+	})
+	installFile := ctx.InstallFile(PathForModuleInstall(ctx), ctx.ModuleName(), outputFile)
+	ctx.InstallSymlink(PathForModuleInstall(ctx, "symlinks"), ctx.ModuleName(), installFile)
 }
 
 func (m *depsModule) DepsMutator(ctx BottomUpMutatorContext) {
-	ctx.AddDependency(ctx.Module(), nil, m.props.Deps...)
+	ctx.AddDependency(ctx.Module(), installDepTag{}, m.props.Deps...)
 }
 
 func depsModuleFactory() Module {
 	m := &depsModule{}
 	m.AddProperties(&m.props)
-	InitAndroidModule(m)
+	InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
 	return m
 }
 
@@ -320,3 +336,286 @@
 		ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(expectedErrs)).
 		RunTestWithBp(t, bp)
 }
+
+func TestInstall(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skip("requires linux")
+	}
+	bp := `
+		deps {
+			name: "foo",
+			deps: ["bar"],
+		}
+
+		deps {
+			name: "bar",
+			deps: ["baz", "qux"],
+		}
+
+		deps {
+			name: "baz",
+			deps: ["qux"],
+		}
+
+		deps {
+			name: "qux",
+		}
+	`
+
+	result := GroupFixturePreparers(
+		prepareForModuleTests,
+		PrepareForTestWithArchMutator,
+	).RunTestWithBp(t, bp)
+
+	module := func(name string, host bool) TestingModule {
+		variant := "android_common"
+		if host {
+			variant = result.Config.BuildOSCommonTarget.String()
+		}
+		return result.ModuleForTests(name, variant)
+	}
+
+	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
+
+	installRule := func(name string) TestingBuildParams {
+		return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system", name))
+	}
+
+	symlinkRule := func(name string) TestingBuildParams {
+		return module(name, false).Output(filepath.Join("out/soong/target/product/test_device/system/symlinks", name))
+	}
+
+	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
+
+	hostInstallRule := func(name string) TestingBuildParams {
+		return module(name, true).Output(filepath.Join("out/soong/host/linux-x86", name))
+	}
+
+	hostSymlinkRule := func(name string) TestingBuildParams {
+		return module(name, true).Output(filepath.Join("out/soong/host/linux-x86/symlinks", name))
+	}
+
+	assertInputs := func(params TestingBuildParams, inputs ...Path) {
+		t.Helper()
+		AssertArrayString(t, "expected inputs", Paths(inputs).Strings(),
+			append(PathsIfNonNil(params.Input), params.Inputs...).Strings())
+	}
+
+	assertImplicits := func(params TestingBuildParams, implicits ...Path) {
+		t.Helper()
+		AssertArrayString(t, "expected implicit dependencies", Paths(implicits).Strings(),
+			append(PathsIfNonNil(params.Implicit), params.Implicits...).Strings())
+	}
+
+	assertOrderOnlys := func(params TestingBuildParams, orderonlys ...Path) {
+		t.Helper()
+		AssertArrayString(t, "expected orderonly dependencies", Paths(orderonlys).Strings(),
+			params.OrderOnly.Strings())
+	}
+
+	// Check host install rule dependencies
+	assertInputs(hostInstallRule("foo"), hostOutputRule("foo").Output)
+	assertImplicits(hostInstallRule("foo"),
+		hostInstallRule("bar").Output,
+		hostSymlinkRule("bar").Output,
+		hostInstallRule("baz").Output,
+		hostSymlinkRule("baz").Output,
+		hostInstallRule("qux").Output,
+		hostSymlinkRule("qux").Output,
+	)
+	assertOrderOnlys(hostInstallRule("foo"))
+
+	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
+	// order-only dependency, so that the tool gets updated when the symlink is depended on.
+	assertInputs(hostSymlinkRule("foo"), hostInstallRule("foo").Output)
+	assertImplicits(hostSymlinkRule("foo"))
+	assertOrderOnlys(hostSymlinkRule("foo"))
+
+	// Check device install rule dependencies
+	assertInputs(installRule("foo"), outputRule("foo").Output)
+	assertImplicits(installRule("foo"))
+	assertOrderOnlys(installRule("foo"),
+		installRule("bar").Output,
+		symlinkRule("bar").Output,
+		installRule("baz").Output,
+		symlinkRule("baz").Output,
+		installRule("qux").Output,
+		symlinkRule("qux").Output,
+	)
+
+	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
+	// but the current implementation uses a normal dependency.
+	assertInputs(symlinkRule("foo"), installRule("foo").Output)
+	assertImplicits(symlinkRule("foo"))
+	assertOrderOnlys(symlinkRule("foo"))
+}
+
+func TestInstallBypassMake(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skip("requires linux")
+	}
+	bp := `
+		deps {
+			name: "foo",
+			deps: ["bar"],
+		}
+
+		deps {
+			name: "bar",
+			deps: ["baz", "qux"],
+		}
+
+		deps {
+			name: "baz",
+			deps: ["qux"],
+		}
+
+		deps {
+			name: "qux",
+		}
+	`
+
+	result := GroupFixturePreparers(
+		prepareForModuleTests,
+		PrepareForTestWithArchMutator,
+		FixtureModifyConfig(SetKatiEnabledForTests),
+		FixtureRegisterWithContext(func(ctx RegistrationContext) {
+			ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
+		}),
+	).RunTestWithBp(t, bp)
+
+	installs := result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
+	buf := bytes.NewBuffer(append([]byte(nil), installs...))
+	parser := mkparser.NewParser("makevars", buf)
+
+	nodes, errs := parser.Parse()
+	if len(errs) > 0 {
+		t.Fatalf("error parsing install rules: %s", errs[0])
+	}
+
+	rules := parseMkRules(t, result.Config, nodes)
+
+	module := func(name string, host bool) TestingModule {
+		variant := "android_common"
+		if host {
+			variant = result.Config.BuildOSCommonTarget.String()
+		}
+		return result.ModuleForTests(name, variant)
+	}
+
+	outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
+
+	ruleForOutput := func(output string) installMakeRule {
+		for _, rule := range rules {
+			if rule.target == output {
+				return rule
+			}
+		}
+		t.Fatalf("no make install rule for %s", output)
+		return installMakeRule{}
+	}
+
+	installRule := func(name string) installMakeRule {
+		return ruleForOutput(filepath.Join("out/target/product/test_device/system", name))
+	}
+
+	symlinkRule := func(name string) installMakeRule {
+		return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
+	}
+
+	hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
+
+	hostInstallRule := func(name string) installMakeRule {
+		return ruleForOutput(filepath.Join("out/host/linux-x86", name))
+	}
+
+	hostSymlinkRule := func(name string) installMakeRule {
+		return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
+	}
+
+	assertDeps := func(rule installMakeRule, deps ...string) {
+		t.Helper()
+		AssertArrayString(t, "expected inputs", deps, rule.deps)
+	}
+
+	assertOrderOnlys := func(rule installMakeRule, orderonlys ...string) {
+		t.Helper()
+		AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.orderOnlyDeps)
+	}
+
+	// Check host install rule dependencies
+	assertDeps(hostInstallRule("foo"),
+		hostOutputRule("foo").Output.String(),
+		hostInstallRule("bar").target,
+		hostSymlinkRule("bar").target,
+		hostInstallRule("baz").target,
+		hostSymlinkRule("baz").target,
+		hostInstallRule("qux").target,
+		hostSymlinkRule("qux").target,
+	)
+	assertOrderOnlys(hostInstallRule("foo"))
+
+	// Check host symlink rule dependencies.  Host symlinks must use a normal dependency, not an
+	// order-only dependency, so that the tool gets updated when the symlink is depended on.
+	assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").target)
+	assertOrderOnlys(hostSymlinkRule("foo"))
+
+	// Check device install rule dependencies
+	assertDeps(installRule("foo"), outputRule("foo").Output.String())
+	assertOrderOnlys(installRule("foo"),
+		installRule("bar").target,
+		symlinkRule("bar").target,
+		installRule("baz").target,
+		symlinkRule("baz").target,
+		installRule("qux").target,
+		symlinkRule("qux").target,
+	)
+
+	// Check device symlink rule dependencies.  Device symlinks could use an order-only dependency,
+	// but the current implementation uses a normal dependency.
+	assertDeps(symlinkRule("foo"), installRule("foo").target)
+	assertOrderOnlys(symlinkRule("foo"))
+}
+
+type installMakeRule struct {
+	target        string
+	deps          []string
+	orderOnlyDeps []string
+}
+
+func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installMakeRule {
+	var rules []installMakeRule
+	for _, node := range nodes {
+		if mkParserRule, ok := node.(*mkparser.Rule); ok {
+			var rule installMakeRule
+
+			if targets := mkParserRule.Target.Words(); len(targets) == 0 {
+				t.Fatalf("no targets for rule %s", mkParserRule.Dump())
+			} else if len(targets) > 1 {
+				t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump())
+			} else if !targets[0].Const() {
+				t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump())
+			} else {
+				rule.target = normalizeStringRelativeToTop(config, targets[0].Value(nil))
+			}
+
+			prereqList := &rule.deps
+			for _, prereq := range mkParserRule.Prerequisites.Words() {
+				if !prereq.Const() {
+					t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump())
+				}
+
+				if prereq.Value(nil) == "|" {
+					prereqList = &rule.orderOnlyDeps
+					continue
+				}
+
+				*prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil)))
+			}
+
+			rules = append(rules, rule)
+		}
+	}
+
+	return rules
+}
diff --git a/android/paths.go b/android/paths.go
index 5285ee8..e68106c 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -2064,7 +2064,12 @@
 // Writes a file to the output directory.  Attempting to write directly to the output directory
 // will fail due to the sandbox of the soong_build process.
 func WriteFileToOutputDir(path WritablePath, data []byte, perm os.FileMode) error {
-	return ioutil.WriteFile(absolutePath(path.String()), data, perm)
+	absPath := absolutePath(path.String())
+	err := os.MkdirAll(filepath.Dir(absPath), 0777)
+	if err != nil {
+		return err
+	}
+	return ioutil.WriteFile(absPath, data, perm)
 }
 
 func RemoveAllOutputDir(path WritablePath) error {
diff --git a/android/paths_test.go b/android/paths_test.go
index 3f4625d..3cad852 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -993,7 +993,7 @@
 		{
 			name:     "in out dir",
 			buildDir: "out",
-			src:      "out/a/b/c",
+			src:      "out/soong/a/b/c",
 			err:      "is in output",
 		},
 	}
@@ -1525,7 +1525,7 @@
 	fmt.Println(p.Rel(), p2.Rel())
 
 	// Output:
-	// out/system/framework/boot.art out/system/framework/boot.oat
+	// out/soong/system/framework/boot.art out/soong/system/framework/boot.oat
 	// boot.art boot.oat
 }
 
@@ -1539,7 +1539,7 @@
 	fmt.Println(p.Rel(), p2.Rel())
 
 	// Output:
-	// out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
+	// out/soong/system/framework/boot.art out/soong/system/framework/oat/arm/boot.vdex
 	// boot.art oat/arm/boot.vdex
 }
 
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index feee90f..3766bb0 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -64,10 +64,10 @@
 	fmt.Printf("outputs: %q\n", rule.Outputs())
 
 	// Output:
-	// commands: "ld a.o b.o -o out/linked && echo success"
+	// commands: "ld a.o b.o -o out/soong/linked && echo success"
 	// tools: ["ld"]
 	// inputs: ["a.o" "b.o"]
-	// outputs: ["out/linked"]
+	// outputs: ["out/soong/linked"]
 }
 
 func ExampleRuleBuilder_SymlinkOutputs() {
@@ -79,7 +79,7 @@
 		Tool(PathForSource(ctx, "ln")).
 		FlagWithInput("-s ", PathForTesting("a.o")).
 		SymlinkOutput(PathForOutput(ctx, "a"))
-	rule.Command().Text("cp out/a out/b").
+	rule.Command().Text("cp out/soong/a out/soong/b").
 		ImplicitSymlinkOutput(PathForOutput(ctx, "b"))
 
 	fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && "))
@@ -89,11 +89,11 @@
 	fmt.Printf("symlink_outputs: %q\n", rule.SymlinkOutputs())
 
 	// Output:
-	// commands: "ln -s a.o out/a && cp out/a out/b"
+	// commands: "ln -s a.o out/soong/a && cp out/soong/a out/soong/b"
 	// tools: ["ln"]
 	// inputs: ["a.o"]
-	// outputs: ["out/a" "out/b"]
-	// symlink_outputs: ["out/a" "out/b"]
+	// outputs: ["out/soong/a" "out/soong/b"]
+	// symlink_outputs: ["out/soong/a" "out/soong/b"]
 }
 
 func ExampleRuleBuilder_Temporary() {
@@ -117,10 +117,10 @@
 	fmt.Printf("outputs: %q\n", rule.Outputs())
 
 	// Output:
-	// commands: "cp a out/b && cp out/b out/c"
+	// commands: "cp a out/soong/b && cp out/soong/b out/soong/c"
 	// tools: ["cp"]
 	// inputs: ["a"]
-	// outputs: ["out/c"]
+	// outputs: ["out/soong/c"]
 }
 
 func ExampleRuleBuilder_DeleteTemporaryFiles() {
@@ -145,10 +145,10 @@
 	fmt.Printf("outputs: %q\n", rule.Outputs())
 
 	// Output:
-	// commands: "cp a out/b && cp out/b out/c && rm -f out/b"
+	// commands: "cp a out/soong/b && cp out/soong/b out/soong/c && rm -f out/soong/b"
 	// tools: ["cp"]
 	// inputs: ["a"]
-	// outputs: ["out/c"]
+	// outputs: ["out/soong/c"]
 }
 
 func ExampleRuleBuilder_Installs() {
@@ -168,7 +168,7 @@
 	fmt.Printf("rule.Installs().String() = %q\n", rule.Installs().String())
 
 	// Output:
-	// rule.Installs().String() = "out/linked:/bin/linked out/linked:/sbin/linked"
+	// rule.Installs().String() = "out/soong/linked:/bin/linked out/soong/linked:/sbin/linked"
 }
 
 func ExampleRuleBuilderCommand() {
@@ -271,7 +271,7 @@
 		FlagWithRspFileInputList("@", PathForOutput(ctx, "foo.rsp"), PathsForTesting("a.java", "b.java")).
 		String())
 	// Output:
-	// javac @out/foo.rsp
+	// javac @out/soong/foo.rsp
 }
 
 func ExampleRuleBuilderCommand_String() {
@@ -371,15 +371,15 @@
 		addCommands(rule)
 
 		wantCommands := []string{
-			"out_local/module/DepFile Flag FlagWithArg=arg FlagWithDepFile=out_local/module/depfile " +
-				"FlagWithInput=input FlagWithOutput=out_local/module/output FlagWithRspFileInputList=out_local/rsp " +
-				"Input out_local/module/Output out_local/module/SymlinkOutput Text Tool after command2 old cmd",
-			"command2 out_local/module/depfile2 input2 out_local/module/output2 tool2",
-			"command3 input3 out_local/module/output2 out_local/module/output3 input3 out_local/module/output2",
+			"out_local/soong/module/DepFile Flag FlagWithArg=arg FlagWithDepFile=out_local/soong/module/depfile " +
+				"FlagWithInput=input FlagWithOutput=out_local/soong/module/output FlagWithRspFileInputList=out_local/soong/rsp " +
+				"Input out_local/soong/module/Output out_local/soong/module/SymlinkOutput Text Tool after command2 old cmd",
+			"command2 out_local/soong/module/depfile2 input2 out_local/soong/module/output2 tool2",
+			"command3 input3 out_local/soong/module/output2 out_local/soong/module/output3 input3 out_local/soong/module/output2",
 		}
 
-		wantDepMergerCommand := "out_local/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer " +
-			"out_local/module/DepFile out_local/module/depfile out_local/module/ImplicitDepFile out_local/module/depfile2"
+		wantDepMergerCommand := "out_local/soong/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer " +
+			"out_local/soong/module/DepFile out_local/soong/module/depfile out_local/soong/module/ImplicitDepFile out_local/soong/module/depfile2"
 
 		AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands())
 
@@ -403,13 +403,13 @@
 		wantCommands := []string{
 			"__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " +
 				"FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " +
-				"FlagWithRspFileInputList=out_local/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
+				"FlagWithRspFileInputList=out_local/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
 				"__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text Tool after command2 old cmd",
 			"command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 tool2",
 			"command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2",
 		}
 
-		wantDepMergerCommand := "out_local/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2"
+		wantDepMergerCommand := "out_local/soong/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2"
 
 		AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands())
 
@@ -433,7 +433,7 @@
 		wantCommands := []string{
 			"__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " +
 				"FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " +
-				"FlagWithRspFileInputList=out_local/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
+				"FlagWithRspFileInputList=out_local/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " +
 				"__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd",
 			"command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2",
 			"command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2",
diff --git a/compliance/build_license_metadata/build_license_metadata.go b/compliance/build_license_metadata/build_license_metadata.go
index ba3cc3e..8b1fe58 100644
--- a/compliance/build_license_metadata/build_license_metadata.go
+++ b/compliance/build_license_metadata/build_license_metadata.go
@@ -119,7 +119,7 @@
 	for _, installMap := range installMaps {
 		components := strings.Split(installMap, ":")
 		if len(components) != 2 {
-			panic(fmt.Errorf("install map entry %q contains %d colons, expected 1", len(components)-1))
+			panic(fmt.Errorf("install map entry %q contains %d colons, expected 1", installMap, len(components)-1))
 		}
 		ret = append(ret, &license_metadata_proto.InstallMap{
 			FromPath:      proto.String(components[0]),
@@ -140,7 +140,7 @@
 		dep := components[0]
 		components = components[1:]
 		ad := &license_metadata_proto.AnnotatedDependency{
-			File: proto.String(dep),
+			File:        proto.String(dep),
 			Annotations: make([]string, 0, len(components)),
 		}
 		for _, ann := range components {
diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go
index d81ac2c..4a3d390 100644
--- a/dexpreopt/class_loader_context_test.go
+++ b/dexpreopt/class_loader_context_test.go
@@ -115,16 +115,16 @@
 	// Test that class loader context structure is correct.
 	t.Run("string", func(t *testing.T) {
 		wantStr := " --host-context-for-sdk 29 " +
-			"PCL[out/" + AndroidHidlManager + ".jar]#" +
-			"PCL[out/" + AndroidHidlBase + ".jar]" +
+			"PCL[out/soong/" + AndroidHidlManager + ".jar]#" +
+			"PCL[out/soong/" + AndroidHidlBase + ".jar]" +
 			" --target-context-for-sdk 29 " +
 			"PCL[/system/framework/" + AndroidHidlManager + ".jar]#" +
 			"PCL[/system/framework/" + AndroidHidlBase + ".jar]" +
 			" --host-context-for-sdk any " +
-			"PCL[out/a.jar]#PCL[out/b.jar]#PCL[out/c.jar]#PCL[out/d.jar]" +
-			"{PCL[out/a2.jar]#PCL[out/b2.jar]#PCL[out/c2.jar]" +
-			"{PCL[out/a1.jar]#PCL[out/b1.jar]}}#" +
-			"PCL[out/f.jar]#PCL[out/a3.jar]#PCL[out/b3.jar]" +
+			"PCL[out/soong/a.jar]#PCL[out/soong/b.jar]#PCL[out/soong/c.jar]#PCL[out/soong/d.jar]" +
+			"{PCL[out/soong/a2.jar]#PCL[out/soong/b2.jar]#PCL[out/soong/c2.jar]" +
+			"{PCL[out/soong/a1.jar]#PCL[out/soong/b1.jar]}}#" +
+			"PCL[out/soong/f.jar]#PCL[out/soong/a3.jar]#PCL[out/soong/b3.jar]" +
 			" --target-context-for-sdk any " +
 			"PCL[/system/a.jar]#PCL[/system/b.jar]#PCL[/system/c.jar]#PCL[/system/d.jar]" +
 			"{PCL[/system/a2.jar]#PCL[/system/b2.jar]#PCL[/system/c2.jar]" +
@@ -138,11 +138,11 @@
 	// Test that all expected build paths are gathered.
 	t.Run("paths", func(t *testing.T) {
 		wantPaths := []string{
-			"out/android.hidl.manager-V1.0-java.jar", "out/android.hidl.base-V1.0-java.jar",
-			"out/a.jar", "out/b.jar", "out/c.jar", "out/d.jar",
-			"out/a2.jar", "out/b2.jar", "out/c2.jar",
-			"out/a1.jar", "out/b1.jar",
-			"out/f.jar", "out/a3.jar", "out/b3.jar",
+			"out/soong/android.hidl.manager-V1.0-java.jar", "out/soong/android.hidl.base-V1.0-java.jar",
+			"out/soong/a.jar", "out/soong/b.jar", "out/soong/c.jar", "out/soong/d.jar",
+			"out/soong/a2.jar", "out/soong/b2.jar", "out/soong/c2.jar",
+			"out/soong/a1.jar", "out/soong/b1.jar",
+			"out/soong/f.jar", "out/soong/a3.jar", "out/soong/b3.jar",
 		}
 		if !reflect.DeepEqual(wantPaths, havePaths.Strings()) {
 			t.Errorf("\nwant paths: %s\nhave paths: %s", wantPaths, havePaths)
@@ -270,13 +270,13 @@
 
 	// Test that class loader context structure is correct.
 	t.Run("string", func(t *testing.T) {
-		wantStr := " --host-context-for-sdk 30 PCL[out/c.jar]" +
+		wantStr := " --host-context-for-sdk 30 PCL[out/soong/c.jar]" +
 			" --target-context-for-sdk 30 PCL[/system/c.jar]" +
-			" --host-context-for-sdk 29 PCL[out/b.jar]" +
+			" --host-context-for-sdk 29 PCL[out/soong/b.jar]" +
 			" --target-context-for-sdk 29 PCL[/system/b.jar]" +
-			" --host-context-for-sdk 28 PCL[out/a.jar]" +
+			" --host-context-for-sdk 28 PCL[out/soong/a.jar]" +
 			" --target-context-for-sdk 28 PCL[/system/a.jar]" +
-			" --host-context-for-sdk any PCL[out/d.jar]" +
+			" --host-context-for-sdk any PCL[out/soong/d.jar]" +
 			" --target-context-for-sdk any PCL[/system/d.jar]"
 		if wantStr != haveStr {
 			t.Errorf("\nwant class loader context: %s\nhave class loader context: %s", wantStr, haveStr)