Merge "Remove myself from the OWNERS"
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/env.go b/android/env.go
index a8c7777..58ad0b6 100644
--- a/android/env.go
+++ b/android/env.go
@@ -17,7 +17,6 @@
import (
"fmt"
"os"
- "os/exec"
"strings"
"syscall"
@@ -34,37 +33,27 @@
var originalEnv map[string]string
var soongDelveListen string
var soongDelvePath string
-var soongDelveEnv []string
+var isDebugging bool
-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")
+func InitEnvironment(envFile string) {
+ var err error
+ originalEnv, err = shared.EnvFromFile(envFile)
+ if err != nil {
+ panic(err)
}
- 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()
+ soongDelveListen = originalEnv["SOONG_DELVE"]
+ soongDelvePath = originalEnv["SOONG_DELVE_PATH"]
}
+// Returns whether the current process is running under Delve due to
+// ReexecWithDelveMaybe().
+func IsDebugging() bool {
+ return isDebugging
+}
func ReexecWithDelveMaybe() {
- if soongDelveListen == "" {
+ isDebugging = os.Getenv("SOONG_DELVE_REEXECUTED") == "true"
+ if isDebugging || soongDelveListen == "" {
return
}
@@ -72,6 +61,17 @@
fmt.Fprintln(os.Stderr, "SOONG_DELVE is set 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{
soongDelvePath,
"--listen=:" + soongDelveListen,
@@ -88,17 +88,6 @@
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 EnvSingleton() Singleton {
return &envSingleton{}
}
@@ -108,7 +97,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 0efe329..ae24b91 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -182,7 +182,13 @@
// Create a Fixture.
Fixture(t *testing.T, preparers ...FixturePreparer) Fixture
- // Run the test, expecting no errors, returning a TestResult instance.
+ // Set the error handler that will be used to check any errors reported by the test.
+ //
+ // The default handlers is FixtureExpectsNoErrors which will fail the go test immediately if any
+ // errors are reported.
+ SetErrorHandler(errorHandler FixtureErrorHandler) FixtureFactory
+
+ // Run the test, checking any errors reported and returning a TestResult instance.
//
// Shorthand for Fixture(t, preparers...).RunTest()
RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult
@@ -202,6 +208,9 @@
return &fixtureFactory{
buildDirSupplier: buildDirSupplier,
preparers: dedupAndFlattenPreparers(nil, preparers),
+
+ // Set the default error handler.
+ errorHandler: FixtureExpectsNoErrors,
}
}
@@ -352,9 +361,84 @@
return &simpleFixturePreparer{function: preparer}
}
+// FixtureErrorHandler determines how to respond to errors reported by the code under test.
+//
+// Some possible responses:
+// * Fail the test if any errors are reported, see FixtureExpectsNoErrors.
+// * Fail the test if at least one error that matches a pattern is not reported see
+// FixtureExpectsAtLeastOneErrorMatchingPattern
+// * Fail the test if any unexpected errors are reported.
+//
+// Although at the moment all the error handlers are implemented as simply a wrapper around a
+// function this is defined as an interface to allow future enhancements, e.g. provide different
+// ways other than patterns to match an error and to combine handlers together.
+type FixtureErrorHandler interface {
+ // CheckErrors checks the errors reported.
+ //
+ // 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)
+}
+
+type simpleErrorHandler struct {
+ function func(result *TestResult, errs []error)
+}
+
+func (h simpleErrorHandler) CheckErrors(result *TestResult, errs []error) {
+ h.function(result, errs)
+}
+
+// The default fixture error handler.
+//
+// Will fail the test immediately if any errors are reported.
+var FixtureExpectsNoErrors = FixtureCustomErrorHandler(
+ func(result *TestResult, errs []error) {
+ FailIfErrored(result.T, errs)
+ },
+)
+
+// FixtureExpectsAtLeastOneMatchingError returns an error handler that will cause the test to fail
+// if at least one error that matches the regular expression is not found.
+//
+// The test will be failed if:
+// * No errors are reported.
+// * One or more errors are reported but none match the pattern.
+//
+// The test will not fail if:
+// * Multiple errors are reported that do not match the pattern as long as one does match.
+func FixtureExpectsAtLeastOneErrorMatchingPattern(pattern string) FixtureErrorHandler {
+ return FixtureCustomErrorHandler(func(result *TestResult, errs []error) {
+ FailIfNoMatchingErrors(result.T, pattern, errs)
+ })
+}
+
+// FixtureExpectsOneErrorToMatchPerPattern returns an error handler that will cause the test to fail
+// if there are any unexpected errors.
+//
+// The test will be failed if:
+// * The number of errors reported does not exactly match the patterns.
+// * One or more of the reported errors do not match a pattern.
+// * No patterns are provided and one or more errors are reported.
+//
+// The test will not fail if:
+// * One or more of the patterns does not match an error.
+func FixtureExpectsAllErrorsToMatchAPattern(patterns []string) FixtureErrorHandler {
+ return FixtureCustomErrorHandler(func(result *TestResult, errs []error) {
+ CheckErrorsAgainstExpectations(result.T, errs, patterns)
+ })
+}
+
+// FixtureCustomErrorHandler creates a custom error handler
+func FixtureCustomErrorHandler(function func(result *TestResult, errs []error)) FixtureErrorHandler {
+ return simpleErrorHandler{
+ function: function,
+ }
+}
+
// Fixture defines the test environment.
type Fixture interface {
- // Run the test, expecting no errors, returning a TestResult instance.
+ // Run the test, checking any errors reported and returning a TestResult instance.
RunTest() *TestResult
}
@@ -454,25 +538,29 @@
type fixtureFactory struct {
buildDirSupplier *string
preparers []*simpleFixturePreparer
+ errorHandler FixtureErrorHandler
}
func (f *fixtureFactory) Extend(preparers ...FixturePreparer) FixtureFactory {
all := append(f.preparers, dedupAndFlattenPreparers(f.preparers, preparers)...)
- return &fixtureFactory{
- buildDirSupplier: f.buildDirSupplier,
- preparers: all,
- }
+ // Copy the existing factory.
+ extendedFactory := &fixtureFactory{}
+ *extendedFactory = *f
+ // Use the extended list of preparers.
+ extendedFactory.preparers = all
+ return extendedFactory
}
func (f *fixtureFactory) Fixture(t *testing.T, preparers ...FixturePreparer) Fixture {
config := TestConfig(*f.buildDirSupplier, nil, "", nil)
ctx := NewTestContext(config)
fixture := &fixture{
- factory: f,
- t: t,
- config: config,
- ctx: ctx,
- mockFS: make(MockFS),
+ factory: f,
+ t: t,
+ config: config,
+ ctx: ctx,
+ mockFS: make(MockFS),
+ errorHandler: f.errorHandler,
}
for _, preparer := range f.preparers {
@@ -486,6 +574,11 @@
return fixture
}
+func (f *fixtureFactory) SetErrorHandler(errorHandler FixtureErrorHandler) FixtureFactory {
+ f.errorHandler = errorHandler
+ return f
+}
+
func (f *fixtureFactory) RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult {
t.Helper()
fixture := f.Fixture(t, preparers...)
@@ -498,11 +591,23 @@
}
type fixture struct {
+ // The factory used to create this fixture.
factory *fixtureFactory
- t *testing.T
- config Config
- ctx *TestContext
- mockFS MockFS
+
+ // The gotest state of the go test within which this was created.
+ t *testing.T
+
+ // The configuration prepared for this fixture.
+ config Config
+
+ // The test context prepared for this fixture.
+ ctx *TestContext
+
+ // The mock filesystem prepared for this fixture.
+ mockFS MockFS
+
+ // The error handler used to check the errors, if any, that are reported.
+ errorHandler FixtureErrorHandler
}
func (f *fixture) RunTest() *TestResult {
@@ -525,9 +630,9 @@
ctx.Register()
_, errs := ctx.ParseBlueprintsFiles("ignored")
- FailIfErrored(f.t, errs)
- _, errs = ctx.PrepareBuildActions(f.config)
- FailIfErrored(f.t, errs)
+ if len(errs) == 0 {
+ _, errs = ctx.PrepareBuildActions(f.config)
+ }
result := &TestResult{
TestHelper: TestHelper{T: f.t},
@@ -535,6 +640,9 @@
fixture: f,
Config: f.config,
}
+
+ f.errorHandler.CheckErrors(result, errs)
+
return result
}
diff --git a/android/module.go b/android/module.go
index f0e17ba..9f923e2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -753,7 +753,7 @@
// Whether this module is installed to vendor ramdisk
Vendor_ramdisk *bool
- // Whether this module is built for non-native architecures (also known as native bridge binary)
+ // Whether this module is built for non-native architectures (also known as native bridge binary)
Native_bridge_supported *bool `android:"arch_variant"`
// init.rc files to be installed if this module is installed
@@ -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/package.go b/android/package.go
index 7012fc7..878e4c4 100644
--- a/android/package.go
+++ b/android/package.go
@@ -23,6 +23,8 @@
RegisterPackageBuildComponents(InitRegistrationContext)
}
+var PrepareForTestWithPackageModule = FixtureRegisterWithContext(RegisterPackageBuildComponents)
+
// Register the package module type.
func RegisterPackageBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("package", PackageFactory)
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/prebuilt_test.go b/android/prebuilt_test.go
index 164b1bc..32af5df 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -388,6 +388,8 @@
ctx.PostDepsMutators(RegisterOverridePostDepsMutators)
}
+var prepareForTestWithFakePrebuiltModules = FixtureRegisterWithContext(registerTestPrebuiltModules)
+
func registerTestPrebuiltModules(ctx RegistrationContext) {
ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
ctx.RegisterModuleType("source", newSourceModule)
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/visibility.go b/android/visibility.go
index 7eac471..631e88f 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -202,6 +202,18 @@
ExcludeFromVisibilityEnforcement()
}
+var PrepareForTestWithVisibilityRuleChecker = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.PreArchMutators(RegisterVisibilityRuleChecker)
+})
+
+var PrepareForTestWithVisibilityRuleGatherer = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
+})
+
+var PrepareForTestWithVisibilityRuleEnforcer = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
+})
+
// The rule checker needs to be registered before defaults expansion to correctly check that
// //visibility:xxx isn't combined with other packages in the same list in any one module.
func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
diff --git a/android/visibility_test.go b/android/visibility_test.go
index 87a295e..30cdcbf 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -9,13 +9,13 @@
var visibilityTests = []struct {
name string
- fs map[string][]byte
+ fs MockFS
expectedErrors []string
effectiveVisibility map[qualifiedModuleName][]string
}{
{
name: "invalid visibility: empty list",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -26,7 +26,7 @@
},
{
name: "invalid visibility: empty rule",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -37,7 +37,7 @@
},
{
name: "invalid visibility: unqualified",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -48,7 +48,7 @@
},
{
name: "invalid visibility: empty namespace",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -59,7 +59,7 @@
},
{
name: "invalid visibility: empty module",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -70,7 +70,7 @@
},
{
name: "invalid visibility: empty namespace and module",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -81,7 +81,7 @@
},
{
name: "//visibility:unknown",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -92,7 +92,7 @@
},
{
name: "//visibility:xxx mixed",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -113,7 +113,7 @@
},
{
name: "//visibility:legacy_public",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -129,7 +129,7 @@
// Verify that //visibility:public will allow the module to be referenced from anywhere, e.g.
// the current directory, a nested directory and a directory in a separate tree.
name: "//visibility:public",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -156,7 +156,7 @@
// Verify that //visibility:private allows the module to be referenced from the current
// directory only.
name: "//visibility:private",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -188,7 +188,7 @@
{
// Verify that :__pkg__ allows the module to be referenced from the current directory only.
name: ":__pkg__",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -221,7 +221,7 @@
// Verify that //top/nested allows the module to be referenced from the current directory and
// the top/nested directory only, not a subdirectory of top/nested and not peak directory.
name: "//top/nested",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -259,7 +259,7 @@
// Verify that :__subpackages__ allows the module to be referenced from the current directory
// and sub directories but nowhere else.
name: ":__subpackages__",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -290,7 +290,7 @@
// Verify that //top/nested:__subpackages__ allows the module to be referenced from the current
// directory and sub directories but nowhere else.
name: "//top/nested:__subpackages__",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -321,7 +321,7 @@
// Verify that ["//top/nested", "//peak:__subpackages"] allows the module to be referenced from
// the current directory, top/nested and peak and all its subpackages.
name: `["//top/nested", "//peak:__subpackages__"]`,
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -347,7 +347,7 @@
{
// Verify that //vendor... cannot be used outside vendor apart from //vendor:__subpackages__
name: `//vendor`,
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -381,7 +381,7 @@
{
// Check that visibility is the union of the defaults modules.
name: "defaults union, basic",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -419,7 +419,7 @@
},
{
name: "defaults union, multiple defaults",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults_1",
@@ -460,7 +460,7 @@
},
{
name: "//visibility:public mixed with other in defaults",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -478,7 +478,7 @@
},
{
name: "//visibility:public overriding defaults",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -501,7 +501,7 @@
},
{
name: "//visibility:public mixed with other from different defaults 1",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults_1",
@@ -524,7 +524,7 @@
},
{
name: "//visibility:public mixed with other from different defaults 2",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults_1",
@@ -547,7 +547,7 @@
},
{
name: "//visibility:private in defaults",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -581,7 +581,7 @@
},
{
name: "//visibility:private mixed with other in defaults",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -599,7 +599,7 @@
},
{
name: "//visibility:private overriding defaults",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -618,7 +618,7 @@
},
{
name: "//visibility:private in defaults overridden",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -637,7 +637,7 @@
},
{
name: "//visibility:private override //visibility:public",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -655,7 +655,7 @@
},
{
name: "//visibility:public override //visibility:private",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -673,7 +673,7 @@
},
{
name: "//visibility:override must be first in the list",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_library {
name: "libexample",
@@ -686,7 +686,7 @@
},
{
name: "//visibility:override discards //visibility:private",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -707,7 +707,7 @@
},
{
name: "//visibility:override discards //visibility:public",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -736,7 +736,7 @@
},
{
name: "//visibility:override discards defaults supplied rules",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -765,7 +765,7 @@
},
{
name: "//visibility:override can override //visibility:public with //visibility:private",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -788,7 +788,7 @@
},
{
name: "//visibility:override can override //visibility:private with //visibility:public",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults",
@@ -808,7 +808,7 @@
},
{
name: "//visibility:private mixed with itself",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "libexample_defaults_1",
@@ -838,7 +838,7 @@
// Defaults module's defaults_visibility tests
{
name: "defaults_visibility invalid",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_defaults {
name: "top_defaults",
@@ -851,7 +851,7 @@
},
{
name: "defaults_visibility overrides package default",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:private"],
@@ -871,7 +871,7 @@
// Package default_visibility tests
{
name: "package default_visibility property is checked",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:invalid"],
@@ -882,7 +882,7 @@
{
// This test relies on the default visibility being legacy_public.
name: "package default_visibility property used when no visibility specified",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:private"],
@@ -904,7 +904,7 @@
},
{
name: "package default_visibility public does not override visibility private",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:public"],
@@ -927,7 +927,7 @@
},
{
name: "package default_visibility private does not override visibility public",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:private"],
@@ -946,7 +946,7 @@
},
{
name: "package default_visibility :__subpackages__",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: [":__subpackages__"],
@@ -973,7 +973,7 @@
},
{
name: "package default_visibility inherited to subpackages",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//outsider"],
@@ -1001,7 +1001,7 @@
},
{
name: "package default_visibility inherited to subpackages",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:private"],
@@ -1031,7 +1031,7 @@
},
{
name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
- fs: map[string][]byte{
+ fs: MockFS{
"prebuilts/Blueprints": []byte(`
prebuilt {
name: "module",
@@ -1053,7 +1053,7 @@
},
{
name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
- fs: map[string][]byte{
+ fs: MockFS{
"prebuilts/Blueprints": []byte(`
prebuilt {
name: "module",
@@ -1076,7 +1076,7 @@
},
{
name: "ensure visibility properties are checked for correctness",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_parent {
name: "parent",
@@ -1093,7 +1093,7 @@
},
{
name: "invalid visibility added to child detected during gather phase",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_parent {
name: "parent",
@@ -1115,7 +1115,7 @@
},
{
name: "automatic visibility inheritance enabled",
- fs: map[string][]byte{
+ fs: MockFS{
"top/Blueprints": []byte(`
mock_parent {
name: "parent",
@@ -1142,55 +1142,43 @@
func TestVisibility(t *testing.T) {
for _, test := range visibilityTests {
t.Run(test.name, func(t *testing.T) {
- ctx, errs := testVisibility(buildDir, test.fs)
-
- CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
+ result := emptyTestFixtureFactory.Extend(
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("mock_library", newMockLibraryModule)
+ ctx.RegisterModuleType("mock_parent", newMockParentFactory)
+ ctx.RegisterModuleType("mock_defaults", defaultsFactory)
+ }),
+ prepareForTestWithFakePrebuiltModules,
+ PrepareForTestWithPackageModule,
+ // Order of the following method calls is significant as they register mutators.
+ PrepareForTestWithArchMutator,
+ PrepareForTestWithPrebuilts,
+ PrepareForTestWithOverrides,
+ PrepareForTestWithVisibilityRuleChecker,
+ PrepareForTestWithDefaults,
+ PrepareForTestWithVisibilityRuleGatherer,
+ PrepareForTestWithVisibilityRuleEnforcer,
+ // Add additional files to the mock filesystem
+ test.fs.AddToFixture(),
+ ).
+ SetErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
+ RunTest(t)
if test.effectiveVisibility != nil {
- checkEffectiveVisibility(t, ctx, test.effectiveVisibility)
+ checkEffectiveVisibility(result, test.effectiveVisibility)
}
})
}
}
-func checkEffectiveVisibility(t *testing.T, ctx *TestContext, effectiveVisibility map[qualifiedModuleName][]string) {
+func checkEffectiveVisibility(result *TestResult, effectiveVisibility map[qualifiedModuleName][]string) {
for moduleName, expectedRules := range effectiveVisibility {
- rule := effectiveVisibilityRules(ctx.config, moduleName)
+ rule := effectiveVisibilityRules(result.Config, moduleName)
stringRules := rule.Strings()
- if !reflect.DeepEqual(expectedRules, stringRules) {
- t.Errorf("effective rules mismatch: expected %q, found %q", expectedRules, stringRules)
- }
+ result.AssertDeepEquals("effective rules mismatch", expectedRules, stringRules)
}
}
-func testVisibility(buildDir string, fs map[string][]byte) (*TestContext, []error) {
-
- // Create a new config per test as visibility information is stored in the config.
- config := TestArchConfig(buildDir, nil, "", fs)
-
- ctx := NewTestArchContext(config)
- ctx.RegisterModuleType("mock_library", newMockLibraryModule)
- ctx.RegisterModuleType("mock_parent", newMockParentFactory)
- ctx.RegisterModuleType("mock_defaults", defaultsFactory)
-
- // Order of the following method calls is significant.
- RegisterPackageBuildComponents(ctx)
- registerTestPrebuiltBuildComponents(ctx)
- ctx.PreArchMutators(RegisterVisibilityRuleChecker)
- ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
- ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
- ctx.PostDepsMutators(RegisterVisibilityRuleEnforcer)
- ctx.Register()
-
- _, errs := ctx.ParseBlueprintsFiles(".")
- if len(errs) > 0 {
- return ctx, errs
- }
-
- _, errs = ctx.PrepareBuildActions(config)
- return ctx, errs
-}
-
type mockLibraryProperties struct {
Deps []string
}
diff --git a/android/writedocs.go b/android/writedocs.go
index 91c2318..6417690 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())
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index 78b84f0..476ac4a 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -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))
@@ -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 a4bdc63..8f388c4 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -121,7 +121,7 @@
// Whether this APEX is considered updatable or not. When set to true, this will enforce
// additional rules for making sure that the APEX is truly updatable. To be updatable,
// min_sdk_version should be set as well. This will also disable the size optimizations like
- // symlinking to the system libs. Default is false.
+ // symlinking to the system libs. Default is true.
Updatable *bool
// Whether this APEX is installable to one of the partitions like system, vendor, etc.
@@ -1232,7 +1232,7 @@
// Implements android.ApexBudleDepsInfoIntf
func (a *apexBundle) Updatable() bool {
- return proptools.Bool(a.properties.Updatable)
+ return proptools.BoolDefault(a.properties.Updatable, true)
}
// getCertString returns the name of the cert that should be used to sign this APEX. This is
diff --git a/apex/apex_test.go b/apex/apex_test.go
index a2992df..aa68378 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -144,17 +144,18 @@
bp = bp + java.GatherRequiredDepsForTest()
fs := map[string][]byte{
- "a.java": nil,
- "PrebuiltAppFoo.apk": nil,
- "PrebuiltAppFooPriv.apk": nil,
- "build/make/target/product/security": nil,
- "apex_manifest.json": nil,
- "AndroidManifest.xml": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- "system/sepolicy/apex/myapex.updatable-file_contexts": nil,
- "system/sepolicy/apex/myapex2-file_contexts": nil,
- "system/sepolicy/apex/otherapex-file_contexts": nil,
- "system/sepolicy/apex/com.android.vndk-file_contexts": nil,
+ "a.java": nil,
+ "PrebuiltAppFoo.apk": nil,
+ "PrebuiltAppFooPriv.apk": nil,
+ "build/make/target/product/security": nil,
+ "apex_manifest.json": nil,
+ "AndroidManifest.xml": nil,
+ "system/sepolicy/apex/myapex-file_contexts": nil,
+ "system/sepolicy/apex/myapex.updatable-file_contexts": nil,
+ "system/sepolicy/apex/myapex2-file_contexts": nil,
+ "system/sepolicy/apex/otherapex-file_contexts": nil,
+ "system/sepolicy/apex/com.android.vndk-file_contexts": nil,
+ "system/sepolicy/apex/com.android.vndk.current-file_contexts": nil,
"mylib.cpp": nil,
"mytest.cpp": nil,
"mytest1.cpp": nil,
@@ -377,6 +378,7 @@
"myjar",
"myjar_dex",
],
+ updatable: false,
}
apex {
@@ -477,6 +479,7 @@
binaries: ["foo"],
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
cc_library_shared {
@@ -670,6 +673,7 @@
apps: ["AppFoo"],
rros: ["rro"],
bpfs: ["bpf"],
+ updatable: false,
}
prebuilt_etc {
@@ -738,6 +742,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
}
apex_key {
@@ -761,6 +766,7 @@
key: "myapex.key",
payload_type: "zip",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -810,6 +816,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib", "mylib3"],
+ updatable: false,
}
apex_key {
@@ -1076,6 +1083,7 @@
name: "myapex2",
key: "myapex2.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -1171,6 +1179,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -1233,6 +1242,7 @@
name: "com.android.runtime",
key: "com.android.runtime.key",
native_shared_libs: ["libc"],
+ updatable: false,
}
apex_key {
@@ -1296,6 +1306,7 @@
name: "com.android.runtime",
key: "com.android.runtime.key",
native_shared_libs: ["libc"],
+ updatable: false,
}
apex_key {
@@ -1381,6 +1392,7 @@
key: "myapex.key",
use_vendor: true,
native_shared_libs: ["mylib"],
+ updatable: false,
`+tc.minSdkVersion+`
}
@@ -1446,6 +1458,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
+ updatable: false,
}
apex_key {
@@ -1672,6 +1685,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libx"],
+ updatable: false,
}
apex_key {
@@ -1717,6 +1731,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libx"],
+ updatable: false,
}
apex_key {
@@ -1943,6 +1958,7 @@
name: "myapex",
java_libs: ["myjar"],
key: "myapex.key",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2253,6 +2269,7 @@
binaries: ["mybin"],
prebuilts: ["myetc"],
compile_multilib: "both",
+ updatable: false,
}
apex_key {
@@ -2319,6 +2336,7 @@
},
compile_multilib: "both",
native_bridge_supported: true,
+ updatable: false,
}
apex_key {
@@ -2371,6 +2389,7 @@
key: "myapex.key",
native_shared_libs: ["mylib"],
use_vendor: true,
+ updatable: false,
}
apex_key {
@@ -2439,6 +2458,7 @@
name: "myapex",
key: "myapex.key",
use_vendor: true,
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2457,6 +2477,7 @@
key: "myapex.key",
native_shared_libs: ["mylib"],
use_vendor: true,
+ updatable: false,
}
apex_key {
@@ -2481,6 +2502,7 @@
key: "myapex.key",
binaries: ["mybin"],
vendor: true,
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2512,7 +2534,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"])
@@ -2527,6 +2550,7 @@
binaries: ["mybin"],
vendor: true,
use_vndk_as_stable: true,
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2588,6 +2612,7 @@
name: "myapex",
key: "myapex.key",
prebuilts: ["myfirmware"],
+ updatable: false,
`+tc.additionalProp+`
}
apex_key {
@@ -2616,6 +2641,7 @@
key: "myapex.key",
use_vendor: true,
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -2650,6 +2676,7 @@
key: "myapex.key",
vendor: true,
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -2681,6 +2708,7 @@
key: "myapex.key",
vintf_fragments: ["fragment.xml"],
init_rc: ["init.rc"],
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2709,6 +2737,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -2755,6 +2784,7 @@
certificate: ":myapex.certificate",
native_shared_libs: ["mylib"],
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
cc_library {
@@ -2809,6 +2839,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2827,6 +2858,7 @@
name: "myapex_keytest",
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2849,6 +2881,7 @@
name: "myapex",
key: "myapex.key",
certificate: ":myapex.certificate",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2872,6 +2905,7 @@
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
certificate: ":myapex.certificate",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2894,6 +2928,7 @@
name: "myapex",
key: "myapex.key",
certificate: "testkey",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2913,6 +2948,7 @@
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
certificate: "testkey",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -2937,6 +2973,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib", "mylib2"],
+ updatable: false,
}
apex {
@@ -3064,6 +3101,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -3204,12 +3242,13 @@
func TestVndkApexCurrent(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex",
- key: "myapex.key",
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
+ updatable: false,
}
apex_key {
- name: "myapex.key",
+ name: "com.android.vndk.current.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -3224,7 +3263,7 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
cc_library {
@@ -3238,11 +3277,11 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
`+vndkLibrariesTxtFiles("current"))
- ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
+ ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
"lib/libvndk.so",
"lib/libvndksp.so",
"lib/libc++.so",
@@ -3260,12 +3299,13 @@
func TestVndkApexWithPrebuilt(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex",
- key: "myapex.key",
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
+ updatable: false,
}
apex_key {
- name: "myapex.key",
+ name: "com.android.vndk.current.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -3280,7 +3320,7 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
cc_prebuilt_library_shared {
@@ -3299,15 +3339,14 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
`+vndkLibrariesTxtFiles("current"),
withFiles(map[string][]byte{
"libvndk.so": nil,
"libvndk.arm.so": nil,
}))
-
- ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
+ ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
"lib/libvndk.so",
"lib/libvndk.arm.so",
"lib64/libvndk.so",
@@ -3344,10 +3383,11 @@
func TestVndkApexVersion(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex_v27",
+ name: "com.android.vndk.v27",
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
vndk_version: "27",
+ updatable: false,
}
apex_key {
@@ -3373,7 +3413,7 @@
srcs: ["libvndk27_arm64.so"],
},
},
- apex_available: [ "myapex_v27" ],
+ apex_available: [ "com.android.vndk.v27" ],
}
vndk_prebuilt_shared {
@@ -3402,73 +3442,27 @@
"libvndk27_x86_64.so": nil,
}))
- ensureExactContents(t, ctx, "myapex_v27", "android_common_image", []string{
+ ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common_image", []string{
"lib/libvndk27_arm.so",
"lib64/libvndk27_arm64.so",
"etc/*",
})
}
-func TestVndkApexErrorWithDuplicateVersion(t *testing.T) {
- testApexError(t, `module "myapex_v27.*" .*: vndk_version: 27 is already defined in "myapex_v27.*"`, `
- apex_vndk {
- name: "myapex_v27",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- vndk_version: "27",
- }
- apex_vndk {
- name: "myapex_v27_other",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- vndk_version: "27",
- }
-
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
-
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- }
-
- vndk_prebuilt_shared {
- name: "libvndk",
- version: "27",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- srcs: ["libvndk.so"],
- }
- `, withFiles(map[string][]byte{
- "libvndk.so": nil,
- }))
-}
-
func TestVndkApexNameRule(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex",
+ name: "com.android.vndk.current",
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex_vndk {
- name: "myapex_v28",
+ name: "com.android.vndk.v28",
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
vndk_version: "28",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -3484,20 +3478,21 @@
}
}
- assertApexName("com.android.vndk.vVER", "myapex")
- assertApexName("com.android.vndk.v28", "myapex_v28")
+ assertApexName("com.android.vndk.vVER", "com.android.vndk.current")
+ assertApexName("com.android.vndk.v28", "com.android.vndk.v28")
}
func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex",
- key: "myapex.key",
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex_key {
- name: "myapex.key",
+ name: "com.android.vndk.current.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -3514,11 +3509,12 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
- `+vndkLibrariesTxtFiles("current"), withNativeBridgeEnabled)
+ `+vndkLibrariesTxtFiles("current"),
+ withNativeBridgeEnabled)
- ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
+ ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
"lib/libvndk.so",
"lib64/libvndk.so",
"lib/libc++.so",
@@ -3528,16 +3524,16 @@
}
func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
- testApexError(t, `module "myapex" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
+ testApexError(t, `module "com.android.vndk.current" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
apex_vndk {
- name: "myapex",
- key: "myapex.key",
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
file_contexts: ":myapex-file_contexts",
native_bridge_supported: true,
}
apex_key {
- name: "myapex.key",
+ name: "com.android.vndk.current.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -3561,10 +3557,11 @@
func TestVndkApexWithBinder32(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex_v27",
+ name: "com.android.vndk.v27",
key: "myapex.key",
file_contexts: ":myapex-file_contexts",
vndk_version: "27",
+ updatable: false,
}
apex_key {
@@ -3604,7 +3601,7 @@
srcs: ["libvndk27binder32.so"],
}
},
- apex_available: [ "myapex_v27" ],
+ apex_available: [ "com.android.vndk.v27" ],
}
`+vndkLibrariesTxtFiles("27"),
withFiles(map[string][]byte{
@@ -3620,7 +3617,7 @@
}),
)
- ensureExactContents(t, ctx, "myapex_v27", "android_common_image", []string{
+ ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common_image", []string{
"lib/libvndk27binder32.so",
"etc/*",
})
@@ -3629,13 +3626,14 @@
func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex",
- key: "myapex.key",
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex_key {
- name: "myapex.key",
+ name: "com.android.vndk.current.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -3656,7 +3654,7 @@
"libz.map.txt": nil,
}))
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_image").Rule("apexManifestRule")
+ apexManifestRule := ctx.ModuleForTests("com.android.vndk.current", "android_common_image").Rule("apexManifestRule")
provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"])
ensureListEmpty(t, provideNativeLibs)
}
@@ -3669,6 +3667,7 @@
native_shared_libs: ["lib_nodep"],
compile_multilib: "both",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex {
@@ -3677,6 +3676,7 @@
native_shared_libs: ["lib_dep"],
compile_multilib: "both",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex {
@@ -3685,6 +3685,7 @@
native_shared_libs: ["libfoo"],
compile_multilib: "both",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex {
@@ -3693,6 +3694,7 @@
native_shared_libs: ["lib_dep", "libfoo"],
compile_multilib: "both",
file_contexts: ":myapex-file_contexts",
+ updatable: false,
}
apex_key {
@@ -3772,6 +3774,7 @@
key: "myapex.key",
apex_name: "com.android.myapex",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -3815,6 +3818,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib_common"],
+ updatable: false,
}
apex_key {
@@ -3867,6 +3871,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib_common_test"],
+ updatable: false,
}
apex_key {
@@ -3914,6 +3919,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
multilib: {
first: {
native_shared_libs: ["mylib_common"],
@@ -4004,6 +4010,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
arch: {
arm64: {
native_shared_libs: ["mylib.arm64"],
@@ -4063,6 +4070,7 @@
name: "myapex",
key: "myapex.key",
binaries: ["myscript"],
+ updatable: false,
}
apex_key {
@@ -4102,6 +4110,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
`+tc.propName+`
}
@@ -4134,6 +4143,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
}
apex_key {
@@ -4153,6 +4163,7 @@
name: "myapex",
key: "myapex.key",
file_contexts: "my_own_file_contexts",
+ updatable: false,
}
apex_key {
@@ -4172,6 +4183,7 @@
key: "myapex.key",
product_specific: true,
file_contexts: "product_specific_file_contexts",
+ updatable: false,
}
apex_key {
@@ -4187,6 +4199,7 @@
key: "myapex.key",
product_specific: true,
file_contexts: "product_specific_file_contexts",
+ updatable: false,
}
apex_key {
@@ -4209,6 +4222,7 @@
key: "myapex.key",
product_specific: true,
file_contexts: ":my-file-contexts",
+ updatable: false,
}
apex_key {
@@ -4682,6 +4696,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["libfoo", "libbar"],
+ updatable: false,
}
apex_key {
@@ -4817,6 +4832,7 @@
apex_test {
name: "myapex",
key: "myapex.key",
+ updatable: false,
tests: [
"mytest",
"mytests",
@@ -4928,6 +4944,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -4998,6 +5015,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["myjavaimport"],
+ updatable: false,
}
apex_key {
@@ -5029,6 +5047,7 @@
"AppFoo",
"AppFooPriv",
],
+ updatable: false,
}
apex_key {
@@ -5107,6 +5126,7 @@
"AppFooPrebuilt",
"AppFooPrivPrebuilt",
],
+ updatable: false,
}
apex_key {
@@ -5154,6 +5174,7 @@
apps: [
"AppFoo",
],
+ updatable: false,
}
apex_key {
@@ -5195,6 +5216,7 @@
apps: [
"TesterHelpAppFoo",
],
+ updatable: false,
}
apex_key {
@@ -5225,6 +5247,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
apex_key {
@@ -5237,6 +5260,7 @@
name: "otherapex",
key: "myapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
cc_defaults {
@@ -5259,6 +5283,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
apex_key {
@@ -5271,6 +5296,7 @@
name: "otherapex",
key: "otherapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
apex_key {
@@ -5300,6 +5326,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
apex_key {
@@ -5337,6 +5364,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
apex_key {
@@ -5357,6 +5385,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libfoo", "libbar"],
+ updatable: false,
}
apex_key {
@@ -5396,6 +5425,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libbar", "libbaz"],
+ updatable: false,
}
apex_key {
@@ -5458,6 +5488,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libfoo"],
+ updatable: false,
}
apex_key {
@@ -5493,6 +5524,7 @@
key: "myapex.key",
apps: ["app"],
overrides: ["oldapex"],
+ updatable: false,
}
override_apex {
@@ -5635,6 +5667,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["foo"],
+ updatable: false,
}
apex_key {
@@ -5672,6 +5705,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["foo", "bar"],
+ updatable: false,
}
apex_key {
@@ -5724,6 +5758,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["foo"],
+ updatable: false,
}
apex_key {
@@ -5786,6 +5821,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["foo", "bar"],
+ updatable: false,
}
apex_key {
@@ -5863,6 +5899,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["foo"],
+ updatable: false,
}
apex_key {
@@ -5890,6 +5927,7 @@
key: "myapex.key",
prebuilts: ["myjar-platform-compat-config"],
java_libs: ["myjar"],
+ updatable: false,
}
apex_key {
@@ -5923,6 +5961,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["myjar"],
+ updatable: false,
}
apex_key {
@@ -5948,6 +5987,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -5987,6 +6027,7 @@
key: "myapex.key",
native_shared_libs: ["mylib"],
java_libs: ["myjar"],
+ updatable: false,
}
apex {
@@ -6115,6 +6156,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -6166,6 +6208,7 @@
name: "myapex",
key: "myapex.key",
jni_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -6206,6 +6249,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -6228,6 +6272,7 @@
name: "myapex",
key: "myapex.key",
apps: ["AppFoo"],
+ updatable: false,
}
apex_key {
@@ -6258,6 +6303,7 @@
name: "myapex",
key: "myapex.key",
apps: ["AppSet"],
+ updatable: false,
}
apex_key {
@@ -6364,6 +6410,7 @@
name: "some-non-updatable-apex",
key: "some-non-updatable-apex.key",
java_libs: ["some-non-updatable-apex-lib"],
+ updatable: false,
}
apex_key {
@@ -6487,6 +6534,21 @@
`)
}
+func TestUpdatableDefault_should_set_min_sdk_version(t *testing.T) {
+ testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+}
+
func TestNoUpdatableJarsInBootImage(t *testing.T) {
var err string
var transform func(*dexpreopt.GlobalConfig)
@@ -6701,6 +6763,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["bcp_lib1", "nonbcp_lib2"],
+ updatable: false,
}`,
bootJars: []string{"bcp_lib1"},
modulesPackages: map[string][]string{
@@ -6733,6 +6796,7 @@
name: "myapex",
key: "myapex.key",
java_libs: ["bcp_lib1", "bcp_lib2"],
+ updatable: false,
}
`,
bootJars: []string{"bcp_lib1", "bcp_lib2"},
@@ -6757,6 +6821,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib", "myprivlib"],
+ updatable: false,
}
apex_key {
@@ -6881,6 +6946,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -6916,6 +6982,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ updatable: false,
}
apex_key {
@@ -6958,6 +7025,7 @@
key: "myapex.key",
apps: ["app"],
allowed_files: "allowed.txt",
+ updatable: false,
}
apex_key {
@@ -7012,6 +7080,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -7047,6 +7116,7 @@
name: "myapex",
key: "myapex.key",
compressible: true,
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -7081,6 +7151,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -7132,6 +7203,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
@@ -7181,6 +7253,7 @@
name: "myapex",
key: "myapex.key",
native_shared_libs: ["mylib"],
+ updatable: false,
}
apex_key {
name: "myapex.key",
@@ -7199,6 +7272,7 @@
enabled: %s,
key: "myapex.key",
native_shared_libs: ["stublib"],
+ updatable: false,
}
`
diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go
index 27a1562..ff779e1 100644
--- a/apex/boot_image_test.go
+++ b/apex/boot_image_test.go
@@ -48,6 +48,7 @@
"baz",
"quuz",
],
+ updatable: false,
}
apex_key {
@@ -187,6 +188,7 @@
boot_images: [
"mybootimage",
],
+ updatable: false,
}
apex_key {
diff --git a/apex/vndk.go b/apex/vndk.go
index f4b12b5..75c0fb0 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -17,7 +17,6 @@
import (
"path/filepath"
"strings"
- "sync"
"android/soong/android"
"android/soong/cc"
@@ -60,17 +59,6 @@
Vndk_version *string
}
-var (
- vndkApexListKey = android.NewOnceKey("vndkApexList")
- vndkApexListMutex sync.Mutex
-)
-
-func vndkApexList(config android.Config) map[string]string {
- return config.Once(vndkApexListKey, func() interface{} {
- return map[string]string{}
- }).(map[string]string)
-}
-
func apexVndkMutator(mctx android.TopDownMutatorContext) {
if ab, ok := mctx.Module().(*apexBundle); ok && ab.vndkApex {
if ab.IsNativeBridgeSupported() {
@@ -80,15 +68,6 @@
vndkVersion := ab.vndkVersion(mctx.DeviceConfig())
// Ensure VNDK APEX mount point is formatted as com.android.vndk.v###
ab.properties.Apex_name = proptools.StringPtr(vndkApexNamePrefix + vndkVersion)
-
- // vndk_version should be unique
- vndkApexListMutex.Lock()
- defer vndkApexListMutex.Unlock()
- vndkApexList := vndkApexList(mctx.Config())
- if other, ok := vndkApexList[vndkVersion]; ok {
- mctx.PropertyErrorf("vndk_version", "%v is already defined in %q", vndkVersion, other)
- }
- vndkApexList[vndkVersion] = mctx.ModuleName()
}
}
@@ -99,9 +78,16 @@
if vndkVersion == "" {
vndkVersion = mctx.DeviceConfig().PlatformVndkVersion()
}
- vndkApexList := vndkApexList(mctx.Config())
- if vndkApex, ok := vndkApexList[vndkVersion]; ok {
- mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApex)
+ if vndkVersion == mctx.DeviceConfig().PlatformVndkVersion() {
+ vndkVersion = "current"
+ } else {
+ vndkVersion = "v" + vndkVersion
+ }
+
+ vndkApexName := "com.android.vndk." + vndkVersion
+
+ if mctx.OtherModuleExists(vndkApexName) {
+ mctx.AddReverseDependency(mctx.Module(), sharedLibTag, vndkApexName)
}
} else if a, ok := mctx.Module().(*apexBundle); ok && a.vndkApex {
vndkVersion := proptools.StringDefault(a.vndkProperties.Vndk_version, "current")
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index ccf4e57..5e9a11f 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -11,12 +11,13 @@
func TestVndkApexForVndkLite(t *testing.T) {
ctx, _ := testApex(t, `
apex_vndk {
- name: "myapex",
- key: "myapex.key",
+ name: "com.android.vndk.current",
+ key: "com.android.vndk.current.key",
+ updatable: false,
}
apex_key {
- name: "myapex.key",
+ name: "com.android.vndk.current.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -31,7 +32,7 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
cc_library {
@@ -45,13 +46,13 @@
},
system_shared_libs: [],
stl: "none",
- apex_available: [ "myapex" ],
+ apex_available: [ "com.android.vndk.current" ],
}
`+vndkLibrariesTxtFiles("current"), func(fs map[string][]byte, config android.Config) {
config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("")
})
// VNDK-Lite contains only core variants of VNDK-Sp libraries
- ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
+ ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
"lib/libvndksp.so",
"lib/libc++.so",
"lib64/libvndksp.so",
@@ -67,8 +68,9 @@
func TestVndkApexUsesVendorVariant(t *testing.T) {
bp := `
apex_vndk {
- name: "myapex",
+ name: "com.android.vndk.current",
key: "mykey",
+ updatable: false,
}
apex_key {
name: "mykey",
@@ -94,7 +96,7 @@
return
}
}
- t.Fail()
+ t.Errorf("expected path %q not found", path)
}
t.Run("VNDK lib doesn't have an apex variant", func(t *testing.T) {
@@ -106,7 +108,7 @@
}
// VNDK APEX doesn't create apex variant
- files := getFiles(t, ctx, "myapex", "android_common_image")
+ files := getFiles(t, ctx, "com.android.vndk.current", "android_common_image")
ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.VER_arm_armv7-a-neon_shared/libfoo.so")
})
@@ -116,7 +118,7 @@
config.TestProductVariables.ProductVndkVersion = proptools.StringPtr("current")
})
- files := getFiles(t, ctx, "myapex", "android_common_image")
+ files := getFiles(t, ctx, "com.android.vndk.current", "android_common_image")
ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.VER_arm_armv7-a-neon_shared/libfoo.so")
})
@@ -126,10 +128,10 @@
config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
})
- files := getFiles(t, ctx, "myapex", "android_common_image")
+ files := getFiles(t, ctx, "com.android.vndk.current", "android_common_image")
ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.VER_arm_armv7-a-neon_shared/libfoo.so")
- files = getFiles(t, ctx, "myapex", "android_common_cov_image")
+ files = getFiles(t, ctx, "com.android.vndk.current", "android_common_cov_image")
ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.VER_arm_armv7-a-neon_shared_cov/libfoo.so")
})
}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 3a6feca..e7f995f 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,15 @@
)
var (
+ topDir string
+ outDir string
docFile string
bazelQueryViewDir 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(&docFile, "soong_docs", "", "build documentation file to output")
flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory")
}
@@ -80,15 +85,22 @@
}
func main() {
- android.ReexecWithDelveMaybe()
flag.Parse()
+ android.InitSandbox(topDir)
+ android.InitEnvironment(shared.JoinPath(topDir, outDir, "soong.environment.available"))
+ android.ReexecWithDelveMaybe()
+
// 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}
+ // 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")
// 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 != "" {
diff --git a/java/java.go b/java/java.go
index e471f0d..b5988fc 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2515,6 +2515,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 +2680,7 @@
module.Module.properties.Installable = proptools.BoolPtr(true)
InitJavaModuleMultiTargets(module, android.HostSupported)
+
return module
}
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/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 997d2f6..3591777 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -251,6 +251,7 @@
uses_sdks: ["mysdk@1"],
key: "myapex.key",
certificate: ":myapex.cert",
+ updatable: false,
}
apex {
@@ -259,6 +260,7 @@
uses_sdks: ["mysdk@2"],
key: "myapex.key",
certificate: ":myapex.cert",
+ updatable: false,
}
apex {
@@ -266,6 +268,7 @@
native_shared_libs: ["sdkmember"],
key: "myapex.key",
certificate: ":myapex.cert",
+ updatable: false,
}
`)
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 17a6ca9..111b22c 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -211,6 +211,7 @@
uses_sdks: ["mysdk@1"],
key: "myapex.key",
certificate: ":myapex.cert",
+ updatable: false,
}
apex {
@@ -219,6 +220,7 @@
uses_sdks: ["mysdk@2"],
key: "myapex.key",
certificate: ":myapex.cert",
+ updatable: false,
}
`)
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..0c9ba4f
--- /dev/null
+++ b/shared/debug.go
@@ -0,0 +1,17 @@
+package shared
+
+import (
+ "os"
+ "os/exec"
+)
+
+// 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
+}
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/paths/logs_test.go b/ui/build/paths/logs_test.go
index 3b1005f..067f3f3 100644
--- a/ui/build/paths/logs_test.go
+++ b/ui/build/paths/logs_test.go
@@ -26,6 +26,9 @@
)
func TestSendLog(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in short mode, sometimes hangs")
+ }
t.Run("Short name", func(t *testing.T) {
d, err := ioutil.TempDir("", "s")
if err != nil {
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 125dbcc..fc43663 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,32 @@
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())
+
+ if os.Getenv("SOONG_DELVE") != "" {
+ // SOONG_DELVE is already in cmd.Environment
+ soongBuildEnv.Set("SOONG_DELVE_PATH", shared.ResolveDelveBinary())
+ }
+
+ writeEnvironmentFile(ctx, envFile, soongBuildEnv.AsMap())
+
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 +172,7 @@
"--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_SANDBOX_SOONG_BUILD", "true")
+ cmd.Environment.Set("SOONG_OUTDIR", config.SoongOutDir())
cmd.Sandbox = soongSandbox
cmd.RunAndStreamOrFatal()
}