Merge "Add min_sdk_version to java_import."
diff --git a/android/bazel.go b/android/bazel.go
index cc02152..51ff3cb 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -130,48 +130,48 @@
// Per-module denylist to always opt modules out.
bp2buildModuleDoNotConvertList = []string{
- "generated_android_ids",
- "libBionicBenchmarksUtils",
- "libbionic_spawn_benchmark",
- "libc_jemalloc_wrapper",
- "libc_bootstrap",
- "libc_init_static",
- "libc_init_dynamic",
- "libc_tzcode",
- "libc_freebsd",
- "libc_freebsd_large_stack",
- "libc_netbsd",
- "libc_openbsd_ndk",
- "libc_openbsd_large_stack",
- "libc_openbsd",
- "libc_gdtoa",
- "libc_fortify",
- "libc_bionic",
- "libc_bionic_ndk",
- "libc_bionic_systrace",
- "libc_pthread",
- "libc_syscalls",
- "libc_aeabi",
- "libc_ndk",
- "libc_nopthread",
- "libc_common",
- "libc_static_dispatch",
- "libc_dynamic_dispatch",
- "libc_common_static",
- "libc_common_shared",
- "libc_unwind_static",
- "libc_nomalloc",
- "libasync_safe",
- "libc_malloc_debug_backtrace",
- "libsystemproperties",
- "libdl_static",
- "liblinker_main",
- "liblinker_malloc",
- "liblinker_debuggerd_stub",
- "libbionic_tests_headers_posix",
- "libc_dns",
- "note_memtag_heap_async",
- "note_memtag_heap_sync",
+ "libBionicBenchmarksUtils", // ruperts@, cc_library_static
+ "libbionic_spawn_benchmark", // ruperts@, cc_library_static, depends on //system/libbase
+ "libc_jemalloc_wrapper", // ruperts@, cc_library_static, depends on //external/jemalloc_new
+ "libc_bootstrap", // ruperts@, cc_library_static
+ "libc_init_static", // ruperts@, cc_library_static
+ "libc_init_dynamic", // ruperts@, cc_library_static
+ "libc_tzcode", // ruperts@, cc_library_static
+ "libc_freebsd", // ruperts@, cc_library_static
+ "libc_freebsd_large_stack", // ruperts@, cc_library_static
+ "libc_netbsd", // ruperts@, cc_library_static
+ "libc_openbsd_ndk", // ruperts@, cc_library_static
+ "libc_openbsd_large_stack", // ruperts@, cc_library_static
+ "libc_openbsd", // ruperts@, cc_library_static
+ "libc_gdtoa", // ruperts@, cc_library_static
+ "libc_fortify", // ruperts@, cc_library_static
+ "libc_bionic", // ruperts@, cc_library_static
+ "libc_bionic_ndk", // ruperts@, cc_library_static, depends on //bionic/libc/system_properties
+ "libc_bionic_systrace", // ruperts@, cc_library_static
+ "libc_pthread", // ruperts@, cc_library_static
+ "libc_syscalls", // ruperts@, cc_library_static
+ "libc_aeabi", // ruperts@, cc_library_static
+ "libc_ndk", // ruperts@, cc_library_static, depends on //bionic/libm:libm
+ "libc_nopthread", // ruperts@, cc_library_static, depends on //external/arm-optimized-routines
+ "libc_common", // ruperts@, cc_library_static, depends on //bionic/libc:libc_nopthread
+ "libc_static_dispatch", // ruperts@, cc_library_static
+ "libc_dynamic_dispatch", // ruperts@, cc_library_static
+ "libc_common_static", // ruperts@, cc_library_static, depends on //bionic/libc:libc_common
+ "libc_common_shared", // ruperts@, cc_library_static, depends on //bionic/libc:libc_common
+ "libc_unwind_static", // ruperts@, cc_library_static
+ "libc_nomalloc", // ruperts@, cc_library_static, depends on //bionic/libc:libc_common
+ "libasync_safe", // ruperts@, cc_library_static
+ "libc_malloc_debug_backtrace", // ruperts@, cc_library_static, depends on //system/libbase
+ "libsystemproperties", // ruperts@, cc_library_static, depends on //system/core/property_service/libpropertyinfoparser
+ "libdl_static", // ruperts@, cc_library_static
+ "liblinker_main", // ruperts@, cc_library_static, depends on //system/libbase
+ "liblinker_malloc", // ruperts@, cc_library_static, depends on //system/logging/liblog:liblog
+ "liblinker_debuggerd_stub", // ruperts@, cc_library_static, depends on //system/libbase
+ "libbionic_tests_headers_posix", // ruperts@, cc_library_static
+ "libc_dns", // ruperts@, cc_library_static
+ "generated_android_ids", // cparsons@, genrule
+ "note_memtag_heap_async", // cparsons@, cc_library_static
+ "note_memtag_heap_sync", // cparsons@, cc_library_static
}
// Used for quicker lookups
diff --git a/android/fixture.go b/android/fixture.go
index 303c95c..5fc668a 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -26,16 +26,9 @@
// Fixture
// =======
// These determine the environment within which a test can be run. Fixtures are mutable and are
-// created by FixtureFactory instances and mutated by FixturePreparer instances. They are created by
-// first creating a base Fixture (which is essentially empty) and then applying FixturePreparer
-// instances to it to modify the environment.
-//
-// FixtureFactory (deprecated)
-// ===========================
-// These are responsible for creating fixtures. Factories are immutable and are intended to be
-// initialized once and reused to create multiple fixtures. Each factory has a list of fixture
-// preparers that prepare a fixture for running a test. Factories can also be used to create other
-// factories by extending them with additional fixture preparers.
+// created and mutated by FixturePreparer instances. They are created by first creating a base
+// Fixture (which is essentially empty) and then applying FixturePreparer instances to it to modify
+// the environment.
//
// FixturePreparer
// ===============
@@ -169,77 +162,6 @@
// PrepareForApex,
// )
//
-// // FixtureFactory instances have been deprecated, this remains for informational purposes to
-// // help explain some of the existing code but will be removed along with FixtureFactory.
-//
-// var javaFixtureFactory = android.NewFixtureFactory(
-// PrepareForIntegrationTestWithJava,
-// FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
-// ctx.RegisterModuleType("test_module", testModule)
-// }),
-// javaMockFS.AddToFixture(),
-// ...
-// }
-//
-// func TestJavaStuff(t *testing.T) {
-// result := javaFixtureFactory.RunTest(t,
-// android.FixtureWithRootAndroidBp(`java_library {....}`),
-// android.MockFS{...}.AddToFixture(),
-// )
-// ... test result ...
-// }
-//
-// package cc
-// var PrepareForTestWithCC = GroupFixturePreparers(
-// android.PrepareForArchMutator,
-// android.prepareForPrebuilts,
-// FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
-// ...
-// )
-//
-// package apex
-//
-// var PrepareForApex = GroupFixturePreparers(
-// ...
-// )
-//
-// Use modules and mutators from java, cc and apex. Any duplicate preparers (like
-// android.PrepareForArchMutator) will be automatically deduped.
-//
-// var apexFixtureFactory = android.NewFixtureFactory(
-// PrepareForJava,
-// PrepareForCC,
-// PrepareForApex,
-// )
-
-// Factory for Fixture objects.
-//
-// This is configured with a set of FixturePreparer objects that are used to
-// initialize each Fixture instance this creates.
-//
-// deprecated: Use FixturePreparer instead.
-type FixtureFactory interface {
- FixturePreparer
-}
-
-// Create a new FixtureFactory that will apply the supplied preparers.
-//
-// The buildDirSupplier is a pointer to the package level buildDir variable that is initialized by
-// the package level setUp method. It has to be a pointer to the variable as the variable will not
-// have been initialized at the time the factory is created. If it is nil then a test specific
-// temporary directory will be created instead.
-//
-// deprecated: The functionality provided by FixtureFactory will be merged into FixturePreparer
-func NewFixtureFactory(buildDirSupplier *string, preparers ...FixturePreparer) FixtureFactory {
- f := &fixtureFactory{
- buildDirSupplier: buildDirSupplier,
- compositeFixturePreparer: compositeFixturePreparer{
- preparers: dedupAndFlattenPreparers(nil, preparers),
- },
- }
- f.initBaseFixturePreparer(f)
- return f
-}
// A set of mock files to add to the mock file system.
type MockFS map[string][]byte
@@ -445,15 +367,6 @@
// Return the flattened and deduped list of simpleFixturePreparer pointers.
list() []*simpleFixturePreparer
- // Creates a copy of this instance and adds some additional preparers.
- //
- // Before the preparers are used they are combined with the preparers provided when the factory
- // was created, any groups of preparers are flattened, and the list is deduped so that each
- // preparer is only used once. See the file documentation in android/fixture.go for more details.
- //
- // deprecated: Use GroupFixturePreparers() instead.
- Extend(preparers ...FixturePreparer) FixturePreparer
-
// Create a Fixture.
Fixture(t *testing.T) Fixture
@@ -734,17 +647,12 @@
b.self = self
}
-func (b *baseFixturePreparer) Extend(preparers ...FixturePreparer) FixturePreparer {
- all := dedupAndFlattenPreparers(b.self.list(), preparers)
- return newFixturePreparer(all)
-}
-
func (b *baseFixturePreparer) Fixture(t *testing.T) Fixture {
return createFixture(t, t.TempDir(), b.self.list())
}
func (b *baseFixturePreparer) ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixturePreparer {
- return b.self.Extend(newSimpleFixturePreparer(func(fixture *fixture) {
+ return GroupFixturePreparers(b.self, newSimpleFixturePreparer(func(fixture *fixture) {
fixture.errorHandler = errorHandler
}))
}
@@ -782,46 +690,6 @@
return fixture.RunTest()
}
-var _ FixtureFactory = (*fixtureFactory)(nil)
-
-type fixtureFactory struct {
- compositeFixturePreparer
-
- buildDirSupplier *string
-}
-
-// Override to preserve the buildDirSupplier.
-func (f *fixtureFactory) Extend(preparers ...FixturePreparer) FixturePreparer {
- // If there is no buildDirSupplier then just use the default implementation.
- if f.buildDirSupplier == nil {
- return f.baseFixturePreparer.Extend(preparers...)
- }
-
- all := dedupAndFlattenPreparers(f.preparers, preparers)
-
- // Create a new factory which uses the same buildDirSupplier as the previous one.
- extendedFactory := &fixtureFactory{
- buildDirSupplier: f.buildDirSupplier,
- compositeFixturePreparer: compositeFixturePreparer{
- preparers: all,
- },
- }
- extendedFactory.initBaseFixturePreparer(extendedFactory)
- return extendedFactory
-}
-
-func (f *fixtureFactory) Fixture(t *testing.T) Fixture {
- // If there is no buildDirSupplier then just use the default implementation.
- if f.buildDirSupplier == nil {
- return f.baseFixturePreparer.Fixture(t)
- }
-
- // Retrieve the buildDir from the supplier.
- buildDir := *f.buildDirSupplier
-
- return createFixture(t, buildDir, f.preparers)
-}
-
type fixture struct {
// The preparers used to create this fixture.
preparers []*simpleFixturePreparer
@@ -936,10 +804,10 @@
// that produced this result.
//
// e.g. assuming that this result was created by running:
-// factory.Extend(preparer1, preparer2).RunTest(t, preparer3, preparer4)
+// GroupFixturePreparers(preparer1, preparer2, preparer3).RunTest(t)
//
// Then this method will be equivalent to running:
-// GroupFixturePreparers(preparer1, preparer2, preparer3, preparer4)
+// GroupFixturePreparers(preparer1, preparer2, preparer3)
//
// This is intended for use by tests whose output is Android.bp files to verify that those files
// are valid, e.g. tests of the snapshots produced by the sdk module type.
diff --git a/android/fixture_test.go b/android/fixture_test.go
index 8f04715..5b810e0 100644
--- a/android/fixture_test.go
+++ b/android/fixture_test.go
@@ -41,7 +41,7 @@
group := GroupFixturePreparers(preparer1, preparer2, preparer1, preparer1Then2)
- extension := group.Extend(preparer4, preparer2)
+ extension := GroupFixturePreparers(group, preparer4, preparer2)
GroupFixturePreparers(extension, preparer1, preparer2, preparer2Then1, preparer3).Fixture(t)
diff --git a/android/mutator.go b/android/mutator.go
index a06e0ee..e25e2e8 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -202,7 +202,7 @@
RegisterPrebuiltsPostDepsMutators,
RegisterVisibilityRuleEnforcer,
RegisterLicensesDependencyChecker,
- RegisterNeverallowMutator,
+ registerNeverallowMutator,
RegisterOverridePostDepsMutators,
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 7455e6a..a385bbc 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -42,7 +42,7 @@
// counts as a match
// - it has none of the "Without" properties matched (same rules as above)
-func RegisterNeverallowMutator(ctx RegisterMutatorsContext) {
+func registerNeverallowMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("neverallow", neverallowMutator).Parallel()
}
@@ -661,6 +661,22 @@
// Overrides the default neverallow rules for the supplied config.
//
// For testing only.
-func SetTestNeverallowRules(config Config, testRules []Rule) {
+func setTestNeverallowRules(config Config, testRules []Rule) {
config.Once(neverallowRulesKey, func() interface{} { return testRules })
}
+
+// Prepares for a test by setting neverallow rules and enabling the mutator.
+//
+// If the supplied rules are nil then the default rules are used.
+func PrepareForTestWithNeverallowRules(testRules []Rule) FixturePreparer {
+ return GroupFixturePreparers(
+ FixtureModifyConfig(func(config Config) {
+ if testRules != nil {
+ setTestNeverallowRules(config, testRules)
+ }
+ }),
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.PostDepsMutators(registerNeverallowMutator)
+ }),
+ )
+}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index de0197a..268346a 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -292,7 +292,6 @@
ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
- ctx.PostDepsMutators(RegisterNeverallowMutator)
}),
)
@@ -301,12 +300,7 @@
t.Run(test.name, func(t *testing.T) {
GroupFixturePreparers(
prepareForNeverAllowTest,
- FixtureModifyConfig(func(config Config) {
- // If the test has its own rules then use them instead of the default ones.
- if test.rules != nil {
- SetTestNeverallowRules(config, test.rules)
- }
- }),
+ PrepareForTestWithNeverallowRules(test.rules),
test.fs.AddToFixture(),
).
ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
diff --git a/apex/apex_test.go b/apex/apex_test.go
index a220a06..98b40fd 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -22,6 +22,7 @@
"reflect"
"regexp"
"sort"
+ "strconv"
"strings"
"testing"
@@ -49,18 +50,28 @@
func testApexError(t *testing.T, pattern, bp string, preparers ...android.FixturePreparer) {
t.Helper()
- apexFixtureFactory.Extend(preparers...).
+ android.GroupFixturePreparers(
+ prepareForApexTest,
+ android.GroupFixturePreparers(preparers...),
+ ).
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
RunTestWithBp(t, bp)
}
func testApex(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext {
t.Helper()
- factory := apexFixtureFactory.Extend(preparers...)
+
+ optionalBpPreparer := android.NullFixturePreparer
if bp != "" {
- factory = factory.Extend(android.FixtureWithRootAndroidBp(bp))
+ optionalBpPreparer = android.FixtureWithRootAndroidBp(bp)
}
- result := factory.RunTest(t)
+
+ result := android.GroupFixturePreparers(
+ prepareForApexTest,
+ android.GroupFixturePreparers(preparers...),
+ optionalBpPreparer,
+ ).RunTest(t)
+
return result.TestContext
}
@@ -114,8 +125,16 @@
},
)
-var apexFixtureFactory = android.NewFixtureFactory(
- nil,
+// Legacy preparer used for running tests within the apex package.
+//
+// This includes everything that was needed to run any test in the apex package prior to the
+// introduction of the test fixtures. Tests that are being converted to use fixtures directly
+// rather than through the testApex...() methods should avoid using this and instead use the
+// various preparers directly, using android.GroupFixturePreparers(...) to group them when
+// necessary.
+//
+// deprecated
+var prepareForApexTest = android.GroupFixturePreparers(
// General preparers in alphabetical order as test infrastructure will enforce correct
// registration order.
android.PrepareForTestWithAndroidBuildComponents,
@@ -801,7 +820,7 @@
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with the latest version of stubs for mylib2
- ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3/mylib2.so")
+ ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
@@ -1279,15 +1298,15 @@
name: "unspecified version links to the latest",
minSdkVersion: "",
apexVariant: "apex10000",
- shouldLink: "30",
- shouldNotLink: []string{"29"},
+ shouldLink: "current",
+ shouldNotLink: []string{"29", "30"},
},
{
name: "always use the latest",
minSdkVersion: "min_sdk_version: \"29\",",
apexVariant: "apex29",
- shouldLink: "30",
- shouldNotLink: []string{"29"},
+ shouldLink: "current",
+ shouldNotLink: []string{"29", "30"},
},
}
for _, tc := range testcases {
@@ -1354,7 +1373,11 @@
}
mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
+ ver := tc.shouldLink
+ if tc.shouldLink == "current" {
+ ver = strconv.Itoa(android.FutureApiLevelInt)
+ }
+ ensureContains(t, mylibCFlags, "__LIBBAR_API__="+ver)
})
}
}
@@ -1416,12 +1439,12 @@
// For dependency to libc
// Ensure that mylib is linking with the latest version of stubs
- ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29/libc.so")
+ ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_current/libc.so")
// ... and not linking to the non-stub (impl) variant
ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared/libc.so")
// ... Cflags from stub is correctly exported to mylib
- ensureContains(t, mylibCFlags, "__LIBC_API__=29")
- ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29")
+ ensureContains(t, mylibCFlags, "__LIBC_API__=10000")
+ ensureContains(t, mylibSharedCFlags, "__LIBC_API__=10000")
// For dependency to libm
// Ensure that mylib is linking with the non-stub (impl) variant
@@ -1527,12 +1550,14 @@
}
// platform liba is linked to non-stub version
expectLink("liba", "shared", "libz", "shared")
- // liba in myapex is linked to #30
- expectLink("liba", "shared_apex29", "libz", "shared_30")
+ // liba in myapex is linked to current
+ expectLink("liba", "shared_apex29", "libz", "shared_current")
+ expectNoLink("liba", "shared_apex29", "libz", "shared_30")
expectNoLink("liba", "shared_apex29", "libz", "shared_28")
expectNoLink("liba", "shared_apex29", "libz", "shared")
- // liba in otherapex is linked to #30
- expectLink("liba", "shared_apex30", "libz", "shared_30")
+ // liba in otherapex is linked to current
+ expectLink("liba", "shared_apex30", "libz", "shared_current")
+ expectNoLink("liba", "shared_apex30", "libz", "shared_30")
expectNoLink("liba", "shared_apex30", "libz", "shared_28")
expectNoLink("liba", "shared_apex30", "libz", "shared")
}
@@ -1583,7 +1608,8 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_apex10000", "libz", "shared_R")
+ expectLink("libx", "shared_apex10000", "libz", "shared_current")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared_R")
expectNoLink("libx", "shared_apex10000", "libz", "shared_29")
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
@@ -1629,8 +1655,9 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_apex10000", "libz", "shared_2")
+ expectLink("libx", "shared_apex10000", "libz", "shared_current")
expectNoLink("libx", "shared_apex10000", "libz", "shared_1")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared_2")
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
@@ -1677,7 +1704,8 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libz", "shared", "libx", "shared_2")
+ expectLink("libz", "shared", "libx", "shared_current")
+ expectNoLink("libz", "shared", "libx", "shared_2")
expectNoLink("libz", "shared", "libz", "shared_1")
expectNoLink("libz", "shared", "libz", "shared")
}
@@ -1724,7 +1752,7 @@
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_30")
+ expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current")
}
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
@@ -2106,7 +2134,7 @@
private_key: "testkey.pem",
}
- // mylib in myapex will link to mylib2#30
+ // mylib in myapex will link to mylib2#current
// mylib in otherapex will link to mylib2(non-stub) in otherapex as well
cc_library {
name: "mylib",
@@ -2140,7 +2168,7 @@
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("mylib", "shared_apex29", "mylib2", "shared_30")
+ expectLink("mylib", "shared_apex29", "mylib2", "shared_current")
expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30")
}
@@ -2208,10 +2236,10 @@
}
`, withSAsActiveCodeNames)
- // ensure libfoo is linked with "S" version of libbar stub
+ // ensure libfoo is linked with current version of libbar stub
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000")
libFlags := libfoo.Rule("ld").Args["libFlags"]
- ensureContains(t, libFlags, "android_arm64_armv8-a_shared_T/libbar.so")
+ ensureContains(t, libFlags, "android_arm64_armv8-a_shared_current/libbar.so")
}
func TestFilesInSubDir(t *testing.T) {
@@ -4513,14 +4541,11 @@
if filepath.Base(output) == base {
foundLibfooJar = true
buildRule := s.Output(output)
- actual := android.NormalizePathForTesting(buildRule.Input)
- if actual != bootDexJarPath {
- t.Errorf("Incorrect boot dex jar path '%s', expected '%s'", actual, bootDexJarPath)
- }
+ android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String())
}
}
if !foundLibfooJar {
- t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs")
+ t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().BuildDir(), s.AllOutputs()))
}
}
@@ -4562,8 +4587,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -4669,8 +4694,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -4736,8 +4761,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -4805,8 +4830,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -5912,9 +5937,10 @@
}
func TestCompatConfig(t *testing.T) {
- result := apexFixtureFactory.
- Extend(java.PrepareForTestWithPlatformCompatConfig).
- RunTestWithBp(t, `
+ result := android.GroupFixturePreparers(
+ prepareForApexTest,
+ java.PrepareForTestWithPlatformCompatConfig,
+ ).RunTestWithBp(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6457,68 +6483,46 @@
func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) *android.TestContext {
t.Helper()
- bp += cc.GatherRequiredDepsForTest(android.Android)
- bp += java.GatherRequiredDepsForTest()
-
- fs := map[string][]byte{
- "a.java": nil,
- "a.jar": nil,
- "build/make/target/product/security": nil,
- "apex_manifest.json": nil,
- "AndroidManifest.xml": nil,
+ fs := android.MockFS{
+ "a.java": nil,
+ "a.jar": nil,
+ "apex_manifest.json": nil,
+ "AndroidManifest.xml": nil,
"system/sepolicy/apex/myapex-file_contexts": nil,
"system/sepolicy/apex/some-updatable-apex-file_contexts": nil,
"system/sepolicy/apex/some-non-updatable-apex-file_contexts": nil,
"system/sepolicy/apex/com.android.art.debug-file_contexts": nil,
"framework/aidl/a.aidl": nil,
}
- cc.GatherRequiredFilesForTest(fs)
- for k, v := range filesForSdkLibrary {
- fs[k] = v
- }
- config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
-
- ctx := android.NewTestArchContext(config)
- ctx.RegisterModuleType("apex", BundleFactory)
- ctx.RegisterModuleType("apex_key", ApexKeyFactory)
- ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
- ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- ctx.PreArchMutators(android.RegisterComponentsMutator)
- android.RegisterPrebuiltMutators(ctx)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
- java.RegisterRequiredBuildComponentsForTest(ctx)
- java.RegisterHiddenApiSingletonComponents(ctx)
- ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
- ctx.PreDepsMutators(RegisterPreDepsMutators)
- ctx.PostDepsMutators(RegisterPostDepsMutators)
-
- ctx.Register()
-
- pathCtx := android.PathContextForTesting(config)
- dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- transformDexpreoptConfig(dexpreoptConfig)
- dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
-
- // Make sure that any changes to these dexpreopt properties are mirrored in the corresponding
- // product variables.
- config.TestProductVariables.BootJars = dexpreoptConfig.BootJars
- config.TestProductVariables.UpdatableBootJars = dexpreoptConfig.UpdatableBootJars
-
- _, errs := ctx.ParseBlueprintsFiles("Android.bp")
- android.FailIfErrored(t, errs)
-
- _, errs = ctx.PrepareBuildActions(config)
- if errmsg == "" {
- android.FailIfErrored(t, errs)
- } else if len(errs) > 0 {
- android.FailIfNoMatchingErrors(t, errmsg, errs)
- } else {
- t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errmsg != "" {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg)
}
- return ctx
+ result := android.GroupFixturePreparers(
+ cc.PrepareForTestWithCcDefaultModules,
+ java.PrepareForTestWithHiddenApiBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ PrepareForTestWithApexBuildComponents,
+ android.FixtureModifyConfig(func(config android.Config) {
+ pathCtx := android.PathContextForTesting(config)
+ dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
+ transformDexpreoptConfig(dexpreoptConfig)
+ dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
+
+ // Make sure that any changes to these dexpreopt properties are mirrored in the corresponding
+ // product variables.
+ config.TestProductVariables.BootJars = dexpreoptConfig.BootJars
+ config.TestProductVariables.UpdatableBootJars = dexpreoptConfig.UpdatableBootJars
+ }),
+ fs.AddToFixture(),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, bp)
+
+ return result.TestContext
}
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
@@ -6692,45 +6696,33 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}`
- fs := map[string][]byte{
+ fs := android.MockFS{
"lib1/src/A.java": nil,
"lib2/src/B.java": nil,
"system/sepolicy/apex/myapex-file_contexts": nil,
}
- config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
- android.SetTestNeverallowRules(config, rules)
- updatableBootJars := make([]string, 0, len(apexBootJars))
- for _, apexBootJar := range apexBootJars {
- updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errmsg != "" {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg)
}
- config.TestProductVariables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars)
- ctx := android.NewTestArchContext(config)
- ctx.RegisterModuleType("apex", BundleFactory)
- ctx.RegisterModuleType("apex_key", ApexKeyFactory)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
- java.RegisterRequiredBuildComponentsForTest(ctx)
- ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
- ctx.PreDepsMutators(RegisterPreDepsMutators)
- ctx.PostDepsMutators(RegisterPostDepsMutators)
- ctx.PostDepsMutators(android.RegisterNeverallowMutator)
-
- ctx.Register()
-
- _, errs := ctx.ParseBlueprintsFiles("Android.bp")
- android.FailIfErrored(t, errs)
-
- _, errs = ctx.PrepareBuildActions(config)
- if errmsg == "" {
- android.FailIfErrored(t, errs)
- } else if len(errs) > 0 {
- android.FailIfNoMatchingErrors(t, errmsg, errs)
- return
- } else {
- t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
- }
+ android.GroupFixturePreparers(
+ android.PrepareForTestWithAndroidBuildComponents,
+ java.PrepareForTestWithJavaBuildComponents,
+ PrepareForTestWithApexBuildComponents,
+ android.PrepareForTestWithNeverallowRules(rules),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ updatableBootJars := make([]string, 0, len(apexBootJars))
+ for _, apexBootJar := range apexBootJars {
+ updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+ }
+ variables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars)
+ }),
+ fs.AddToFixture(),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, bp)
}
func TestApexPermittedPackagesRules(t *testing.T) {
@@ -7462,7 +7454,7 @@
t.Errorf("AndroidMk entry for \"stublib\" has LOCAL_NOT_AVAILABLE_FOR_PLATFORM set: %+v", entry.mkEntries)
}
cflags := entry.mkEntries.EntryMap["LOCAL_EXPORT_CFLAGS"]
- expected := "-D__STUBLIB_API__=1"
+ expected := "-D__STUBLIB_API__=10000"
if !android.InList(expected, cflags) {
t.Errorf("LOCAL_EXPORT_CFLAGS expected to have %q, but got %q", expected, cflags)
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 19596c3..76e75da 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2672,9 +2672,11 @@
expected := []string{
"android_vendor.VER_arm64_armv8-a_shared_1",
"android_vendor.VER_arm64_armv8-a_shared_2",
+ "android_vendor.VER_arm64_armv8-a_shared_current",
"android_vendor.VER_arm64_armv8-a_shared",
"android_vendor.VER_arm_armv7-a-neon_shared_1",
"android_vendor.VER_arm_armv7-a-neon_shared_2",
+ "android_vendor.VER_arm_armv7-a-neon_shared_current",
"android_vendor.VER_arm_armv7-a-neon_shared",
}
checkEquals(t, "variants for llndk stubs", expected, actual)
@@ -3174,10 +3176,12 @@
"android_arm64_armv8-a_shared_1",
"android_arm64_armv8-a_shared_2",
"android_arm64_armv8-a_shared_3",
+ "android_arm64_armv8-a_shared_current",
"android_arm_armv7-a-neon_shared",
"android_arm_armv7-a-neon_shared_1",
"android_arm_armv7-a-neon_shared_2",
"android_arm_armv7-a-neon_shared_3",
+ "android_arm_armv7-a-neon_shared_current",
}
variantsMismatch := false
if len(variants) != len(expectedVariants) {
diff --git a/cc/library.go b/cc/library.go
index f459e80..091acfe 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -65,7 +65,8 @@
// symbols that are exported for stubs variant of this library.
Symbol_file *string `android:"path"`
- // List versions to generate stubs libs for.
+ // List versions to generate stubs libs for. The version name "current" is always
+ // implicitly added.
Versions []string
}
@@ -171,6 +172,8 @@
// This variant is a stubs lib
BuildStubs bool `blueprint:"mutated"`
+ // This variant is the latest version
+ IsLatestVersion bool `blueprint:"mutated"`
// Version of the stubs lib
StubsVersion string `blueprint:"mutated"`
// List of all stubs versions associated with an implementation lib
@@ -775,7 +778,7 @@
type versionedInterface interface {
buildStubs() bool
- setBuildStubs()
+ setBuildStubs(isLatest bool)
hasStubsVariants() bool
setStubsVersion(string)
stubsVersion() string
@@ -1493,7 +1496,7 @@
if ctx.isVndk() && !ctx.IsVndkExt() {
return
}
- } else if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.directlyInAnyApex() {
+ } else if library.hasStubsVariants() && !ctx.Host() && ctx.directlyInAnyApex() {
// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
// The original path becomes a symlink to the corresponding file in the
// runtime APEX.
@@ -1609,11 +1612,29 @@
}
func (library *libraryDecorator) hasStubsVariants() bool {
- return len(library.Properties.Stubs.Versions) > 0
+ // Just having stubs.symbol_file is enough to create a stub variant. In that case
+ // the stub for the future API level is created.
+ return library.Properties.Stubs.Symbol_file != nil ||
+ len(library.Properties.Stubs.Versions) > 0
}
func (library *libraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
- return library.Properties.Stubs.Versions
+ if !library.hasStubsVariants() {
+ return nil
+ }
+
+ // Future API level is implicitly added if there isn't
+ vers := library.Properties.Stubs.Versions
+ if inList(android.FutureApiLevel.String(), vers) {
+ return vers
+ }
+ // In some cases, people use the raw value "10000" in the versions property.
+ // We shouldn't add the future API level in that case, otherwise there will
+ // be two identical versions.
+ if inList(strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()), vers) {
+ return vers
+ }
+ return append(vers, android.FutureApiLevel.String())
}
func (library *libraryDecorator) setStubsVersion(version string) {
@@ -1624,8 +1645,9 @@
return library.MutatedProperties.StubsVersion
}
-func (library *libraryDecorator) setBuildStubs() {
+func (library *libraryDecorator) setBuildStubs(isLatest bool) {
library.MutatedProperties.BuildStubs = true
+ library.MutatedProperties.IsLatestVersion = isLatest
}
func (library *libraryDecorator) setAllStubsVersions(versions []string) {
@@ -1637,8 +1659,7 @@
}
func (library *libraryDecorator) isLatestStubVersion() bool {
- versions := library.Properties.Stubs.Versions
- return versions[len(versions)-1] == library.stubsVersion()
+ return library.MutatedProperties.IsLatestVersion
}
func (library *libraryDecorator) availableFor(what string) bool {
@@ -1881,7 +1902,8 @@
c.stl = nil
c.Properties.PreventInstall = true
lib := moduleLibraryInterface(m)
- lib.setBuildStubs()
+ isLatest := i == (len(versions) - 1)
+ lib.setBuildStubs(isLatest)
if variants[i] != "" {
// A non-LLNDK stubs module is hidden from make and has a dependency from the
diff --git a/cc/linker.go b/cc/linker.go
index 6d0d416..21281d2 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -599,21 +599,20 @@
_ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh")
genSortedBssSymbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols",
blueprint.RuleParams{
- Command: "CROSS_COMPILE=$crossCompile $genSortedBssSymbolsPath ${in} ${out}",
- CommandDeps: []string{"$genSortedBssSymbolsPath", "${crossCompile}nm"},
+ Command: "CLANG_BIN=${clangBin} $genSortedBssSymbolsPath ${in} ${out}",
+ CommandDeps: []string{"$genSortedBssSymbolsPath", "${clangBin}/llvm-nm"},
},
- "crossCompile")
+ "clangBin")
)
func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string {
- crossCompile := gccCmd(flags.toolchain, "")
ctx.Build(pctx, android.BuildParams{
Rule: genSortedBssSymbols,
Description: "generate bss symbol order " + symbolOrderingFile.Base(),
Output: symbolOrderingFile,
Input: in,
Args: map[string]string{
- "crossCompile": crossCompile,
+ "clangBin": "${config.ClangBin}",
},
})
return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String()
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index fcc80a9..7bd0868 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -387,6 +387,14 @@
}
defer in.Close()
+ // Remove the target before copying. In most cases the file won't exist, but if there are
+ // duplicate copy rules for a file and the source file was read-only the second copy could
+ // fail.
+ err = os.Remove(to)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
out, err := os.Create(to)
if err != nil {
return err
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index e2fc78c..3abf978 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -24,7 +24,6 @@
"time"
"android/soong/shared"
-
"github.com/google/blueprint/bootstrap"
"android/soong/android"
@@ -65,16 +64,10 @@
return android.NewNameResolver(exportFilter)
}
-// bazelConversionRequested checks that the user is intending to convert
-// Blueprint to Bazel BUILD files.
-func bazelConversionRequested(configuration android.Config) bool {
- return configuration.IsEnvTrue("GENERATE_BAZEL_FILES")
-}
-
-func newContext(configuration android.Config) *android.Context {
+func newContext(configuration android.Config, prepareBuildActions bool) *android.Context {
ctx := android.NewContext(configuration)
ctx.Register()
- if !shouldPrepareBuildActions(configuration) {
+ if !prepareBuildActions {
configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
}
ctx.SetNameInterface(newNameResolver(configuration))
@@ -91,6 +84,84 @@
return configuration
}
+// Bazel-enabled mode. Soong runs in two passes.
+// First pass: Analyze the build tree, but only store all bazel commands
+// needed to correctly evaluate the tree in the second pass.
+// TODO(cparsons): Don't output any ninja file, as the second pass will overwrite
+// the incorrect results from the first pass, and file I/O is expensive.
+func runMixedModeBuild(configuration android.Config, firstCtx *android.Context, extraNinjaDeps []string) {
+ configuration.SetStopBefore(bootstrap.StopBeforeWriteNinja)
+ bootstrap.Main(firstCtx.Context, configuration, false, extraNinjaDeps...)
+ // Invoke bazel commands and save results for second pass.
+ if err := configuration.BazelContext.InvokeBazel(); err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err)
+ os.Exit(1)
+ }
+ // Second pass: Full analysis, using the bazel command results. Output ninja file.
+ secondPassConfig, err := android.ConfigForAdditionalRun(configuration)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err)
+ os.Exit(1)
+ }
+ secondCtx := newContext(secondPassConfig, true)
+ bootstrap.Main(secondCtx.Context, secondPassConfig, false, extraNinjaDeps...)
+}
+
+// Run the code-generation phase to convert BazelTargetModules to BUILD files.
+func runQueryView(configuration android.Config, ctx *android.Context) {
+ codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
+ absoluteQueryViewDir := shared.JoinPath(topDir, bazelQueryViewDir)
+ if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err)
+ os.Exit(1)
+ }
+}
+
+func runSoongDocs(configuration android.Config, extraNinjaDeps []string) {
+ ctx := newContext(configuration, false)
+ bootstrap.Main(ctx.Context, configuration, false, extraNinjaDeps...)
+ if err := writeDocs(ctx, configuration, docFile); err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err)
+ os.Exit(1)
+ }
+}
+
+func writeMetrics(configuration android.Config) {
+ metricsFile := filepath.Join(bootstrap.CmdlineBuildDir(), "soong_build_metrics.pb")
+ err := android.WriteMetrics(configuration, metricsFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error writing soong_build metrics %s: %s", metricsFile, err)
+ os.Exit(1)
+ }
+}
+
+func doChosenActivity(configuration android.Config, extraNinjaDeps []string) {
+ bazelConversionRequested := configuration.IsEnvTrue("GENERATE_BAZEL_FILES")
+ mixedModeBuild := configuration.BazelContext.BazelEnabled()
+ generateQueryView := bazelQueryViewDir != ""
+
+ if bazelConversionRequested {
+ // Run the alternate pipeline of bp2build mutators and singleton to convert
+ // Blueprint to BUILD files before everything else.
+ runBp2Build(configuration, extraNinjaDeps)
+ return
+ }
+
+ ctx := newContext(configuration, !generateQueryView)
+ if mixedModeBuild {
+ runMixedModeBuild(configuration, ctx, extraNinjaDeps)
+ } else {
+ bootstrap.Main(ctx.Context, configuration, false, extraNinjaDeps...)
+ }
+
+ // Convert the Soong module graph into Bazel BUILD files.
+ if generateQueryView {
+ runQueryView(configuration, ctx)
+ return
+ }
+ writeMetrics(configuration)
+}
+
func main() {
flag.Parse()
@@ -101,7 +172,6 @@
usedVariablesFile := shared.JoinPath(outDir, "soong.environment.used")
// 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,
@@ -122,72 +192,17 @@
extraNinjaDeps = append(extraNinjaDeps, filepath.Join(configuration.BuildDir(), "always_rerun_for_delve"))
}
- bazelConversionRequested := bazelConversionRequested(configuration)
- if bazelConversionRequested {
- // Run the alternate pipeline of bp2build mutators and singleton to convert Blueprint to BUILD files
- // before everything else.
- runBp2Build(srcDir, configuration, extraNinjaDeps)
- } else if configuration.BazelContext.BazelEnabled() {
- // Bazel-enabled mode. Soong runs in two passes.
- // First pass: Analyze the build tree, but only store all bazel commands
- // needed to correctly evaluate the tree in the second pass.
- // TODO(cparsons): Don't output any ninja file, as the second pass will overwrite
- // the incorrect results from the first pass, and file I/O is expensive.
- firstCtx := newContext(configuration)
- configuration.SetStopBefore(bootstrap.StopBeforeWriteNinja)
- bootstrap.Main(firstCtx.Context, configuration, false, extraNinjaDeps...)
- // Invoke bazel commands and save results for second pass.
- if err := configuration.BazelContext.InvokeBazel(); err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
- // Second pass: Full analysis, using the bazel command results. Output ninja file.
- secondPassConfig, err := android.ConfigForAdditionalRun(configuration)
- if err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
- ctx = newContext(secondPassConfig)
- bootstrap.Main(ctx.Context, secondPassConfig, false, extraNinjaDeps...)
- } else {
- ctx = newContext(configuration)
- bootstrap.Main(ctx.Context, configuration, false, extraNinjaDeps...)
+ if docFile != "" {
+ // We don't write an used variables file when generating documentation
+ // because that is done from within the actual builds as a Ninja action and
+ // thus it would overwrite the actual used variables file so this is
+ // special-cased.
+ runSoongDocs(configuration, extraNinjaDeps)
+ return
}
- // Convert the Soong module graph into Bazel BUILD files.
- if !bazelConversionRequested && bazelQueryViewDir != "" {
- // Run the code-generation phase to convert BazelTargetModules to BUILD files.
- codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
- absoluteQueryViewDir := shared.JoinPath(topDir, bazelQueryViewDir)
- if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
- }
-
- if !bazelConversionRequested && docFile != "" {
- if err := writeDocs(ctx, configuration, docFile); err != nil {
- fmt.Fprintf(os.Stderr, "%s", err)
- os.Exit(1)
- }
- }
-
- // TODO(ccross): make this a command line argument. Requires plumbing through blueprint
- // to affect the command line of the primary builder.
- if !bazelConversionRequested && shouldPrepareBuildActions(configuration) {
- metricsFile := filepath.Join(bootstrap.CmdlineBuildDir(), "soong_build_metrics.pb")
- err := android.WriteMetrics(configuration, metricsFile)
- if err != nil {
- fmt.Fprintf(os.Stderr, "error writing soong_build metrics %s: %s", metricsFile, err)
- os.Exit(1)
- }
- }
-
- if docFile == "" {
- // Let's not overwrite the used variables file when generating
- // documentation
- writeUsedVariablesFile(shared.JoinPath(topDir, usedVariablesFile), configuration)
- }
+ doChosenActivity(configuration, extraNinjaDeps)
+ writeUsedVariablesFile(shared.JoinPath(topDir, usedVariablesFile), configuration)
}
func writeUsedVariablesFile(path string, configuration android.Config) {
@@ -218,7 +233,7 @@
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
-func runBp2Build(srcDir string, configuration android.Config, extraNinjaDeps []string) {
+func runBp2Build(configuration android.Config, extraNinjaDeps []string) {
// Register an alternate set of singletons and mutators for bazel
// conversion for Bazel conversion.
bp2buildCtx := android.NewContext(configuration)
@@ -233,7 +248,7 @@
// configurations or variables, since those will generate different BUILD
// files based on how the user has configured their tree.
bp2buildCtx.SetModuleListFile(bootstrap.CmdlineModuleListFile())
- modulePaths, err := bp2buildCtx.ListModulePaths(srcDir)
+ modulePaths, err := bp2buildCtx.ListModulePaths(configuration.SrcDir())
if err != nil {
panic(err)
}
@@ -283,20 +298,3 @@
[]byte(fmt.Sprintf("%s: \\\n %s\n", ninjaFileName, extraNinjaDepsString)),
0666)
}
-
-// shouldPrepareBuildActions reads configuration and flags if build actions
-// should be generated.
-func shouldPrepareBuildActions(configuration android.Config) bool {
- // Generating Soong docs
- if docFile != "" {
- return false
- }
-
- // Generating a directory for Soong query (queryview)
- if bazelQueryViewDir != "" {
- return false
- }
-
- // Generating a directory for converted Bazel BUILD files
- return !bazelConversionRequested(configuration)
-}
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index 20d9622..dbbc1d8 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -43,6 +43,10 @@
// Total size of the logical partition
Size *string
+ // List of partitions for default group. Default group has no size limit and automatically
+ // minimized when creating an image.
+ Default_group []partitionProperties
+
// List of groups. A group defines a fixed sized region. It can host one or more logical
// partitions and their total size is limited by the size of the group they are in.
Groups []groupProperties
@@ -52,7 +56,7 @@
}
type groupProperties struct {
- // Name of the partition group
+ // Name of the partition group. Can't be "default"; use default_group instead.
Name *string
// Size of the partition group
@@ -92,8 +96,9 @@
// Sparse the filesystem images and calculate their sizes
sparseImages := make(map[string]android.OutputPath)
sparseImageSizes := make(map[string]android.OutputPath)
- for _, group := range l.properties.Groups {
- for _, part := range group.Partitions {
+
+ sparsePartitions := func(partitions []partitionProperties) {
+ for _, part := range partitions {
sparseImg, sizeTxt := sparseFilesystem(ctx, part, builder)
pName := proptools.String(part.Name)
sparseImages[pName] = sparseImg
@@ -101,6 +106,12 @@
}
}
+ for _, group := range l.properties.Groups {
+ sparsePartitions(group.Partitions)
+ }
+
+ sparsePartitions(l.properties.Default_group)
+
cmd := builder.Command().BuiltTool("lpmake")
size := proptools.String(l.properties.Size)
@@ -123,10 +134,32 @@
groupNames := make(map[string]bool)
partitionNames := make(map[string]bool)
+ addPartitionsToGroup := func(partitions []partitionProperties, gName string) {
+ for _, part := range partitions {
+ pName := proptools.String(part.Name)
+ if pName == "" {
+ ctx.PropertyErrorf("groups.partitions.name", "must be set")
+ }
+ if _, ok := partitionNames[pName]; ok {
+ ctx.PropertyErrorf("groups.partitions.name", "already exists")
+ } else {
+ partitionNames[pName] = true
+ }
+ // Get size of the partition by reading the -size.txt file
+ pSize := fmt.Sprintf("$(cat %s)", sparseImageSizes[pName])
+ cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
+ cmd.FlagWithInput("--image="+pName+"=", sparseImages[pName])
+ }
+ }
+
+ addPartitionsToGroup(l.properties.Default_group, "default")
+
for _, group := range l.properties.Groups {
gName := proptools.String(group.Name)
if gName == "" {
ctx.PropertyErrorf("groups.name", "must be set")
+ } else if gName == "default" {
+ ctx.PropertyErrorf("groups.name", `can't use "default" as a group name. Use default_group instead`)
}
if _, ok := groupNames[gName]; ok {
ctx.PropertyErrorf("group.name", "already exists")
@@ -142,21 +175,7 @@
}
cmd.FlagWithArg("--group=", gName+":"+gSize)
- for _, part := range group.Partitions {
- pName := proptools.String(part.Name)
- if pName == "" {
- ctx.PropertyErrorf("groups.partitions.name", "must be set")
- }
- if _, ok := partitionNames[pName]; ok {
- ctx.PropertyErrorf("groups.partitions.name", "already exists")
- } else {
- partitionNames[pName] = true
- }
- // Get size of the partition by reading the -size.txt file
- pSize := fmt.Sprintf("$(cat %s)", sparseImageSizes[pName])
- cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
- cmd.FlagWithInput("--image="+pName+"=", sparseImages[pName])
- }
+ addPartitionsToGroup(group.Partitions, gName)
}
l.output = android.PathForModuleOut(ctx, l.installFileName()).OutputPath
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 2ee456d..3f1e9f3 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -670,7 +670,8 @@
cmd: "cat $(in) > $(out)",
}
`
- result := prepareForGenRuleTest.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForGenRuleTest,
android.FixtureModifyConfigAndContext(
func(config android.Config, ctx *android.TestContext) {
config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
diff --git a/java/Android.bp b/java/Android.bp
index b6c14ac..8334b85 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -50,6 +50,7 @@
"kotlin.go",
"lint.go",
"legacy_core_platform_api_usage.go",
+ "platform_bootclasspath.go",
"platform_compat_config.go",
"plugin.go",
"prebuilt_apis.go",
@@ -79,6 +80,7 @@
"java_test.go",
"jdeps_test.go",
"kotlin_test.go",
+ "platform_bootclasspath_test.go",
"platform_compat_config_test.go",
"plugin_test.go",
"rro_test.go",
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index dc4e8aa..5c449e5 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -39,7 +39,8 @@
prepareForJavaTest, PrepareForTestWithHiddenApiBuildComponents)
func TestHiddenAPISingleton(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_library {
@@ -56,7 +57,8 @@
}
func TestHiddenAPIIndexSingleton(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("bar"),
fixtureSetBootJarsProductVariable("platform:foo", "platform:bar"),
@@ -115,7 +117,8 @@
" replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a" +
" suitable boot dex jar"
- hiddenApiFixtureFactory.Extend(
+ android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)).
RunTestWithBp(t, `
@@ -134,7 +137,8 @@
}
func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_import {
@@ -151,7 +155,8 @@
}
func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_library {
@@ -178,7 +183,8 @@
}
func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_library {
@@ -236,7 +242,8 @@
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
tc.preparer,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
@@ -286,7 +293,8 @@
// Where to find the prebuilt hiddenapi files:
prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi"
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
fixtureSetPrebuiltHiddenApiDirProductVariable(&prebuiltHiddenApiDir),
).RunTestWithBp(t, `
diff --git a/java/java.go b/java/java.go
index a7fbed2..26e5091 100644
--- a/java/java.go
+++ b/java/java.go
@@ -33,12 +33,12 @@
)
func init() {
- RegisterJavaBuildComponents(android.InitRegistrationContext)
+ registerJavaBuildComponents(android.InitRegistrationContext)
RegisterJavaSdkMemberTypes()
}
-func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
+func registerJavaBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_defaults", DefaultsFactory)
ctx.RegisterModuleType("java_library", LibraryFactory)
diff --git a/java/java_test.go b/java/java_test.go
index 3aafdda..fdf7579 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -74,23 +74,6 @@
return result.TestContext, result.Config
}
-// testJavaErrorWithConfig is a legacy way of running tests of java modules that expect errors.
-//
-// See testJava for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config) (*android.TestContext, android.Config) {
- t.Helper()
- // This must be done on the supplied config and not as part of the fixture because any changes to
- // the fixture's config will be ignored when RunTestWithConfig replaces it.
- pathCtx := android.PathContextForTesting(config)
- dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
- result := prepareForJavaTest.
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
- RunTestWithConfig(t, config)
- return result.TestContext, result.Config
-}
-
// testJavaWithFS runs tests using the prepareForJavaTest
//
// See testJava for an explanation as to how to stop using this deprecated method.
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
new file mode 100644
index 0000000..5507077
--- /dev/null
+++ b/java/platform_bootclasspath.go
@@ -0,0 +1,74 @@
+// 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 java
+
+import (
+ "android/soong/android"
+ "android/soong/dexpreopt"
+)
+
+func init() {
+ registerPlatformBootclasspathBuildComponents(android.InitRegistrationContext)
+}
+
+func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("platform_bootclasspath", platformBootclasspathFactory)
+}
+
+type platformBootclasspathModule struct {
+ android.ModuleBase
+}
+
+func platformBootclasspathFactory() android.Module {
+ m := &platformBootclasspathModule{}
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+ return m
+}
+
+func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if SkipDexpreoptBootJars(ctx) {
+ return
+ }
+
+ // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
+ // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
+ dexpreopt.RegisterToolDeps(ctx)
+}
+
+func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Nothing to do if skipping the dexpreopt of boot image jars.
+ if SkipDexpreoptBootJars(ctx) {
+ return
+ }
+
+ // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
+ // GenerateSingletonBuildActions method as it cannot create it for itself.
+ dexpreopt.GetGlobalSoongConfig(ctx)
+
+ imageConfig := b.getImageConfig(ctx)
+ if imageConfig == nil {
+ return
+ }
+
+ // Construct the boot image info from the config.
+ info := BootImageInfo{imageConfig: imageConfig}
+
+ // Make it available for other modules.
+ ctx.SetProvider(BootImageInfoProvider, info)
+}
+
+func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
+ return defaultBootImageConfig(ctx)
+}
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
new file mode 100644
index 0000000..1c81cfd
--- /dev/null
+++ b/java/platform_bootclasspath_test.go
@@ -0,0 +1,38 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// 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 java
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+)
+
+// Contains some simple tests for platform_bootclasspath.
+
+var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ dexpreopt.PrepareForTestByEnablingDexpreopt,
+)
+
+func TestPlatformBootclasspath(t *testing.T) {
+ prepareForTestWithPlatformBootclasspath.
+ RunTestWithBp(t, `
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+ `)
+}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index e1ec41b..2b18465 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -402,14 +402,16 @@
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8
t.Run("REL + Java language level 8", func(t *testing.T) {
- result := fixtureFactory.Extend(prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8)
+ result := android.GroupFixturePreparers(
+ fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8)
checkClasspath(t, result, true /* isJava8 */)
})
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9
t.Run("REL + Java language level 9", func(t *testing.T) {
- result := fixtureFactory.Extend(prepareWithPlatformVersionRel).RunTestWithBp(t, bp)
+ result := android.GroupFixturePreparers(
+ fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bp)
checkClasspath(t, result, false /* isJava8 */)
})
diff --git a/java/testing.go b/java/testing.go
index 221ceb1..80c107d 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -160,28 +160,6 @@
)
}
-func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) android.Config {
- bp += GatherRequiredDepsForTest()
-
- mockFS := android.MockFS{}
-
- cc.GatherRequiredFilesForTest(mockFS)
-
- for k, v := range fs {
- mockFS[k] = v
- }
-
- if env == nil {
- env = make(map[string]string)
- }
- if env["ANDROID_JAVA8_HOME"] == "" {
- env["ANDROID_JAVA8_HOME"] = "jdk8"
- }
- config := android.TestArchConfig(buildDir, env, bp, mockFS)
-
- return config
-}
-
func prebuiltApisFilesForLibs(apiLevels []string, sdkLibs []string) map[string][]byte {
fs := make(map[string][]byte)
for _, level := range apiLevels {
@@ -200,19 +178,6 @@
return fs
}
-// Register build components provided by this package that are needed by tests.
-//
-// In particular this must register all the components that are used in the `Android.bp` snippet
-// returned by GatherRequiredDepsForTest()
-//
-// deprecated: Use test fixtures instead, e.g. PrepareForTestWithJavaBuildComponents
-func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
- registerRequiredBuildComponentsForTest(ctx)
-
- // Make sure that any tool related module types needed by dexpreopt have been registered.
- dexpreopt.RegisterToolModulesForTest(ctx)
-}
-
// registerRequiredBuildComponentsForTest registers the build components used by
// PrepareForTestWithJavaDefaultModules.
//
@@ -228,7 +193,8 @@
RegisterDexpreoptBootJarsComponents(ctx)
RegisterDocsBuildComponents(ctx)
RegisterGenRuleBuildComponents(ctx)
- RegisterJavaBuildComponents(ctx)
+ registerJavaBuildComponents(ctx)
+ registerPlatformBootclasspathBuildComponents(ctx)
RegisterPrebuiltApisBuildComponents(ctx)
RegisterRuntimeResourceOverlayBuildComponents(ctx)
RegisterSdkLibraryBuildComponents(ctx)
@@ -236,23 +202,6 @@
RegisterSystemModulesBuildComponents(ctx)
}
-// Gather the module definitions needed by tests that depend upon code from this package.
-//
-// Returns an `Android.bp` snippet that defines the modules that are needed by this package.
-//
-// deprecated: Use test fixtures instead, e.g. PrepareForTestWithJavaDefaultModules
-func GatherRequiredDepsForTest() string {
- bp := gatherRequiredDepsForTest()
-
- // For class loader context and <uses-library> tests.
- bp += dexpreopt.CompatLibDefinitionsForTest()
-
- // Make sure that any tools needed for dexpreopting are defined.
- bp += dexpreopt.BpToolModulesForTest()
-
- return bp
-}
-
// gatherRequiredDepsForTest gathers the module definitions used by
// PrepareForTestWithJavaDefaultModules.
//
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index e90564f..bd3bfb1 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -18,7 +18,6 @@
"testing"
"android/soong/android"
- "android/soong/cc"
)
func TestClippy(t *testing.T) {
@@ -45,15 +44,6 @@
clippy_lints: "none",
}`
- bp = bp + GatherRequiredDepsForTest()
- bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
-
- fs := map[string][]byte{
- // Reuse the same blueprint file for subdirectories.
- "external/Android.bp": []byte(bp),
- "hardware/Android.bp": []byte(bp),
- }
-
var clippyLintTests = []struct {
modulePath string
fooFlags string
@@ -66,29 +56,22 @@
for _, tc := range clippyLintTests {
t.Run("path="+tc.modulePath, func(t *testing.T) {
- config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
- ctx := CreateTestContext(config)
- ctx.Register()
- _, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
+ result := android.GroupFixturePreparers(
+ prepareForRustTest,
+ // Test with the blueprint file in different directories.
+ android.FixtureAddTextFile(tc.modulePath+"Android.bp", bp),
+ ).RunTest(t)
- r := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
- if r.Args["clippyFlags"] != tc.fooFlags {
- t.Errorf("Incorrect flags for libfoo: %q, want %q", r.Args["clippyFlags"], tc.fooFlags)
- }
+ r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ android.AssertStringEquals(t, "libfoo flags", tc.fooFlags, r.Args["clippyFlags"])
- r = ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
- if r.Args["clippyFlags"] != "${config.ClippyDefaultLints}" {
- t.Errorf("Incorrect flags for libbar: %q, want %q", r.Args["clippyFlags"], "${config.ClippyDefaultLints}")
- }
+ r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ android.AssertStringEquals(t, "libbar flags", "${config.ClippyDefaultLints}", r.Args["clippyFlags"])
- r = ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
+ r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
if r.Rule != nil {
t.Errorf("libfoobar is setup to use clippy when explicitly disabled: clippyFlags=%q", r.Args["clippyFlags"])
}
-
})
}
}
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 3ed086f..c752762 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -19,7 +19,6 @@
"testing"
"android/soong/android"
- "android/soong/cc"
)
// Test that feature flags are being correctly generated.
@@ -132,15 +131,6 @@
lints: "none",
}`
- bp = bp + GatherRequiredDepsForTest()
- bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
-
- fs := map[string][]byte{
- // Reuse the same blueprint file for subdirectories.
- "external/Android.bp": []byte(bp),
- "hardware/Android.bp": []byte(bp),
- }
-
var lintTests = []struct {
modulePath string
fooFlags string
@@ -153,29 +143,20 @@
for _, tc := range lintTests {
t.Run("path="+tc.modulePath, func(t *testing.T) {
- config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
- ctx := CreateTestContext(config)
- ctx.Register()
- _, errs := ctx.ParseFileList(".", []string{tc.modulePath + "Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
+ result := android.GroupFixturePreparers(
+ prepareForRustTest,
+ // Test with the blueprint file in different directories.
+ android.FixtureAddTextFile(tc.modulePath+"Android.bp", bp),
+ ).RunTest(t)
- r := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
- if !strings.Contains(r.Args["rustcFlags"], tc.fooFlags) {
- t.Errorf("Incorrect flags for libfoo: %q, want %q", r.Args["rustcFlags"], tc.fooFlags)
- }
+ r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ android.AssertStringDoesContain(t, "libfoo flags", r.Args["rustcFlags"], tc.fooFlags)
- r = ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
- if !strings.Contains(r.Args["rustcFlags"], "${config.RustDefaultLints}") {
- t.Errorf("Incorrect flags for libbar: %q, want %q", r.Args["rustcFlags"], "${config.RustDefaultLints}")
- }
+ r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ android.AssertStringDoesContain(t, "libbar flags", r.Args["rustcFlags"], "${config.RustDefaultLints}")
- r = ctx.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
- if !strings.Contains(r.Args["rustcFlags"], "${config.RustAllowAllLints}") {
- t.Errorf("Incorrect flags for libfoobar: %q, want %q", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
- }
-
+ r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
+ android.AssertStringDoesContain(t, "libfoobar flags", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
})
}
}
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index 7af4635..09d30db 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -28,9 +28,10 @@
// testProjectJson run the generation of rust-project.json. It returns the raw
// content of the generated file.
func testProjectJson(t *testing.T, bp string) []byte {
- result := prepareForRustTest.
- Extend(android.FixtureMergeEnv(map[string]string{"SOONG_GEN_RUST_PROJECT": "1"})).
- RunTestWithBp(t, bp)
+ result := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.FixtureMergeEnv(map[string]string{"SOONG_GEN_RUST_PROJECT": "1"}),
+ ).RunTestWithBp(t, bp)
// The JSON file is generated via WriteFileToOutputDir. Therefore, it
// won't appear in the Output of the TestingSingleton. Manually verify
diff --git a/rust/testing.go b/rust/testing.go
index 5be71c9..75adcfc 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -17,13 +17,12 @@
import (
"android/soong/android"
"android/soong/cc"
- "android/soong/genrule"
)
// Preparer that will define all cc module types and a limited set of mutators and singletons that
// make those module types usable.
var PrepareForTestWithRustBuildComponents = android.GroupFixturePreparers(
- android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
+ android.FixtureRegisterWithContext(registerRequiredBuildComponentsForTest),
)
// The directory in which rust test default modules will be defined.
@@ -197,7 +196,7 @@
return bp
}
-func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
+func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
@@ -231,14 +230,3 @@
})
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
}
-
-func CreateTestContext(config android.Config) *android.TestContext {
- ctx := android.NewTestArchContext(config)
- android.RegisterPrebuiltMutators(ctx)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- genrule.RegisterGenruleBuildComponents(ctx)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
- RegisterRequiredBuildComponentsForTest(ctx)
-
- return ctx
-}
diff --git a/scripts/gen_sorted_bss_symbols.sh b/scripts/gen_sorted_bss_symbols.sh
index 244ed0d..a9b61a1 100755
--- a/scripts/gen_sorted_bss_symbols.sh
+++ b/scripts/gen_sorted_bss_symbols.sh
@@ -18,11 +18,11 @@
# their sizes.
# Inputs:
# Environment:
-# CROSS_COMPILE: prefix added to nm tools
+# CLANG_BIN: path to the clang bin directory
# Arguments:
# $1: Input ELF file
# $2: Output symbol ordering file
set -o pipefail
-${CROSS_COMPILE}nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2
+${CLANG_BIN}/llvm-nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index 907f239..8168fbf 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -74,7 +74,7 @@
return parser.parse_args()
-def enforce_uses_libraries(manifest, required, optional, relax, is_apk = False):
+def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
"""Verify that the <uses-library> tags in the manifest match those provided
by the build system.
@@ -86,26 +86,36 @@
is_apk: if the manifest comes from an APK or an XML file
"""
if is_apk:
- manifest_required, manifest_optional = extract_uses_libs_apk(manifest)
+ manifest_required, manifest_optional, tags = extract_uses_libs_apk(manifest)
else:
- manifest_required, manifest_optional = extract_uses_libs_xml(manifest)
+ manifest_required, manifest_optional, tags = extract_uses_libs_xml(manifest)
- err = []
- if manifest_required != required:
- err.append('Expected required <uses-library> tags "%s", got "%s"' %
- (', '.join(required), ', '.join(manifest_required)))
+ if manifest_required == required and manifest_optional == optional:
+ return None
- if manifest_optional != optional:
- err.append('Expected optional <uses-library> tags "%s", got "%s"' %
- (', '.join(optional), ', '.join(manifest_optional)))
+ errmsg = ''.join([
+ 'mismatch in the <uses-library> tags between the build system and the '
+ 'manifest:\n',
+ '\t- required libraries in build system: [%s]\n' % ', '.join(required),
+ '\t vs. in the manifest: [%s]\n' % ', '.join(manifest_required),
+ '\t- optional libraries in build system: [%s]\n' % ', '.join(optional),
+ '\t vs. in the manifest: [%s]\n' % ', '.join(manifest_optional),
+ '\t- tags in the manifest (%s):\n' % path,
+ '\t\t%s\n' % '\t\t'.join(tags),
+ 'note: the following options are available:\n',
+ '\t- to temporarily disable the check on command line, rebuild with ',
+ 'RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" ',
+ 'and disable AOT-compilation in dexpreopt)\n',
+ '\t- to temporarily disable the check for the whole product, set ',
+ 'PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles\n',
+ '\t- to fix the check, make build system properties coherent with the '
+ 'manifest\n',
+ '\t- see build/make/Changes.md for details\n'])
- if err:
- errmsg = '\n'.join(err)
- if not relax:
- raise ManifestMismatchError(errmsg)
- return errmsg
+ if not relax:
+ raise ManifestMismatchError(errmsg)
- return None
+ return errmsg
def extract_uses_libs_apk(badging):
@@ -115,14 +125,19 @@
required = []
optional = []
+ lines = []
for match in re.finditer(pattern, badging):
+ lines.append(match.group(0))
libname = match.group(2)
if match.group(1) == None:
required.append(libname)
else:
optional.append(libname)
- return first_unique_elements(required), first_unique_elements(optional)
+ required = first_unique_elements(required)
+ optional = first_unique_elements(optional)
+ tags = first_unique_elements(lines)
+ return required, optional, tags
def extract_uses_libs_xml(xml):
@@ -143,7 +158,15 @@
required = [uses_library_name(x) for x in libs if uses_library_required(x)]
optional = [uses_library_name(x) for x in libs if not uses_library_required(x)]
- return first_unique_elements(required), first_unique_elements(optional)
+ # render <uses-library> tags as XML for a pretty error message
+ tags = []
+ for lib in libs:
+ tags.append(lib.toprettyxml())
+
+ required = first_unique_elements(required)
+ optional = first_unique_elements(optional)
+ tags = first_unique_elements(tags)
+ return required, optional, tags
def first_unique_elements(l):
@@ -278,7 +301,7 @@
# in the manifest. Raise an exception on mismatch, unless the script was
# passed a special parameter to suppress exceptions.
errmsg = enforce_uses_libraries(manifest, required, optional,
- args.enforce_uses_libraries_relax, is_apk)
+ args.enforce_uses_libraries_relax, is_apk, args.input)
# Create a status file that is empty on success, or contains an error
# message on failure. When exceptions are suppressed, dexpreopt command
diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py
index 635ba9d..7159bdd 100755
--- a/scripts/manifest_check_test.py
+++ b/scripts/manifest_check_test.py
@@ -49,9 +49,9 @@
try:
relax = False
manifest_check.enforce_uses_libraries(doc, uses_libraries,
- optional_uses_libraries, relax, is_apk=False)
+ optional_uses_libraries, relax, False, 'path/to/X/AndroidManifest.xml')
manifest_check.enforce_uses_libraries(apk, uses_libraries,
- optional_uses_libraries, relax, is_apk=True)
+ optional_uses_libraries, relax, True, 'path/to/X/X.apk')
return True
except manifest_check.ManifestMismatchError:
return False
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index a886a18..b19fcc5 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -2407,6 +2407,7 @@
"1",
"2",
"3",
+ "current",
],
},
arch: {
@@ -2461,6 +2462,7 @@
"1",
"2",
"3",
+ "current",
],
},
target: {
@@ -2500,6 +2502,7 @@
"1",
"2",
"3",
+ "current",
],
},
target: {