Merge "Fix nested properties in soong config structs"
diff --git a/android/apex.go b/android/apex.go
index 81f8c86..a014592 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -849,8 +849,12 @@
if err := to.ShouldSupportSdkVersion(ctx, minSdkVersion); err != nil {
toName := ctx.OtherModuleName(to)
if ver, ok := minSdkVersionAllowlist[toName]; !ok || ver.GreaterThan(minSdkVersion) {
- ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v. Dependency path: %s",
- minSdkVersion, ctx.ModuleName(), err.Error(), ctx.GetPathString(false))
+ ctx.OtherModuleErrorf(to, "should support min_sdk_version(%v) for %q: %v."+
+ "\n\nDependency path: %s\n\n"+
+ "Consider adding 'min_sdk_version: %q' to %q",
+ minSdkVersion, ctx.ModuleName(), err.Error(),
+ ctx.GetPathString(false),
+ minSdkVersion, ctx.ModuleName())
return false
}
}
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 415f00e..9cd9fad 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -441,7 +441,7 @@
case "arm":
deps_arm = append(deps_arm, labelString)
default:
- panic(fmt.Sprintf("unhandled architecture %s for %s", getArchString(val), val))
+ panic(fmt.Sprintf("unhandled architecture %s for %v", getArchString(val), val))
}
}
diff --git a/android/config.go b/android/config.go
index ef5eadf..c10ad09 100644
--- a/android/config.go
+++ b/android/config.go
@@ -232,7 +232,7 @@
// Copy the real PATH value to the test environment, it's needed by
// NonHermeticHostSystemTool() used in x86_darwin_host.go
- envCopy["PATH"] = originalEnv["PATH"]
+ envCopy["PATH"] = os.Getenv("PATH")
config := &config{
productVariables: productVariables{
diff --git a/android/defs.go b/android/defs.go
index 38ecb05..1a76721 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -57,6 +57,15 @@
},
"cpFlags")
+ // A copy rule that only updates the output if it changed.
+ CpIfChanged = pctx.AndroidStaticRule("CpIfChanged",
+ blueprint.RuleParams{
+ Command: "if ! cmp -s $in $out; then cp $in $out; fi",
+ Description: "cp if changed $out",
+ Restat: true,
+ },
+ "cpFlags")
+
CpExecutable = pctx.AndroidStaticRule("CpExecutable",
blueprint.RuleParams{
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out",
diff --git a/android/env.go b/android/env.go
index a8c7777..289d803 100644
--- a/android/env.go
+++ b/android/env.go
@@ -15,12 +15,6 @@
package android
import (
- "fmt"
- "os"
- "os/exec"
- "strings"
- "syscall"
-
"android/soong/shared"
)
@@ -32,70 +26,12 @@
// a manifest regeneration.
var originalEnv map[string]string
-var soongDelveListen string
-var soongDelvePath string
-var soongDelveEnv []string
-func init() {
- // Delve support needs to read this environment variable very early, before NewConfig has created a way to
- // access originalEnv with dependencies. Store the value where soong_build can find it, it will manually
- // ensure the dependencies are created.
- soongDelveListen = os.Getenv("SOONG_DELVE")
- soongDelvePath = os.Getenv("SOONG_DELVE_PATH")
- if soongDelvePath == "" {
- soongDelvePath, _ = exec.LookPath("dlv")
- }
-
- originalEnv = make(map[string]string)
- soongDelveEnv = []string{}
- for _, env := range os.Environ() {
- idx := strings.IndexRune(env, '=')
- if idx != -1 {
- originalEnv[env[:idx]] = env[idx+1:]
- if env[:idx] != "SOONG_DELVE" && env[:idx] != "SOONG_DELVE_PATH" {
- soongDelveEnv = append(soongDelveEnv, env)
- }
- }
- }
-
- // Clear the environment to prevent use of os.Getenv(), which would not provide dependencies on environment
- // variable values. The environment is available through ctx.Config().Getenv, ctx.Config().IsEnvTrue, etc.
- os.Clearenv()
-}
-
-func ReexecWithDelveMaybe() {
- if soongDelveListen == "" {
- return
- }
-
- if soongDelvePath == "" {
- fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
- os.Exit(1)
- }
- dlvArgv := []string{
- soongDelvePath,
- "--listen=:" + soongDelveListen,
- "--headless=true",
- "--api-version=2",
- "exec",
- os.Args[0],
- "--",
- }
- dlvArgv = append(dlvArgv, os.Args[1:]...)
- os.Chdir(absSrcDir)
- syscall.Exec(soongDelvePath, dlvArgv, soongDelveEnv)
- fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve")
- os.Exit(1)
-}
-
-// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
-// function above. It doesn't add any dependencies on the environment variable, so it should
-// only be used for values that won't change. For values that might change use ctx.Config().Getenv.
-func getenv(key string) string {
- if originalEnv == nil {
- return os.Getenv(key)
- } else {
- return originalEnv[key]
+func InitEnvironment(envFile string) {
+ var err error
+ originalEnv, err = shared.EnvFromFile(envFile)
+ if err != nil {
+ panic(err)
}
}
@@ -108,7 +44,7 @@
func (c *envSingleton) GenerateBuildActions(ctx SingletonContext) {
envDeps := ctx.Config().EnvDeps()
- envFile := PathForOutput(ctx, ".soong.environment")
+ envFile := PathForOutput(ctx, "soong.environment.used")
if ctx.Failed() {
return
}
diff --git a/android/fixture.go b/android/fixture.go
index ae24b91..2c8997b 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -61,15 +61,15 @@
// register module bar twice:
// var Preparer1 = FixtureRegisterWithContext(RegisterModuleFooAndBar)
// var Preparer2 = FixtureRegisterWithContext(RegisterModuleBarAndBaz)
-// var AllPreparers = FixturePreparers(Preparer1, Preparer2)
+// var AllPreparers = GroupFixturePreparers(Preparer1, Preparer2)
//
// However, when restructured like this it would work fine:
// var PreparerFoo = FixtureRegisterWithContext(RegisterModuleFoo)
// var PreparerBar = FixtureRegisterWithContext(RegisterModuleBar)
// var PreparerBaz = FixtureRegisterWithContext(RegisterModuleBaz)
-// var Preparer1 = FixturePreparers(RegisterModuleFoo, RegisterModuleBar)
-// var Preparer2 = FixturePreparers(RegisterModuleBar, RegisterModuleBaz)
-// var AllPreparers = FixturePreparers(Preparer1, Preparer2)
+// var Preparer1 = GroupFixturePreparers(RegisterModuleFoo, RegisterModuleBar)
+// var Preparer2 = GroupFixturePreparers(RegisterModuleBar, RegisterModuleBaz)
+// var AllPreparers = GroupFixturePreparers(Preparer1, Preparer2)
//
// As after deduping and flattening AllPreparers would result in the following preparers being
// applied:
@@ -109,7 +109,7 @@
// An exported preparer for use by other packages that need to use java modules.
//
// package java
-// var PrepareForIntegrationTestWithJava = FixturePreparers(
+// var PrepareForIntegrationTestWithJava = GroupFixturePreparers(
// android.PrepareForIntegrationTestWithAndroid,
// FixtureRegisterWithContext(RegisterAGroupOfRelatedModulesMutatorsAndSingletons),
// FixtureRegisterWithContext(RegisterAnotherGroupOfRelatedModulesMutatorsAndSingletons),
@@ -144,7 +144,7 @@
// }
//
// package cc
-// var PrepareForTestWithCC = FixturePreparers(
+// var PrepareForTestWithCC = GroupFixturePreparers(
// android.PrepareForArchMutator,
// android.prepareForPrebuilts,
// FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
@@ -153,7 +153,7 @@
//
// package apex
//
-// var PrepareForApex = FixturePreparers(
+// var PrepareForApex = GroupFixturePreparers(
// ...
// )
//
@@ -182,7 +182,8 @@
// Create a Fixture.
Fixture(t *testing.T, preparers ...FixturePreparer) Fixture
- // Set the error handler that will be used to check any errors reported by the test.
+ // SetErrorHandler creates a new FixtureFactory that will use the supplied error handler to check
+ // the errors (may be 0) reported by the test.
//
// The default handlers is FixtureExpectsNoErrors which will fail the go test immediately if any
// errors are reported.
@@ -285,9 +286,12 @@
return FixtureAddTextFile("Android.bp", contents)
}
-// Create a composite FixturePreparer that is equivalent to applying each of the supplied
-// FixturePreparer instances in order.
-func FixturePreparers(preparers ...FixturePreparer) FixturePreparer {
+// GroupFixturePreparers creates a composite FixturePreparer that is equivalent to applying each of
+// the supplied FixturePreparer instances in order.
+//
+// Before preparing the fixture the list of preparers is flattened by replacing each
+// instance of GroupFixturePreparers with its contents.
+func GroupFixturePreparers(preparers ...FixturePreparer) FixturePreparer {
return &compositeFixturePreparer{dedupAndFlattenPreparers(nil, preparers)}
}
@@ -378,23 +382,28 @@
// The supplied result can be used to access the state of the code under test just as the main
// body of the test would but if any errors other than ones expected are reported the state may
// be indeterminate.
- CheckErrors(result *TestResult, errs []error)
+ CheckErrors(result *TestResult)
}
type simpleErrorHandler struct {
- function func(result *TestResult, errs []error)
+ function func(result *TestResult)
}
-func (h simpleErrorHandler) CheckErrors(result *TestResult, errs []error) {
- h.function(result, errs)
+func (h simpleErrorHandler) CheckErrors(result *TestResult) {
+ result.Helper()
+ h.function(result)
}
// The default fixture error handler.
//
// Will fail the test immediately if any errors are reported.
+//
+// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
+// which the test is being run which means that the RunTest() method will not return.
var FixtureExpectsNoErrors = FixtureCustomErrorHandler(
- func(result *TestResult, errs []error) {
- FailIfErrored(result.T, errs)
+ func(result *TestResult) {
+ result.Helper()
+ FailIfErrored(result.T, result.Errs)
},
)
@@ -407,9 +416,15 @@
//
// The test will not fail if:
// * Multiple errors are reported that do not match the pattern as long as one does match.
+//
+// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
+// which the test is being run which means that the RunTest() method will not return.
func FixtureExpectsAtLeastOneErrorMatchingPattern(pattern string) FixtureErrorHandler {
- return FixtureCustomErrorHandler(func(result *TestResult, errs []error) {
- FailIfNoMatchingErrors(result.T, pattern, errs)
+ return FixtureCustomErrorHandler(func(result *TestResult) {
+ result.Helper()
+ if !FailIfNoMatchingErrors(result.T, pattern, result.Errs) {
+ result.FailNow()
+ }
})
}
@@ -423,14 +438,18 @@
//
// The test will not fail if:
// * One or more of the patterns does not match an error.
+//
+// If the test fails this handler will call `result.FailNow()` which will exit the goroutine within
+// which the test is being run which means that the RunTest() method will not return.
func FixtureExpectsAllErrorsToMatchAPattern(patterns []string) FixtureErrorHandler {
- return FixtureCustomErrorHandler(func(result *TestResult, errs []error) {
- CheckErrorsAgainstExpectations(result.T, errs, patterns)
+ return FixtureCustomErrorHandler(func(result *TestResult) {
+ result.Helper()
+ CheckErrorsAgainstExpectations(result.T, result.Errs, patterns)
})
}
// FixtureCustomErrorHandler creates a custom error handler
-func FixtureCustomErrorHandler(function func(result *TestResult, errs []error)) FixtureErrorHandler {
+func FixtureCustomErrorHandler(function func(result *TestResult)) FixtureErrorHandler {
return simpleErrorHandler{
function: function,
}
@@ -531,6 +550,9 @@
fixture *fixture
Config Config
+
+ // The errors that were reported during the test.
+ Errs []error
}
var _ FixtureFactory = (*fixtureFactory)(nil)
@@ -575,8 +597,10 @@
}
func (f *fixtureFactory) SetErrorHandler(errorHandler FixtureErrorHandler) FixtureFactory {
- f.errorHandler = errorHandler
- return f
+ newFactory := &fixtureFactory{}
+ *newFactory = *f
+ newFactory.errorHandler = errorHandler
+ return newFactory
}
func (f *fixtureFactory) RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult {
@@ -639,9 +663,10 @@
testContext: testContext{ctx},
fixture: f,
Config: f.config,
+ Errs: errs,
}
- f.errorHandler.CheckErrors(result, errs)
+ f.errorHandler.CheckErrors(result)
return result
}
diff --git a/android/fixture_test.go b/android/fixture_test.go
index 7bc033b..5a7bf3b 100644
--- a/android/fixture_test.go
+++ b/android/fixture_test.go
@@ -32,9 +32,9 @@
preparer3 := appendToList("preparer3")
preparer4 := appendToList("preparer4")
- preparer1Then2 := FixturePreparers(preparer1, preparer2)
+ preparer1Then2 := GroupFixturePreparers(preparer1, preparer2)
- preparer2Then1 := FixturePreparers(preparer2, preparer1)
+ preparer2Then1 := GroupFixturePreparers(preparer2, preparer1)
buildDir := "build"
factory := NewFixtureFactory(&buildDir, preparer1, preparer2, preparer1, preparer1Then2)
diff --git a/android/license.go b/android/license.go
index b140b55..3bc6199 100644
--- a/android/license.go
+++ b/android/license.go
@@ -19,7 +19,7 @@
)
type licenseKindDependencyTag struct {
- blueprint.BaseDependencyTag
+ blueprint.BaseDependencyTag
}
var (
diff --git a/android/license_test.go b/android/license_test.go
index 552bbae..9f68713 100644
--- a/android/license_test.go
+++ b/android/license_test.go
@@ -49,9 +49,9 @@
}`),
},
expectedErrors: []string{
- `other/Blueprints:2:5: module "arule": depends on //top:top_allowed_as_notice `+
+ `other/Blueprints:2:5: module "arule": depends on //top:top_allowed_as_notice ` +
`which is not visible to this module`,
- `yetmore/Blueprints:2:5: module "//yetmore": depends on //top:top_allowed_as_notice `+
+ `yetmore/Blueprints:2:5: module "//yetmore": depends on //top:top_allowed_as_notice ` +
`which is not visible to this module`,
},
},
@@ -70,7 +70,7 @@
}`),
},
expectedErrors: []string{
- `top/Blueprints:6:5: module "top_proprietary": license_kinds property `+
+ `top/Blueprints:6:5: module "top_proprietary": license_kinds property ` +
`"top_by_exception_only" is not a license_kind module`,
},
},
diff --git a/android/licenses.go b/android/licenses.go
index 1000429..2838f5d 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -51,7 +51,7 @@
func newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty {
return applicableLicensesPropertyImpl{
- name: name,
+ name: name,
licensesProperty: licensesProperty,
}
}
diff --git a/android/licenses_test.go b/android/licenses_test.go
index b94add7..c043791 100644
--- a/android/licenses_test.go
+++ b/android/licenses_test.go
@@ -7,15 +7,15 @@
)
var licensesTests = []struct {
- name string
- fs map[string][]byte
- expectedErrors []string
- effectiveLicenses map[string][]string
- effectiveInheritedLicenses map[string][]string
- effectivePackage map[string]string
- effectiveNotices map[string][]string
- effectiveKinds map[string][]string
- effectiveConditions map[string][]string
+ name string
+ fs map[string][]byte
+ expectedErrors []string
+ effectiveLicenses map[string][]string
+ effectiveInheritedLicenses map[string][]string
+ effectivePackage map[string]string
+ effectiveNotices map[string][]string
+ effectiveKinds map[string][]string
+ effectiveConditions map[string][]string
}{
{
name: "invalid module type without licenses property",
@@ -71,28 +71,28 @@
},
effectiveLicenses: map[string][]string{
"libexample1": []string{"top_Apache2"},
- "libnested": []string{"top_Apache2"},
- "libother": []string{"top_Apache2"},
+ "libnested": []string{"top_Apache2"},
+ "libother": []string{"top_Apache2"},
},
effectiveKinds: map[string][]string{
"libexample1": []string{"notice"},
- "libnested": []string{"notice"},
- "libother": []string{"notice"},
+ "libnested": []string{"notice"},
+ "libother": []string{"notice"},
},
effectivePackage: map[string]string{
"libexample1": "topDog",
- "libnested": "topDog",
- "libother": "topDog",
+ "libnested": "topDog",
+ "libother": "topDog",
},
effectiveConditions: map[string][]string{
"libexample1": []string{"shownotice"},
- "libnested": []string{"shownotice"},
- "libother": []string{"shownotice"},
+ "libnested": []string{"shownotice"},
+ "libother": []string{"shownotice"},
},
effectiveNotices: map[string][]string{
"libexample1": []string{"top/LICENSE", "top/NOTICE"},
- "libnested": []string{"top/LICENSE", "top/NOTICE"},
- "libother": []string{"top/LICENSE", "top/NOTICE"},
+ "libnested": []string{"top/LICENSE", "top/NOTICE"},
+ "libother": []string{"top/LICENSE", "top/NOTICE"},
},
},
@@ -147,28 +147,28 @@
}`),
},
effectiveLicenses: map[string][]string{
- "libexample": []string{"nested_other", "top_other"},
+ "libexample": []string{"nested_other", "top_other"},
"libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
+ "libnested": []string{},
+ "libother": []string{},
},
effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"nested_other", "top_other"},
+ "libexample": []string{"nested_other", "top_other"},
"libsamepackage": []string{"nested_other", "top_other"},
- "libnested": []string{"nested_other", "top_other"},
- "libother": []string{"nested_other", "top_other"},
+ "libnested": []string{"nested_other", "top_other"},
+ "libother": []string{"nested_other", "top_other"},
},
effectiveKinds: map[string][]string{
- "libexample": []string{"nested_notice", "top_notice"},
+ "libexample": []string{"nested_notice", "top_notice"},
"libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
+ "libnested": []string{},
+ "libother": []string{},
},
effectiveConditions: map[string][]string{
- "libexample": []string{"notice"},
+ "libexample": []string{"notice"},
"libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
+ "libnested": []string{},
+ "libother": []string{},
},
},
{
@@ -218,32 +218,32 @@
}`),
},
effectiveLicenses: map[string][]string{
- "libexample": []string{"other", "top_nested"},
+ "libexample": []string{"other", "top_nested"},
"libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
- "liboutsider": []string{},
+ "libnested": []string{},
+ "libother": []string{},
+ "liboutsider": []string{},
},
effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"other", "top_nested"},
+ "libexample": []string{"other", "top_nested"},
"libsamepackage": []string{"other", "top_nested"},
- "libnested": []string{"other", "top_nested"},
- "libother": []string{"other", "top_nested"},
- "liboutsider": []string{"other", "top_nested"},
+ "libnested": []string{"other", "top_nested"},
+ "libother": []string{"other", "top_nested"},
+ "liboutsider": []string{"other", "top_nested"},
},
effectiveKinds: map[string][]string{
- "libexample": []string{},
+ "libexample": []string{},
"libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
- "liboutsider": []string{},
+ "libnested": []string{},
+ "libother": []string{},
+ "liboutsider": []string{},
},
effectiveNotices: map[string][]string{
- "libexample": []string{"top/nested/LICENSE.txt"},
+ "libexample": []string{"top/nested/LICENSE.txt"},
"libsamepackage": []string{},
- "libnested": []string{},
- "libother": []string{},
- "liboutsider": []string{},
+ "libnested": []string{},
+ "libother": []string{},
+ "liboutsider": []string{},
},
},
@@ -285,11 +285,11 @@
}`),
},
effectiveLicenses: map[string][]string{
- "libexample": []string{"by_exception_only"},
+ "libexample": []string{"by_exception_only"},
"libdefaults": []string{"notice"},
},
effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"by_exception_only"},
+ "libexample": []string{"by_exception_only"},
"libdefaults": []string{"notice"},
},
},
@@ -327,11 +327,11 @@
}`),
},
effectiveLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
+ "libexample": []string{"top_notice"},
"liboutsider": []string{},
},
effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
+ "libexample": []string{"top_notice"},
"liboutsider": []string{"top_notice"},
},
},
@@ -370,15 +370,15 @@
}`),
},
effectiveLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
- "libnested": []string{"outsider"},
- "libother": []string{},
+ "libexample": []string{"top_notice"},
+ "libnested": []string{"outsider"},
+ "libother": []string{},
"liboutsider": []string{},
},
effectiveInheritedLicenses: map[string][]string{
- "libexample": []string{"top_notice"},
- "libnested": []string{"outsider"},
- "libother": []string{},
+ "libexample": []string{"top_notice"},
+ "libnested": []string{"outsider"},
+ "libother": []string{},
"liboutsider": []string{"top_notice", "outsider"},
},
},
@@ -449,7 +449,7 @@
},
effectiveInheritedLicenses: map[string][]string{
"module": []string{"prebuilt", "top_sources"},
- "other": []string{"prebuilt", "top_sources"},
+ "other": []string{"prebuilt", "top_sources"},
},
},
}
diff --git a/android/module.go b/android/module.go
index e8fb749..9f923e2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1832,6 +1832,18 @@
return
}
+ m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
+ rcDir := PathForModuleInstall(ctx, "etc", "init")
+ for _, src := range m.initRcPaths {
+ ctx.PackageFile(rcDir, filepath.Base(src.String()), src)
+ }
+
+ m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
+ vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
+ for _, src := range m.vintfFragmentsPaths {
+ ctx.PackageFile(vintfDir, filepath.Base(src.String()), src)
+ }
+
// Create the set of tagged dist files after calling GenerateAndroidBuildActions
// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
// output paths being set which must be done before or during
@@ -1844,8 +1856,6 @@
m.installFiles = append(m.installFiles, ctx.installFiles...)
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
- m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
- m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
for k, v := range ctx.phonies {
m.phonies[k] = append(m.phonies[k], v...)
}
diff --git a/android/mutator.go b/android/mutator.go
index b023001..9552aa1 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -33,22 +33,8 @@
// run FinalDeps mutators (CreateVariations disallowed in this phase)
// continue on to GenerateAndroidBuildActions
-func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
- for _, t := range mutators {
- var handle blueprint.MutatorHandle
- if t.bottomUpMutator != nil {
- handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator)
- } else if t.topDownMutator != nil {
- handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator)
- }
- if t.parallel {
- handle.Parallel()
- }
- }
-}
-
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
-func RegisterMutatorsForBazelConversion(ctx *blueprint.Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
+func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators, depsMutators, bp2buildMutators []RegisterMutatorFunc) {
mctx := ®isterMutatorsContext{
bazelConversionMode: true,
}
@@ -80,10 +66,17 @@
f(mctx)
}
- registerMutatorsToContext(ctx, mctx.mutators)
+ mctx.mutators.registerAll(ctx)
}
-func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
+// collateGloballyRegisteredMutators constructs the list of mutators that have been registered
+// with the InitRegistrationContext and will be used at runtime.
+func collateGloballyRegisteredMutators() sortableComponents {
+ return collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps)
+}
+
+// collateRegisteredMutators constructs a single list of mutators from the separate lists.
+func collateRegisteredMutators(preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) sortableComponents {
mctx := ®isterMutatorsContext{}
register := func(funcs []RegisterMutatorFunc) {
@@ -103,11 +96,11 @@
mctx.finalPhase = true
register(finalDeps)
- registerMutatorsToContext(ctx, mctx.mutators)
+ return mctx.mutators
}
type registerMutatorsContext struct {
- mutators []*mutator
+ mutators sortableComponents
finalPhase bool
bazelConversionMode bool
}
@@ -473,6 +466,23 @@
return mutator
}
+func (mutator *mutator) componentName() string {
+ return mutator.name
+}
+
+func (mutator *mutator) register(ctx *Context) {
+ blueprintCtx := ctx.Context
+ var handle blueprint.MutatorHandle
+ if mutator.bottomUpMutator != nil {
+ handle = blueprintCtx.RegisterBottomUpMutator(mutator.name, mutator.bottomUpMutator)
+ } else if mutator.topDownMutator != nil {
+ handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
+ }
+ if mutator.parallel {
+ handle.Parallel()
+ }
+}
+
type MutatorHandle interface {
Parallel() MutatorHandle
}
diff --git a/android/paths.go b/android/paths.go
index ada4da6..3f4d3f2 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1662,9 +1662,9 @@
// on a device without a dedicated recovery partition, install the
// recovery variant.
if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() {
- partition = "vendor-ramdisk/first_stage_ramdisk"
+ partition = "vendor_ramdisk/first_stage_ramdisk"
} else {
- partition = "vendor-ramdisk"
+ partition = "vendor_ramdisk"
}
if !ctx.InstallInRoot() {
partition += "/system"
diff --git a/android/queryview.go b/android/queryview.go
index 9e3e45a..b940202 100644
--- a/android/queryview.go
+++ b/android/queryview.go
@@ -67,10 +67,14 @@
blueprint.RuleParams{
Command: fmt.Sprintf(
"rm -rf ${outDir}/* && "+
- "%s --bazel_queryview_dir ${outDir} %s && "+
+ "BUILDER=\"%s\" && "+
+ "cd $$(dirname \"$$BUILDER\") && "+
+ "ABSBUILDER=\"$$PWD/$$(basename \"$$BUILDER\")\" && "+
+ "cd / && "+
+ "env -i \"$$ABSBUILDER\" --bazel_queryview_dir ${outDir} \"%s\" && "+
"echo WORKSPACE: `cat %s` > ${outDir}/.queryview-depfile.d",
primaryBuilder.String(),
- strings.Join(os.Args[1:], " "),
+ strings.Join(os.Args[1:], "\" \""),
moduleListFilePath.String(), // Use the contents of Android.bp.list as the depfile.
),
CommandDeps: []string{primaryBuilder.String()},
diff --git a/android/register.go b/android/register.go
index 47df972..278a04f 100644
--- a/android/register.go
+++ b/android/register.go
@@ -21,21 +21,78 @@
"github.com/google/blueprint"
)
+// A sortable component is one whose registration order affects the order in which it is executed
+// and so affects the behavior of the build system. As a result it is important for the order in
+// which they are registered during tests to match the order used at runtime and so the test
+// infrastructure will sort them to match.
+//
+// The sortable components are mutators, singletons and pre-singletons. Module types are not
+// sortable because their order of registration does not affect the runtime behavior.
+type sortableComponent interface {
+ // componentName returns the name of the component.
+ //
+ // Uniquely identifies the components within the set of components used at runtimr and during
+ // tests.
+ componentName() string
+
+ // register registers this component in the supplied context.
+ register(ctx *Context)
+}
+
+type sortableComponents []sortableComponent
+
+// registerAll registers all components in this slice with the supplied context.
+func (r sortableComponents) registerAll(ctx *Context) {
+ for _, c := range r {
+ c.register(ctx)
+ }
+}
+
type moduleType struct {
name string
factory ModuleFactory
}
+func (t moduleType) register(ctx *Context) {
+ ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
+}
+
var moduleTypes []moduleType
var moduleTypesForDocs = map[string]reflect.Value{}
type singleton struct {
+ // True if this should be registered as a pre-singleton, false otherwise.
+ pre bool
+
name string
factory SingletonFactory
}
-var singletons []singleton
-var preSingletons []singleton
+func newSingleton(name string, factory SingletonFactory) singleton {
+ return singleton{false, name, factory}
+}
+
+func newPreSingleton(name string, factory SingletonFactory) singleton {
+ return singleton{true, name, factory}
+}
+
+func (s singleton) componentName() string {
+ return s.name
+}
+
+func (s singleton) register(ctx *Context) {
+ adaptor := SingletonFactoryAdaptor(ctx, s.factory)
+ if s.pre {
+ ctx.RegisterPreSingletonType(s.name, adaptor)
+ } else {
+ ctx.RegisterSingletonType(s.name, adaptor)
+ }
+}
+
+var _ sortableComponent = singleton{}
+
+var singletons sortableComponents
+var preSingletons sortableComponents
type mutator struct {
name string
@@ -44,6 +101,8 @@
parallel bool
}
+var _ sortableComponent = &mutator{}
+
type ModuleFactory func() Module
// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
@@ -84,11 +143,11 @@
}
func RegisterSingletonType(name string, factory SingletonFactory) {
- singletons = append(singletons, singleton{name, factory})
+ singletons = append(singletons, newSingleton(name, factory))
}
func RegisterPreSingletonType(name string, factory SingletonFactory) {
- preSingletons = append(preSingletons, singleton{name, factory})
+ preSingletons = append(preSingletons, newPreSingleton(name, factory))
}
type Context struct {
@@ -107,33 +166,30 @@
// files to semantically equivalent BUILD files.
func (ctx *Context) RegisterForBazelConversion() {
for _, t := range moduleTypes {
- ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
+ t.register(ctx)
}
// Required for SingletonModule types, even though we are not using them.
for _, t := range singletons {
- ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
+ t.register(ctx)
}
- RegisterMutatorsForBazelConversion(ctx.Context, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators)
+ RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators, bp2buildDepsMutators, bp2buildMutators)
}
// Register the pipeline of singletons, module types, and mutators for
// generating build.ninja and other files for Kati, from Android.bp files.
func (ctx *Context) Register() {
- for _, t := range preSingletons {
- ctx.RegisterPreSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
- }
+ preSingletons.registerAll(ctx)
for _, t := range moduleTypes {
- ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
+ t.register(ctx)
}
- for _, t := range singletons {
- ctx.RegisterSingletonType(t.name, SingletonFactoryAdaptor(ctx, t.factory))
- }
+ singletons.registerAll(ctx)
- registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
+ mutators := collateGloballyRegisteredMutators()
+ mutators.registerAll(ctx)
ctx.RegisterSingletonType("bazeldeps", SingletonFactoryAdaptor(ctx, BazelSingleton))
diff --git a/android/sandbox.go b/android/sandbox.go
index ed022fb..28e903a 100644
--- a/android/sandbox.go
+++ b/android/sandbox.go
@@ -14,29 +14,8 @@
package android
-import (
- "fmt"
- "os"
-)
-
-func init() {
- // Stash the working directory in a private variable and then change the working directory
- // to "/", which will prevent untracked accesses to files by Go Soong plugins. The
- // SOONG_SANDBOX_SOONG_BUILD environment variable is set by soong_ui, and is not
- // overrideable on the command line.
-
- orig, err := os.Getwd()
- if err != nil {
- panic(fmt.Errorf("failed to get working directory: %s", err))
- }
- absSrcDir = orig
-
- if getenv("SOONG_SANDBOX_SOONG_BUILD") == "true" {
- err = os.Chdir("/")
- if err != nil {
- panic(fmt.Errorf("failed to change working directory to '/': %s", err))
- }
- }
+func InitSandbox(topDir string) {
+ absSrcDir = topDir
}
// DO NOT USE THIS FUNCTION IN NEW CODE.
diff --git a/android/testing.go b/android/testing.go
index 5832796..b134eae 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -48,7 +48,7 @@
return ctx
}
-var PrepareForTestWithArchMutator = FixturePreparers(
+var PrepareForTestWithArchMutator = GroupFixturePreparers(
// Configure architecture targets in the fixture config.
FixtureModifyConfig(modifyTestConfigToSupportArchMutator),
@@ -73,7 +73,7 @@
})
// Prepares an integration test with build components from the android package.
-var PrepareForIntegrationTestWithAndroid = FixturePreparers(
+var PrepareForIntegrationTestWithAndroid = GroupFixturePreparers(
// Mutators. Must match order in mutator.go.
PrepareForTestWithArchMutator,
PrepareForTestWithDefaults,
@@ -141,14 +141,15 @@
}
func (ctx *TestContext) Register() {
- registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
+ mutators := collateRegisteredMutators(ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
+ mutators.registerAll(ctx.Context)
ctx.RegisterSingletonType("env", EnvSingleton)
}
// RegisterForBazelConversion prepares a test context for bp2build conversion.
func (ctx *TestContext) RegisterForBazelConversion() {
- RegisterMutatorsForBazelConversion(ctx.Context.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
+ RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch, ctx.bp2buildDeps, ctx.bp2buildMutators)
}
func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {
@@ -456,12 +457,15 @@
}
}
-func FailIfNoMatchingErrors(t *testing.T, pattern string, errs []error) {
+// Fail if no errors that matched the regular expression were found.
+//
+// Returns true if a matching error was found, false otherwise.
+func FailIfNoMatchingErrors(t *testing.T, pattern string, errs []error) bool {
t.Helper()
matcher, err := regexp.Compile(pattern)
if err != nil {
- t.Errorf("failed to compile regular expression %q because %s", pattern, err)
+ t.Fatalf("failed to compile regular expression %q because %s", pattern, err)
}
found := false
@@ -477,6 +481,8 @@
t.Errorf("errs[%d] = %q", i, err)
}
}
+
+ return found
}
func CheckErrorsAgainstExpectations(t *testing.T, errs []error, expectedErrorPatterns []string) {
@@ -497,9 +503,9 @@
for i, err := range errs {
t.Errorf("errs[%d] = %s", i, err)
}
+ t.FailNow()
}
}
-
}
func SetKatiEnabledForTests(config Config) {
diff --git a/android/writedocs.go b/android/writedocs.go
index 91c2318..6cb2f10 100644
--- a/android/writedocs.go
+++ b/android/writedocs.go
@@ -34,7 +34,8 @@
type docsSingleton struct{}
func primaryBuilderPath(ctx SingletonContext) Path {
- primaryBuilder, err := filepath.Rel(ctx.Config().BuildDir(), os.Args[0])
+ buildDir := absolutePath(ctx.Config().BuildDir())
+ primaryBuilder, err := filepath.Rel(buildDir, os.Args[0])
if err != nil {
ctx.Errorf("path to primary builder %q is not in build dir %q",
os.Args[0], ctx.Config().BuildDir())
@@ -65,7 +66,9 @@
soongDocs := ctx.Rule(pctx, "soongDocs",
blueprint.RuleParams{
Command: fmt.Sprintf("rm -f ${outDir}/* && %s --soong_docs %s %s",
- primaryBuilder.String(), docsFile.String(), strings.Join(os.Args[1:], " ")),
+ primaryBuilder.String(),
+ docsFile.String(),
+ "\""+strings.Join(os.Args[1:], "\" \"")+"\""),
CommandDeps: []string{primaryBuilder.String()},
Description: fmt.Sprintf("%s docs $out", primaryBuilder.Base()),
},
diff --git a/apex/OWNERS b/apex/OWNERS
index 793f3ed..fee739b 100644
--- a/apex/OWNERS
+++ b/apex/OWNERS
@@ -1,4 +1,4 @@
per-file * = jiyong@google.com
per-file allowed_deps.txt = set noparent
-per-file allowed_deps.txt = dariofreni@google.com,hansson@google.com,harpin@google.com,jiyong@google.com,narayan@google.com,omakoto@google.com,jham@google.com
+per-file allowed_deps.txt = dariofreni@google.com,hansson@google.com,harpin@google.com,jiyong@google.com,narayan@google.com,jham@google.com
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index 78b84f0..047a0f3 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -192,7 +192,7 @@
GoogleCellBroadcastApp(minSdkVersion:29)
GoogleCellBroadcastServiceModule(minSdkVersion:29)
GoogleExtServices(minSdkVersion:current)
-GooglePermissionController(minSdkVersion:28)
+GooglePermissionController(minSdkVersion:30)
guava(minSdkVersion:current)
gwp_asan_headers(minSdkVersion:(no version))
i18n.module.public.api.stubs(minSdkVersion:(no version))
@@ -361,6 +361,7 @@
libmedia_headers(minSdkVersion:29)
libmedia_helper_headers(minSdkVersion:29)
libmedia_midiiowrapper(minSdkVersion:29)
+libmediaparser-jni(minSdkVersion:29)
libmidiextractor(minSdkVersion:29)
libminijail(minSdkVersion:29)
libminijail_gen_constants(minSdkVersion:(no version))
@@ -526,7 +527,7 @@
no_op(minSdkVersion:current)
note_memtag_heap_async(minSdkVersion:16)
note_memtag_heap_sync(minSdkVersion:16)
-PermissionController(minSdkVersion:28)
+PermissionController(minSdkVersion:30)
permissioncontroller-statsd(minSdkVersion:current)
philox_random(minSdkVersion:(no version))
philox_random_headers(minSdkVersion:(no version))
@@ -635,6 +636,7 @@
Tethering(minSdkVersion:current)
TetheringApiCurrentLib(minSdkVersion:30)
TetheringApiCurrentLib(minSdkVersion:current)
+TetheringGoogle(minSdkVersion:30)
TetheringGoogle(minSdkVersion:current)
textclassifier-statsd(minSdkVersion:current)
TextClassifierNotificationLibNoManifest(minSdkVersion:29)
diff --git a/apex/apex.go b/apex/apex.go
index 8f388c4..efd1736 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2244,8 +2244,10 @@
if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
return true
}
- ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'. Dependency path:%s",
- fromName, toName, ctx.GetPathString(true))
+ ctx.ModuleErrorf("%q requires %q that doesn't list the APEX under 'apex_available'."+
+ "\n\nDependency path:%s\n\n"+
+ "Consider adding %q to 'apex_available' property of %q",
+ fromName, toName, ctx.GetPathString(true), apexName, toName)
// Visit this module's dependencies to check and report any issues with their availability.
return true
})
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 8ae6634..991f5c9 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -67,14 +67,14 @@
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
-func testApex(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+func testApex(t *testing.T, bp string, handlers ...testCustomizer) *android.TestContext {
t.Helper()
ctx, config := testApexContext(t, bp, handlers...)
_, errs := ctx.ParseBlueprintsFiles(".")
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
- return ctx, config
+ return ctx
}
type testCustomizer func(fs map[string][]byte, config android.Config)
@@ -240,7 +240,6 @@
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(android.RegisterComponentsMutator)
- ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
android.RegisterPrebuiltMutators(ctx)
@@ -249,6 +248,10 @@
ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
+ // These must come after prebuilts and visibility rules to match runtime.
+ ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
+
+ // These must come after override rules to match the runtime.
cc.RegisterRequiredBuildComponentsForTest(ctx)
rust.RegisterRequiredBuildComponentsForTest(ctx)
java.RegisterRequiredBuildComponentsForTest(ctx)
@@ -357,7 +360,7 @@
// Minimal test
func TestBasicApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_defaults {
name: "myapex-defaults",
manifest: ":myapex.manifest",
@@ -663,7 +666,7 @@
}
func TestDefaults(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_defaults {
name: "myapex-defaults",
key: "myapex.key",
@@ -738,7 +741,7 @@
}
func TestApexManifest(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -760,7 +763,7 @@
}
func TestBasicZipApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -811,7 +814,7 @@
}
func TestApexWithStubs(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -906,7 +909,7 @@
func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
t.Parallel()
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1013,7 +1016,7 @@
// |
// <platform> |
// libplatform ----------------'
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1078,7 +1081,7 @@
}
func TestApexWithExplicitStubsDependency(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex2",
key: "myapex2.key",
@@ -1174,7 +1177,7 @@
|
`------> libbar
*/
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1236,7 +1239,7 @@
}
func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
- ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+ ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) {
bp := `
apex {
name: "com.android.runtime",
@@ -1300,7 +1303,7 @@
}
func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
- ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+ ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) {
bp := `
apex {
name: "com.android.runtime",
@@ -1386,7 +1389,7 @@
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1453,7 +1456,7 @@
}
func TestApexWithSystemLibsStubs(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1549,7 +1552,7 @@
// 1) myapex -> libx -> liba -> libz : this should be #30 link
// 2) otherapex -> liby -> liba -> libz : this should be #30 link
// 3) (platform) -> liba -> libz : this should be non-stub link
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1631,7 +1634,7 @@
}
func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1680,7 +1683,7 @@
}
func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1726,7 +1729,7 @@
}
func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1774,7 +1777,7 @@
}
func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1813,7 +1816,7 @@
}
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2140,7 +2143,7 @@
}
func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2227,7 +2230,7 @@
config.TestProductVariables.Platform_sdk_codename = proptools.StringPtr("S")
config.TestProductVariables.Platform_version_active_codenames = []string{"S", "T"}
}
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2261,7 +2264,7 @@
}
func TestFilesInSubDir(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2324,7 +2327,7 @@
}
func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2383,7 +2386,7 @@
}
func TestUseVendor(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2496,7 +2499,7 @@
}
func TestVendorApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2534,7 +2537,8 @@
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
- ensureContains(t, androidMk, `LOCAL_MODULE_PATH := /tmp/target/product/test_device/vendor/apex`)
+ installPath := path.Join(buildDir, "../target/product/test_device/vendor/apex")
+ ensureContains(t, androidMk, "LOCAL_MODULE_PATH := "+installPath)
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
@@ -2542,7 +2546,7 @@
}
func TestVendorApex_use_vndk_as_stable(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2606,7 +2610,7 @@
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2634,7 +2638,7 @@
}
func TestAndroidMk_UseVendorRequired(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2669,7 +2673,7 @@
}
func TestAndroidMk_VendorApexRequired(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2701,7 +2705,7 @@
}
func TestAndroidMkWritesCommonProperties(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2731,7 +2735,7 @@
}
func TestStaticLinking(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2776,7 +2780,7 @@
}
func TestKeys(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex_keytest",
key: "myapex.key",
@@ -2834,7 +2838,7 @@
func TestCertificate(t *testing.T) {
t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2852,7 +2856,7 @@
}
})
t.Run("override when unspecified", func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex_keytest",
key: "myapex.key",
@@ -2875,7 +2879,7 @@
}
})
t.Run("if specified as :module, it respects the prop", func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2898,7 +2902,7 @@
}
})
t.Run("override when specifiec as <:module>", func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex_keytest",
key: "myapex.key",
@@ -2922,7 +2926,7 @@
}
})
t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2941,7 +2945,7 @@
}
})
t.Run("override when specified as <name>", func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex_keytest",
key: "myapex.key",
@@ -2967,7 +2971,7 @@
}
func TestMacro(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3095,7 +3099,7 @@
}
func TestHeaderLibsDependency(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3239,7 +3243,7 @@
}
func TestVndkApexCurrent(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.current",
key: "com.android.vndk.current.key",
@@ -3296,7 +3300,7 @@
}
func TestVndkApexWithPrebuilt(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.current",
key: "com.android.vndk.current.key",
@@ -3380,7 +3384,7 @@
}
func TestVndkApexVersion(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.v27",
key: "myapex.key",
@@ -3449,7 +3453,7 @@
}
func TestVndkApexNameRule(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.current",
key: "myapex.key",
@@ -3482,7 +3486,7 @@
}
func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.current",
key: "com.android.vndk.current.key",
@@ -3554,7 +3558,7 @@
}
func TestVndkApexWithBinder32(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.v27",
key: "myapex.key",
@@ -3623,7 +3627,7 @@
}
func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.current",
key: "com.android.vndk.current.key",
@@ -3659,7 +3663,7 @@
}
func TestDependenciesInApexManifest(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex_nodep",
key: "myapex.key",
@@ -3767,7 +3771,7 @@
}
func TestApexName(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3812,7 +3816,7 @@
}
func TestNonTestApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3865,7 +3869,7 @@
}
func TestTestApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_test {
name: "myapex",
key: "myapex.key",
@@ -3914,7 +3918,7 @@
}
func TestApexWithTarget(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4005,7 +4009,7 @@
}
func TestApexWithArch(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4064,7 +4068,7 @@
}
func TestApexWithShBinary(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4105,7 +4109,7 @@
}
for _, tc := range testcases {
t.Run(tc.propName+":"+tc.parition, func(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4138,7 +4142,7 @@
}
func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4192,7 +4196,7 @@
}
`)
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4215,7 +4219,7 @@
}
func TestFileContexts_SetViaFileGroup(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4243,7 +4247,7 @@
}
func TestApexKeyFromOtherModule(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_key {
name: "myapex.key",
public_key: ":my.avbpubkey",
@@ -4276,7 +4280,7 @@
}
func TestPrebuilt(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
prebuilt_apex {
name: "myapex",
arch: {
@@ -4299,7 +4303,7 @@
}
func TestPrebuiltFilenameOverride(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
prebuilt_apex {
name: "myapex",
src: "myapex-arm.apex",
@@ -4316,7 +4320,7 @@
}
func TestPrebuiltOverrides(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
prebuilt_apex {
name: "myapex.prebuilt",
src: "myapex-arm.apex",
@@ -4827,7 +4831,7 @@
}
func TestApexWithTests(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_test {
name: "myapex",
key: "myapex.key",
@@ -4939,7 +4943,7 @@
}
func TestInstallExtraFlattenedApexes(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5009,7 +5013,7 @@
}
func TestApexWithJavaImport(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5038,7 +5042,7 @@
}
func TestApexWithApps(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5117,7 +5121,7 @@
}
func TestApexWithAppImports(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5166,7 +5170,7 @@
}
func TestApexWithAppImportsPrefer(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5203,12 +5207,13 @@
}))
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "app/AppFoo/AppFooPrebuilt.apk",
+ // TODO(b/181974714) - this is wrong it should be "app/AppFoo/AppFooPrebuilt.apk"
+ "app/AppFoo/AppFoo.apk",
})
}
func TestApexWithTestHelperApp(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5314,7 +5319,7 @@
func TestApexAvailable_IndirectDep(t *testing.T) {
// libbbaz is an indirect dep
- testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'. Dependency path:
+ testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path:
.*via tag apex\.dependencyTag.*name:sharedLib.*
.*-> libfoo.*link:shared.*
.*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
@@ -5419,7 +5424,7 @@
}
func TestApexAvailable_CheckForPlatform(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5482,7 +5487,7 @@
}
func TestApexAvailable_CreatedForApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5517,7 +5522,7 @@
}
func TestOverrideApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5601,7 +5606,7 @@
}
func TestLegacyAndroid10Support(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5661,7 +5666,7 @@
}
func TestJavaSDKLibrary(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5699,7 +5704,7 @@
}
func TestJavaSDKLibrary_WithinApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5752,7 +5757,7 @@
}
func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5803,7 +5808,7 @@
}
func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
prebuilt_apis {
name: "sdk",
api_dirs: ["100"],
@@ -5920,7 +5925,7 @@
}
func TestCompatConfig(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -5981,7 +5986,7 @@
}
func TestCarryRequiredModuleNames(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6125,7 +6130,7 @@
// For unbundled build, symlink shouldn't exist regardless of whether an APEX
// is updatable or not
- ctx, _ := testApex(t, bp, withUnbundledBuild)
+ ctx := testApex(t, bp, withUnbundledBuild)
files := getFiles(t, ctx, "myapex", "android_common_myapex_image")
ensureRealfileExists(t, files, "javalib/myjar.jar")
ensureRealfileExists(t, files, "lib64/mylib.so")
@@ -6137,7 +6142,7 @@
ensureRealfileExists(t, files, "lib64/myotherlib.so")
// For bundled build, symlink to the system for the non-updatable APEXes only
- ctx, _ = testApex(t, bp)
+ ctx = testApex(t, bp)
files = getFiles(t, ctx, "myapex", "android_common_myapex_image")
ensureRealfileExists(t, files, "javalib/myjar.jar")
ensureRealfileExists(t, files, "lib64/mylib.so")
@@ -6150,7 +6155,7 @@
}
func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6202,7 +6207,7 @@
}
func TestApexWithJniLibs(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6244,7 +6249,7 @@
}
func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6266,7 +6271,7 @@
}
func TestAppBundle(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6297,7 +6302,7 @@
}
func TestAppSetBundle(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6330,7 +6335,7 @@
}
func TestAppSetBundlePrebuilt(t *testing.T) {
- ctx, _ := testApex(t, "", func(fs map[string][]byte, config android.Config) {
+ ctx := testApex(t, "", func(fs map[string][]byte, config android.Config) {
bp := `
apex_set {
name: "myapex",
@@ -6815,7 +6820,7 @@
}
func TestTestFor(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6901,7 +6906,7 @@
}
func TestApexSet(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_set {
name: "myapex",
set: "myapex.apks",
@@ -6977,7 +6982,7 @@
}
func TestApexKeysTxt(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -7018,7 +7023,7 @@
}
func TestAllowedFiles(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -7074,7 +7079,7 @@
}
func TestNonPreferredPrebuiltDependency(t *testing.T) {
- _, _ = testApex(t, `
+ testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -7110,7 +7115,7 @@
}
func TestCompressedApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -7145,7 +7150,7 @@
}
func TestPreferredPrebuiltSharedLibDep(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -7197,7 +7202,7 @@
}
func TestExcludeDependency(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -7341,7 +7346,7 @@
t.Run(test.name, func(t *testing.T) {
for _, otherApexEnabled := range test.otherApexEnabled {
t.Run("otherapex_enabled_"+otherApexEnabled, func(t *testing.T) {
- ctx, _ := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp)
+ ctx := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp)
type modAndMkEntries struct {
mod *cc.Module
diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go
index ff779e1..2e6ed82 100644
--- a/apex/boot_image_test.go
+++ b/apex/boot_image_test.go
@@ -28,7 +28,7 @@
// modules from the ART apex.
func TestBootImages(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
java_sdk_library {
name: "foo",
srcs: ["b.java"],
@@ -181,7 +181,7 @@
}
func TestBootImageInApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 5e9a11f..34b9408 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -9,7 +9,7 @@
)
func TestVndkApexForVndkLite(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx := testApex(t, `
apex_vndk {
name: "com.android.vndk.current",
key: "com.android.vndk.current.key",
@@ -100,7 +100,7 @@
}
t.Run("VNDK lib doesn't have an apex variant", func(t *testing.T) {
- ctx, _ := testApex(t, bp)
+ ctx := testApex(t, bp)
// libfoo doesn't have apex variants
for _, variant := range ctx.ModuleVariantsForTests("libfoo") {
@@ -113,7 +113,7 @@
})
t.Run("VNDK APEX gathers only vendor variants even if product variants are available", func(t *testing.T) {
- ctx, _ := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
+ ctx := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
// Now product variant is available
config.TestProductVariables.ProductVndkVersion = proptools.StringPtr("current")
})
@@ -123,7 +123,7 @@
})
t.Run("VNDK APEX supports coverage variants", func(t *testing.T) {
- ctx, _ := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
+ ctx := testApex(t, bp, func(fs map[string][]byte, config android.Config) {
config.TestProductVariables.GcovCoverage = proptools.BoolPtr(true)
config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
})
diff --git a/cc/testing.go b/cc/testing.go
index 45e5312..f62c5f1 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -25,7 +25,6 @@
RegisterBinaryBuildComponents(ctx)
RegisterLibraryBuildComponents(ctx)
RegisterLibraryHeadersBuildComponents(ctx)
- genrule.RegisterGenruleBuildComponents(ctx)
ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
ctx.RegisterModuleType("llndk_library", LlndkLibraryFactory)
@@ -591,6 +590,7 @@
func CreateTestContext(config android.Config) *android.TestContext {
ctx := android.NewTestArchContext(config)
+ genrule.RegisterGenruleBuildComponents(ctx)
ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
ctx.RegisterModuleType("cc_test", TestFactory)
ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 3a6feca..d022f49 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -21,6 +21,7 @@
"path/filepath"
"strings"
+ "android/soong/shared"
"github.com/google/blueprint/bootstrap"
"android/soong/android"
@@ -28,11 +29,19 @@
)
var (
+ topDir string
+ outDir string
docFile string
bazelQueryViewDir string
+ delveListen string
+ delvePath string
)
func init() {
+ flag.StringVar(&topDir, "top", "", "Top directory of the Android source tree")
+ flag.StringVar(&outDir, "out", "", "Soong output directory (usually $TOP/out/soong)")
+ flag.StringVar(&delveListen, "delve_listen", "", "Delve port to listen on for debugging")
+ flag.StringVar(&delvePath, "delve_path", "", "Path to Delve. Only used if --delve_listen is set")
flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory")
}
@@ -80,18 +89,23 @@
}
func main() {
- android.ReexecWithDelveMaybe()
flag.Parse()
+ shared.ReexecWithDelveMaybe(delveListen, delvePath)
+ android.InitSandbox(topDir)
+ android.InitEnvironment(shared.JoinPath(topDir, outDir, "soong.environment.available"))
+
// The top-level Blueprints file is passed as the first argument.
srcDir := filepath.Dir(flag.Arg(0))
var ctx *android.Context
configuration := newConfig(srcDir)
extraNinjaDeps := []string{configuration.ProductVariablesFileName}
- // Read the SOONG_DELVE again through configuration so that there is a dependency on the environment variable
- // and soong_build will rerun when it is set for the first time.
- if listen := configuration.Getenv("SOONG_DELVE"); listen != "" {
+ // These two are here so that we restart a non-debugged soong_build when the
+ // user sets SOONG_DELVE the first time.
+ configuration.Getenv("SOONG_DELVE")
+ configuration.Getenv("SOONG_DELVE_PATH")
+ if shared.IsDebugging() {
// Add a non-existent file to the dependencies so that soong_build will rerun when the debugger is
// enabled even if it completed successfully.
extraNinjaDeps = append(extraNinjaDeps, filepath.Join(configuration.BuildDir(), "always_rerun_for_delve"))
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 74ede68..1c5e78a 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -25,6 +25,7 @@
"strings"
"time"
+ "android/soong/shared"
"android/soong/ui/build"
"android/soong/ui/logger"
"android/soong/ui/metrics"
@@ -118,6 +119,8 @@
// Command is the type of soong_ui execution. Only one type of
// execution is specified. The args are specific to the command.
func main() {
+ shared.ReexecWithDelveMaybe(os.Getenv("SOONG_UI_DELVE"), shared.ResolveDelveBinary())
+
buildStarted := time.Now()
c, args, err := getCommand(os.Args)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 737773f..fdb00bd 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -288,12 +288,9 @@
} else {
// Other libraries or APKs for which the exact <uses-library> list is unknown.
- // Pass special class loader context to skip the classpath and collision check.
- // This will get removed once LOCAL_USES_LIBRARIES is enforced.
- // Right now LOCAL_USES_LIBRARIES is opt in, for the case where it's not specified we still default
- // to the &.
+ // We assume the class loader context is empty.
rule.Command().
- Text(`class_loader_context_arg=--class-loader-context=\&`).
+ Text(`class_loader_context_arg=--class-loader-context=PCL[]`).
Text(`stored_class_loader_context_arg=""`)
}
diff --git a/java/aar.go b/java/aar.go
index 602d2c4..554ea67 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -805,14 +805,6 @@
return android.Paths{a.classpathFile}
}
-func (a *AARImport) ImplementationJars() android.Paths {
- return android.Paths{a.classpathFile}
-}
-
-func (a *AARImport) ResourceJars() android.Paths {
- return nil
-}
-
func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
return android.Paths{a.classpathFile}
}
@@ -825,22 +817,10 @@
return nil
}
-func (a *AARImport) AidlIncludeDirs() android.Paths {
- return nil
-}
-
func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
return nil
}
-func (d *AARImport) ExportedPlugins() (android.Paths, []string, bool) {
- return nil, nil, false
-}
-
-func (a *AARImport) SrcJarArgs() ([]string, android.Paths) {
- return nil, nil
-}
-
var _ android.ApexModule = (*AARImport)(nil)
// Implements android.ApexModule
diff --git a/java/android_manifest.go b/java/android_manifest.go
index c76bb2f..b30f3d2 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -91,7 +91,7 @@
if err != nil {
ctx.ModuleErrorf("invalid targetSdkVersion: %s", err)
}
- if UseApiFingerprint(ctx) {
+ if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
deps = append(deps, ApiFingerprintPath(ctx))
}
@@ -100,7 +100,7 @@
if err != nil {
ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
}
- if UseApiFingerprint(ctx) {
+ if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" {
minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String())
deps = append(deps, ApiFingerprintPath(ctx))
}
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index ee7d018..39fb04a 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -146,14 +146,6 @@
return d.headerJars
}
-func (d *DeviceHostConverter) ImplementationJars() android.Paths {
- return d.implementationJars
-}
-
-func (d *DeviceHostConverter) ResourceJars() android.Paths {
- return d.resourceJars
-}
-
func (d *DeviceHostConverter) ImplementationAndResourcesJars() android.Paths {
return d.implementationAndResourceJars
}
@@ -174,14 +166,6 @@
return nil
}
-func (d *DeviceHostConverter) ExportedPlugins() (android.Paths, []string, bool) {
- return nil, nil, false
-}
-
-func (d *DeviceHostConverter) SrcJarArgs() ([]string, android.Paths) {
- return d.srcJarArgs, d.srcJarDeps
-}
-
func (d *DeviceHostConverter) JacocoReportClassesFile() android.Path {
return nil
}
diff --git a/java/java.go b/java/java.go
index e471f0d..9e35835 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2046,13 +2046,6 @@
return j.installFile
}
-func (j *Module) ResourceJars() android.Paths {
- if j.resourceJar == nil {
- return nil
- }
- return android.Paths{j.resourceJar}
-}
-
func (j *Module) ImplementationAndResourcesJars() android.Paths {
if j.implementationAndResourcesJar == nil {
return nil
@@ -2069,17 +2062,6 @@
return j.classLoaderContexts
}
-// ExportedPlugins returns the list of jars needed to run the exported plugins, the list of
-// classes for the plugins, and a boolean for whether turbine needs to be disabled due to plugins
-// that generate APIs.
-func (j *Module) ExportedPlugins() (android.Paths, []string, bool) {
- return j.exportedPluginJars, j.exportedPluginClasses, j.exportedDisableTurbine
-}
-
-func (j *Module) SrcJarArgs() ([]string, android.Paths) {
- return j.srcJarArgs, j.srcJarDeps
-}
-
var _ logtagsProducer = (*Module)(nil)
func (j *Module) logtags() android.Paths {
@@ -2515,6 +2497,11 @@
}
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if j.testProperties.Test_options.Unit_test == nil && ctx.Host() {
+ // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding.
+ defaultUnitTest := !inList("tradefed", j.properties.Static_libs) && !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites) && !inList("robolectric-host-android_all", j.properties.Static_libs) && !inList("robolectric-host-android_all", j.properties.Libs)
+ j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
+ }
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
j.testProperties.Test_suites, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test)
@@ -2675,6 +2662,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
InitJavaModuleMultiTargets(module, android.HostSupported)
+
return module
}
@@ -3046,17 +3034,6 @@
return android.Paths{j.combinedClasspathFile}
}
-func (j *Import) ImplementationJars() android.Paths {
- if j.combinedClasspathFile == nil {
- return nil
- }
- return android.Paths{j.combinedClasspathFile}
-}
-
-func (j *Import) ResourceJars() android.Paths {
- return nil
-}
-
func (j *Import) ImplementationAndResourcesJars() android.Paths {
if j.combinedClasspathFile == nil {
return nil
@@ -3072,22 +3049,10 @@
return nil
}
-func (j *Import) AidlIncludeDirs() android.Paths {
- return j.exportAidlIncludeDirs
-}
-
func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
return j.classLoaderContexts
}
-func (j *Import) ExportedPlugins() (android.Paths, []string, bool) {
- return nil, nil, false
-}
-
-func (j *Import) SrcJarArgs() ([]string, android.Paths) {
- return nil, nil
-}
-
var _ android.ApexModule = (*Import)(nil)
// Implements android.ApexModule
diff --git a/java/java_test.go b/java/java_test.go
index bb51ebc..9112655 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -25,6 +25,7 @@
"strings"
"testing"
+ "android/soong/genrule"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -79,6 +80,8 @@
android.RegisterPrebuiltMutators(ctx)
+ genrule.RegisterGenruleBuildComponents(ctx)
+
// Register module types and mutators from cc needed for JNI testing
cc.RegisterRequiredBuildComponentsForTest(ctx)
diff --git a/java/lint.go b/java/lint.go
index 8272595..50b84dc 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -313,6 +313,7 @@
rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(cacheDir.String()).Flag(homeDir.String())
+ rule.Command().Text("rm -f").Output(html).Output(text).Output(xml)
var annotationsZipPath, apiVersionsXMLPath android.Path
if ctx.Config().AlwaysUsePrebuiltSdks() {
@@ -329,8 +330,7 @@
FlagWithArg("ANDROID_SDK_HOME=", homeDir.String()).
FlagWithInput("SDK_ANNOTATIONS=", annotationsZipPath).
FlagWithInput("LINT_OPTS=-DLINT_API_DATABASE=", apiVersionsXMLPath).
- Tool(android.PathForSource(ctx, "prebuilts/cmdline-tools/tools/bin/lint")).
- Implicit(android.PathForSource(ctx, "prebuilts/cmdline-tools/tools/lib/lint-classpath.jar")).
+ BuiltTool("lint").
Flag("--quiet").
FlagWithInput("--project ", projectXML).
FlagWithInput("--config ", lintXML).
@@ -362,7 +362,7 @@
}
}
- cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")")
+ cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)").Text(")")
rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
@@ -438,13 +438,13 @@
}
ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
+ Rule: android.CpIfChanged,
Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".annotations.zip"),
Output: copiedAnnotationsZipPath(ctx),
})
ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
+ Rule: android.CpIfChanged,
Input: android.OutputFileForModule(ctx, frameworkDocStubs, ".api_versions.xml"),
Output: copiedAPIVersionsXmlPath(ctx),
})
diff --git a/java/robolectric.go b/java/robolectric.go
index 98bb710..00f233e 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -31,13 +31,15 @@
}
var robolectricDefaultLibs = []string{
- "Robolectric_all-target",
"mockito-robolectric-prebuilt",
"truth-prebuilt",
// TODO(ccross): this is not needed at link time
"junitxml",
}
+const robolectricCurrentLib = "Robolectric_all-target"
+const robolectricPrebuiltLibPattern = "platform-robolectric-%s-prebuilt"
+
var (
roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
roboRuntimesTag = dependencyTag{name: "roboRuntimes"}
@@ -57,6 +59,10 @@
// Number of shards to use when running the tests.
Shards *int64
}
+
+ // The version number of a robolectric prebuilt to use from prebuilts/misc/common/robolectric
+ // instead of the one built from source in external/robolectric-shadows.
+ Robolectric_prebuilt_version *string
}
type robolectricTest struct {
@@ -94,6 +100,12 @@
ctx.PropertyErrorf("instrumentation_for", "missing required instrumented module")
}
+ if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
+ ctx.AddVariationDependencies(nil, libTag, fmt.Sprintf(robolectricPrebuiltLibPattern, v))
+ } else {
+ ctx.AddVariationDependencies(nil, libTag, robolectricCurrentLib)
+ }
+
ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
@@ -298,7 +310,11 @@
if t := r.robolectricProperties.Test_options.Timeout; t != nil {
fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
}
- fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
+ if v := String(r.robolectricProperties.Robolectric_prebuilt_version); v != "" {
+ fmt.Fprintf(w, "-include prebuilts/misc/common/robolectric/%s/run_robotests.mk\n", v)
+ } else {
+ fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
+ }
}
// An android_robolectric_test module compiles tests against the Robolectric framework that can run on the local host
diff --git a/java/rro_test.go b/java/rro_test.go
index edbf170..061d9d3 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -20,6 +20,7 @@
"testing"
"android/soong/android"
+ "android/soong/shared"
)
func TestRuntimeResourceOverlay(t *testing.T) {
@@ -105,7 +106,7 @@
// Check device location.
path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
- expectedPath = []string{"/tmp/target/product/test_device/product/overlay"}
+ expectedPath = []string{shared.JoinPath(buildDir, "../target/product/test_device/product/overlay")}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
}
@@ -114,7 +115,7 @@
m = ctx.ModuleForTests("foo_themed", "android_common")
androidMkEntries = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0]
path = androidMkEntries.EntryMap["LOCAL_MODULE_PATH"]
- expectedPath = []string{"/tmp/target/product/test_device/product/overlay/faza"}
+ expectedPath = []string{shared.JoinPath(buildDir, "../target/product/test_device/product/overlay/faza")}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
}
@@ -160,7 +161,7 @@
// Check device location.
path := android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
- expectedPath := []string{"/tmp/target/product/test_device/product/overlay/default_theme"}
+ expectedPath := []string{shared.JoinPath(buildDir, "../target/product/test_device/product/overlay/default_theme")}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_MODULE_PATH value: %q, expected: %q", path, expectedPath)
}
@@ -179,7 +180,7 @@
// Check device location.
path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
- expectedPath = []string{"/tmp/target/product/test_device/system/overlay"}
+ expectedPath = []string{shared.JoinPath(buildDir, "../target/product/test_device/system/overlay")}
if !reflect.DeepEqual(path, expectedPath) {
t.Errorf("Unexpected LOCAL_MODULE_PATH value: %v, expected: %v", path, expectedPath)
}
diff --git a/rust/testing.go b/rust/testing.go
index 1afe27e..9534ab5 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"android/soong/cc"
+ "android/soong/genrule"
)
func GatherRequiredDepsForTest() string {
@@ -211,6 +212,7 @@
ctx := android.NewTestArchContext(config)
android.RegisterPrebuiltMutators(ctx)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ genrule.RegisterGenruleBuildComponents(ctx)
cc.RegisterRequiredBuildComponentsForTest(ctx)
RegisterRequiredBuildComponentsForTest(ctx)
diff --git a/sdk/testing.go b/sdk/testing.go
index 0bbf7f4..7a2540a 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -26,6 +26,7 @@
"android/soong/android"
"android/soong/apex"
"android/soong/cc"
+ "android/soong/genrule"
"android/soong/java"
)
@@ -109,6 +110,9 @@
// from java package
java.RegisterRequiredBuildComponentsForTest(ctx)
+ // from genrule package
+ genrule.RegisterGenruleBuildComponents(ctx)
+
// from cc package
cc.RegisterRequiredBuildComponentsForTest(ctx)
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index fb7ab13..f48f7fb 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -3,6 +3,7 @@
import (
"io/ioutil"
"os"
+ "path"
"path/filepath"
"reflect"
"testing"
@@ -73,7 +74,8 @@
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
- expectedPath := "/tmp/target/product/test_device/data/nativetest64/foo_test"
+ expectedPath := path.Join(buildDir,
+ "../target/product/test_device/data/nativetest64/foo_test")
actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0]
if expectedPath != actualPath {
t.Errorf("Unexpected LOCAL_MODULE_PATH expected: %q, actual: %q", expectedPath, actualPath)
@@ -97,7 +99,8 @@
entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
- expectedPath := "/tmp/target/product/test_device/data/nativetest64/foo"
+ expectedPath := path.Join(buildDir,
+ "../target/product/test_device/data/nativetest64/foo")
actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0]
if expectedPath != actualPath {
t.Errorf("Unexpected LOCAL_MODULE_PATH expected: %q, actual: %q", expectedPath, actualPath)
diff --git a/shared/Android.bp b/shared/Android.bp
index c79bc2b..deb17f8 100644
--- a/shared/Android.bp
+++ b/shared/Android.bp
@@ -8,6 +8,10 @@
srcs: [
"env.go",
"paths.go",
+ "debug.go",
+ ],
+ testSrcs: [
+ "paths_test.go",
],
deps: [
"soong-bazel",
diff --git a/shared/debug.go b/shared/debug.go
new file mode 100644
index 0000000..5392f2b
--- /dev/null
+++ b/shared/debug.go
@@ -0,0 +1,69 @@
+package shared
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+ "syscall"
+)
+
+var (
+ isDebugging bool
+)
+
+// Finds the Delve binary to use. Either uses the SOONG_DELVE_PATH environment
+// variable or if that is unset, looks at $PATH.
+func ResolveDelveBinary() string {
+ result := os.Getenv("SOONG_DELVE_PATH")
+ if result == "" {
+ result, _ = exec.LookPath("dlv")
+ }
+
+ return result
+}
+
+// Returns whether the current process is running under Delve due to
+// ReexecWithDelveMaybe().
+func IsDebugging() bool {
+ return isDebugging
+}
+
+// Re-executes the binary in question under the control of Delve when
+// delveListen is not the empty string. delvePath gives the path to the Delve.
+func ReexecWithDelveMaybe(delveListen, delvePath string) {
+ isDebugging = os.Getenv("SOONG_DELVE_REEXECUTED") == "true"
+ if isDebugging || delveListen == "" {
+ return
+ }
+
+ if delvePath == "" {
+ fmt.Fprintln(os.Stderr, "Delve debugging requested but failed to find dlv")
+ os.Exit(1)
+ }
+
+ soongDelveEnv := []string{}
+ for _, env := range os.Environ() {
+ idx := strings.IndexRune(env, '=')
+ if idx != -1 {
+ soongDelveEnv = append(soongDelveEnv, env)
+ }
+ }
+
+ soongDelveEnv = append(soongDelveEnv, "SOONG_DELVE_REEXECUTED=true")
+
+ dlvArgv := []string{
+ delvePath,
+ "--listen=:" + delveListen,
+ "--headless=true",
+ "--api-version=2",
+ "exec",
+ os.Args[0],
+ "--",
+ }
+
+ dlvArgv = append(dlvArgv, os.Args[1:]...)
+ syscall.Exec(delvePath, dlvArgv, soongDelveEnv)
+ fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve")
+ os.Exit(1)
+}
diff --git a/shared/env.go b/shared/env.go
index 7900daa..152729b 100644
--- a/shared/env.go
+++ b/shared/env.go
@@ -91,6 +91,28 @@
return false, nil
}
+// Deserializes and environment serialized by EnvFileContents() and returns it
+// as a map[string]string.
+func EnvFromFile(envFile string) (map[string]string, error) {
+ result := make(map[string]string)
+ data, err := ioutil.ReadFile(envFile)
+ if err != nil {
+ return result, err
+ }
+
+ var contents envFileData
+ err = json.Unmarshal(data, &contents)
+ if err != nil {
+ return result, err
+ }
+
+ for _, entry := range contents {
+ result[entry.Key] = entry.Value
+ }
+
+ return result, nil
+}
+
// Implements sort.Interface so that we can use sort.Sort on envFileData arrays.
func (e envFileData) Len() int {
return len(e)
diff --git a/shared/paths.go b/shared/paths.go
index 1b9ff60..fca8b4c 100644
--- a/shared/paths.go
+++ b/shared/paths.go
@@ -30,6 +30,21 @@
BazelMetricsDir() string
}
+// Joins the path strings in the argument list, taking absolute paths into
+// account. That is, if one of the strings is an absolute path, the ones before
+// are ignored.
+func JoinPath(base string, rest ...string) string {
+ result := base
+ for _, next := range rest {
+ if filepath.IsAbs(next) {
+ result = next
+ } else {
+ result = filepath.Join(result, next)
+ }
+ }
+ return result
+}
+
// Given the out directory, returns the root of the temp directory (to be cleared at the start of each execution of Soong)
func TempDirForOutDir(outDir string) (tempPath string) {
return filepath.Join(outDir, ".temp")
diff --git a/shared/paths_test.go b/shared/paths_test.go
new file mode 100644
index 0000000..018d55f
--- /dev/null
+++ b/shared/paths_test.go
@@ -0,0 +1,32 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package shared
+
+import (
+ "testing"
+)
+
+func assertEqual(t *testing.T, expected, actual string) {
+ t.Helper()
+ if expected != actual {
+ t.Errorf("expected %q != got %q", expected, actual)
+ }
+}
+
+func TestJoinPath(t *testing.T) {
+ assertEqual(t, "/a/b", JoinPath("c/d", "/a/b"))
+ assertEqual(t, "a/b", JoinPath("a", "b"))
+ assertEqual(t, "/a/b", JoinPath("x", "/a", "b"))
+}
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index b1f8551..6ba497c 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -124,7 +124,7 @@
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 6d8a28f..50d059f 100644
--- a/ui/build/environment.go
+++ b/ui/build/environment.go
@@ -33,6 +33,19 @@
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/soong.go b/ui/build/soong.go
index 125dbcc..c2fa427 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -21,6 +21,7 @@
"strconv"
"android/soong/shared"
+
soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
"github.com/golang/protobuf/proto"
@@ -30,6 +31,15 @@
"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 @@
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 @@
}
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,11 +91,30 @@
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")
+ envFile := filepath.Join(config.SoongOutDir(), "soong.environment.used")
getenv := func(k string) string {
v, _ := config.Environment().Get(k)
return v
@@ -134,14 +170,12 @@
"--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())
+ cmd.Environment.Set("SOONG_OUTDIR", config.SoongOutDir())
+ if os.Getenv("SOONG_DELVE") != "" {
+ // SOONG_DELVE is already in cmd.Environment
+ cmd.Environment.Set("SOONG_DELVE_PATH", shared.ResolveDelveBinary())
+ }
- cmd.Environment.Set("SOONG_SANDBOX_SOONG_BUILD", "true")
cmd.Sandbox = soongSandbox
cmd.RunAndStreamOrFatal()
}
diff --git a/vnames.go.json b/vnames.go.json
index 7ce2d4b..f8c6b7f 100644
--- a/vnames.go.json
+++ b/vnames.go.json
@@ -2,7 +2,6 @@
{
"pattern": "(.*)",
"vname": {
- "corpus": "android.googlesource.com/platform/superproject",
"path": "@1@"
}
}
diff --git a/vnames.json b/vnames.json
index f9d3adc..096260f 100644
--- a/vnames.json
+++ b/vnames.json
@@ -2,7 +2,6 @@
{
"pattern": "out/(.*)",
"vname": {
- "corpus": "android.googlesource.com/platform/superproject",
"root": "out",
"path": "@1@"
}
@@ -10,9 +9,7 @@
{
"pattern": "(.*)",
"vname": {
- "corpus": "android.googlesource.com/platform/superproject",
"path": "@1@"
}
}
]
-