Merge "Revert "Revert "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/apex/apex_test.go b/apex/apex_test.go
index 9bc4a8e..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) {
@@ -5909,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",
@@ -7425,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/bp2build/conversion.go b/bp2build/conversion.go
index 787222d..6b47cd1 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -19,12 +19,13 @@
ruleShims map[string]RuleShim,
buildToTargets map[string]BazelTargets,
mode CodegenMode) []BazelFile {
- files := make([]BazelFile, 0, len(ruleShims)+len(buildToTargets)+numAdditionalFiles)
- // Write top level files: WORKSPACE. These files are empty.
- files = append(files, newFile("", "WORKSPACE", ""))
+ var files []BazelFile
if mode == QueryView {
+ // Write top level WORKSPACE.
+ files = append(files, newFile("", "WORKSPACE", ""))
+
// Used to denote that the top level directory is a package.
files = append(files, newFile("", GeneratedBuildFileName, ""))
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index a115ddc..9fd6817 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -24,36 +24,6 @@
basename string
}
-func assertFilecountsAreEqual(t *testing.T, actual []BazelFile, expected []filepath) {
- if a, e := len(actual), len(expected); a != e {
- t.Errorf("Expected %d files, got %d", e, a)
- }
-}
-
-func assertFileContent(t *testing.T, actual []BazelFile, expected []filepath) {
- for i := range actual {
- if g, w := actual[i], expected[i]; g.Dir != w.dir || g.Basename != w.basename {
- t.Errorf("Did not find expected file %s/%s", g.Dir, g.Basename)
- } else if g.Basename == "BUILD" || g.Basename == "WORKSPACE" {
- if g.Contents != "" {
- t.Errorf("Expected %s to have no content.", g)
- }
- } else if g.Contents == "" {
- t.Errorf("Contents of %s unexpected empty.", g)
- }
- }
-}
-
-func sortFiles(files []BazelFile) {
- sort.Slice(files, func(i, j int) bool {
- if dir1, dir2 := files[i].Dir, files[j].Dir; dir1 == dir2 {
- return files[i].Basename < files[j].Basename
- } else {
- return dir1 < dir2
- }
- })
-}
-
func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) {
files := CreateBazelFiles(map[string]RuleShim{}, map[string]BazelTargets{}, QueryView)
expectedFilePaths := []filepath{
@@ -79,21 +49,39 @@
},
}
- assertFilecountsAreEqual(t, files, expectedFilePaths)
- sortFiles(files)
- assertFileContent(t, files, expectedFilePaths)
-}
-
-func TestCreateBazelFiles_Bp2Build_AddsTopLevelFiles(t *testing.T) {
- files := CreateBazelFiles(map[string]RuleShim{}, map[string]BazelTargets{}, Bp2Build)
- expectedFilePaths := []filepath{
- {
- dir: "",
- basename: "WORKSPACE",
- },
+ // Compare number of files
+ if a, e := len(files), len(expectedFilePaths); a != e {
+ t.Errorf("Expected %d files, got %d", e, a)
}
- assertFilecountsAreEqual(t, files, expectedFilePaths)
- sortFiles(files)
- assertFileContent(t, files, expectedFilePaths)
+ // Sort the files to be deterministic
+ sort.Slice(files, func(i, j int) bool {
+ if dir1, dir2 := files[i].Dir, files[j].Dir; dir1 == dir2 {
+ return files[i].Basename < files[j].Basename
+ } else {
+ return dir1 < dir2
+ }
+ })
+
+ // Compare the file contents
+ for i := range files {
+ actualFile, expectedFile := files[i], expectedFilePaths[i]
+
+ if actualFile.Dir != expectedFile.dir || actualFile.Basename != expectedFile.basename {
+ t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
+ } else if actualFile.Basename == "BUILD" || actualFile.Basename == "WORKSPACE" {
+ if actualFile.Contents != "" {
+ t.Errorf("Expected %s to have no content.", actualFile)
+ }
+ } else if actualFile.Contents == "" {
+ t.Errorf("Contents of %s unexpected empty.", actualFile)
+ }
+ }
+}
+
+func TestCreateBazelFiles_Bp2Build_CreatesNoFilesWithNoTargets(t *testing.T) {
+ files := CreateBazelFiles(map[string]RuleShim{}, map[string]BazelTargets{}, Bp2Build)
+ if len(files) != 0 {
+ t.Errorf("Expected no files, got %d", len(files))
+ }
}
diff --git a/cc/builder.go b/cc/builder.go
index 4771b89..8c9743f 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -182,11 +182,11 @@
blueprint.RuleParams{
Depfile: "${out}.d",
Deps: blueprint.DepsGCC,
- Command: "CROSS_COMPILE=$crossCompile $tocPath $format -i ${in} -o ${out} -d ${out}.d",
+ Command: "CLANG_BIN=$clangBin $tocPath $format -i ${in} -o ${out} -d ${out}.d",
CommandDeps: []string{"$tocPath"},
Restat: true,
},
- "crossCompile", "format")
+ "clangBin", "format")
// Rule for invoking clang-tidy (a clang-based linter).
clangTidy, clangTidyRE = pctx.RemoteStaticRules("clangTidy",
@@ -918,16 +918,12 @@
outputFile android.WritablePath, flags builderFlags) {
var format string
- var crossCompile string
if ctx.Darwin() {
format = "--macho"
- crossCompile = "${config.MacToolPath}"
} else if ctx.Windows() {
format = "--pe"
- crossCompile = gccCmd(flags.toolchain, "")
} else {
format = "--elf"
- crossCompile = gccCmd(flags.toolchain, "")
}
ctx.Build(pctx, android.BuildParams{
@@ -936,8 +932,8 @@
Output: outputFile,
Input: inputFile,
Args: map[string]string{
- "crossCompile": crossCompile,
- "format": format,
+ "clangBin": "${config.ClangBin}",
+ "format": format,
},
})
}
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/cc/stl.go b/cc/stl.go
index 75fab17..594231d 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -188,12 +188,7 @@
if needsLibAndroidSupport(ctx) {
deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
}
- // TODO: Switch the NDK over to the LLVM unwinder for non-arm32 architectures.
- if ctx.Arch().ArchType == android.Arm {
- deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
- } else {
- deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped")
- }
+ deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
default:
panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl))
}
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/config/kotlin.go b/java/config/kotlin.go
index fd8e3db..6cb61f3 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -35,11 +35,16 @@
pctx.SourcePathVariable("KotlinAnnotationJar", "external/kotlinc/lib/annotations-13.0.jar")
pctx.SourcePathVariable("KotlinStdlibJar", KotlinStdlibJar)
- // These flags silence "Illegal reflective access" warnings when running kotlinc in OpenJDK9
- pctx.StaticVariable("KotlincSuppressJDK9Warnings", strings.Join([]string{
+ // These flags silence "Illegal reflective access" warnings when running kapt in OpenJDK9+
+ pctx.StaticVariable("KaptSuppressJDK9Warnings", strings.Join([]string{
"-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
"-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
"-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
"-J--add-opens=java.base/sun.net.www.protocol.jar=ALL-UNNAMED",
}, " "))
+
+ // These flags silence "Illegal reflective access" warnings when running kotlinc in OpenJDK9+
+ pctx.StaticVariable("KotlincSuppressJDK9Warnings", strings.Join([]string{
+ "-J--add-opens=java.base/java.util=ALL-UNNAMED", // https://youtrack.jetbrains.com/issue/KT-43704
+ }, " "))
}
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 26e5091..3ffe572 100644
--- a/java/java.go
+++ b/java/java.go
@@ -776,7 +776,7 @@
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)
+ defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites)
j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest)
}
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
diff --git a/java/kotlin.go b/java/kotlin.go
index 2960f81..3a6fc0f 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -34,8 +34,9 @@
`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
- `${config.KotlincCmd} ${config.JavacHeapFlags} $kotlincFlags ` +
- `-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile -kotlin-home $emptyDir && ` +
+ `${config.KotlincCmd} ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
+ `$kotlincFlags -jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile ` +
+ `-kotlin-home $emptyDir && ` +
`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` +
`rm -rf "$srcJarDir"`,
CommandDeps: []string{
@@ -123,8 +124,8 @@
`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
` --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
- `${config.KotlincCmd} ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} $kotlincFlags ` +
- `-Xplugin=${config.KotlinKaptJar} ` +
+ `${config.KotlincCmd} ${config.KaptSuppressJDK9Warnings} ${config.KotlincSuppressJDK9Warnings} ` +
+ `${config.JavacHeapFlags} $kotlincFlags -Xplugin=${config.KotlinKaptJar} ` +
`-P plugin:org.jetbrains.kotlin.kapt3:sources=$kaptDir/sources ` +
`-P plugin:org.jetbrains.kotlin.kapt3:classes=$kaptDir/classes ` +
`-P plugin:org.jetbrains.kotlin.kapt3:stubs=$kaptDir/stubs ` +
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 1113af7..80c107d 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -194,6 +194,7 @@
RegisterDocsBuildComponents(ctx)
RegisterGenRuleBuildComponents(ctx)
registerJavaBuildComponents(ctx)
+ registerPlatformBootclasspathBuildComponents(ctx)
RegisterPrebuiltApisBuildComponents(ctx)
RegisterRuntimeResourceOverlayBuildComponents(ctx)
RegisterSdkLibraryBuildComponents(ctx)
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/scripts/toc.sh b/scripts/toc.sh
index 8b1d25f..af8bece 100755
--- a/scripts/toc.sh
+++ b/scripts/toc.sh
@@ -17,7 +17,7 @@
# Script to handle generating a .toc file from a .so file
# Inputs:
# Environment:
-# CROSS_COMPILE: prefix added to readelf tool
+# CLANG_BIN: path to the clang bin directory
# Arguments:
# -i ${file}: input file (required)
# -o ${file}: output file (required)
@@ -35,34 +35,34 @@
}
do_elf() {
- ("${CROSS_COMPILE}readelf" -d "${infile}" | grep SONAME || echo "No SONAME for ${infile}") > "${outfile}.tmp"
- "${CROSS_COMPILE}readelf" --dyn-syms "${infile}" | awk '{$2=""; $3=""; print}' >> "${outfile}.tmp"
+ ("${CLANG_BIN}/llvm-readelf" -d "${infile}" | grep SONAME || echo "No SONAME for ${infile}") > "${outfile}.tmp"
+ "${CLANG_BIN}/llvm-readelf" --dyn-syms "${infile}" | awk '{$2=""; $3=""; print}' >> "${outfile}.tmp"
cat <<EOF > "${depsfile}"
${outfile}: \\
- ${CROSS_COMPILE}readelf \\
+ ${CLANG_BIN}/llvm-readelf \\
EOF
}
do_macho() {
- "${CROSS_COMPILE}/otool" -l "${infile}" | grep LC_ID_DYLIB -A 5 > "${outfile}.tmp"
- "${CROSS_COMPILE}/nm" -gP "${infile}" | cut -f1-2 -d" " | (grep -v 'U$' >> "${outfile}.tmp" || true)
+ "${CLANG_BIN}/llvm-objdump" -p "${infile}" | grep LC_ID_DYLIB -A 5 > "${outfile}.tmp"
+ "${CLANG_BIN}/llvm-nm" -gP "${infile}" | cut -f1-2 -d" " | (grep -v 'U$' >> "${outfile}.tmp" || true)
cat <<EOF > "${depsfile}"
${outfile}: \\
- ${CROSS_COMPILE}/otool \\
- ${CROSS_COMPILE}/nm \\
+ ${CLANG_BIN}/llvm-objdump \\
+ ${CLANG_BIN}/llvm-nm \\
EOF
}
do_pe() {
- "${CROSS_COMPILE}objdump" -x "${infile}" | grep "^Name" | cut -f3 -d" " > "${outfile}.tmp"
- "${CROSS_COMPILE}nm" -g -f p "${infile}" | cut -f1-2 -d" " >> "${outfile}.tmp"
+ "${CLANG_BIN}/llvm-objdump" -x "${infile}" | grep "^Name" | cut -f3 -d" " > "${outfile}.tmp"
+ "${CLANG_BIN}/llvm-nm" -g -f p "${infile}" | cut -f1-2 -d" " >> "${outfile}.tmp"
cat <<EOF > "${depsfile}"
${outfile}: \\
- ${CROSS_COMPILE}objdump \\
- ${CROSS_COMPILE}nm \\
+ ${CLANG_BIN}/llvm-objdump \\
+ ${CLANG_BIN}/llvm-nm \\
EOF
}
@@ -98,8 +98,8 @@
usage
fi
-if [ -z "${CROSS_COMPILE:-}" ]; then
- echo "CROSS_COMPILE environment variable must be set"
+if [ -z "${CLANG_BIN:-}" ]; then
+ echo "CLANG_BIN environment variable must be set"
usage
fi
@@ -107,7 +107,7 @@
cat <<EOF > "${depsfile}"
${outfile}: \\
- ${CROSS_COMPILE}readelf \\
+ ${CLANG_BIN}/llvm-readelf \\
EOF
if [ -n "${elf:-}" ]; then
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: {