Merge "Use classpath elements in platform_bootclasspath" am: 9d31361873 am: 5805a4f34a

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1738975

Change-Id: Ia072fc05e1f63b409ba8e837bd809af505b4f4e6
This commit is contained in:
Paul Duffin
2021-06-21 20:16:57 +00:00
committed by Automerger Merge Worker
4 changed files with 174 additions and 72 deletions

View File

@@ -4496,6 +4496,11 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
java.CheckHiddenAPIRuleInputs(t, expectedInputs, indexRule)
}
fragment := java.ApexVariantReference{
Apex: proptools.StringPtr("myapex"),
Module: proptools.StringPtr("my-bootclasspath-fragment"),
}
t.Run("prebuilt only", func(t *testing.T) {
bp := `
prebuilt_apex {
@@ -4508,7 +4513,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo", "libbar"],
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
}
java_import {
@@ -4523,10 +4534,11 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer)
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
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")
@@ -4542,7 +4554,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
apex_set {
name: "myapex",
set: "myapex.apks",
exported_java_libs: ["libfoo", "libbar"],
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
}
java_import {
@@ -4557,10 +4575,11 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer)
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
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")
@@ -4583,7 +4602,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo", "libbar"],
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
}
java_import {
@@ -4604,6 +4629,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@@ -4619,7 +4645,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
// prebuilt_apex module always depends on the prebuilt, and so it doesn't
// find the dex boot jar in it. We either need to disable the source libfoo
// or make the prebuilt libfoo preferred.
testDexpreoptWithApexes(t, bp, "module libfoo does not provide a dex boot jar", preparer)
testDexpreoptWithApexes(t, bp, "module libfoo does not provide a dex boot jar", preparer, fragment)
})
t.Run("prebuilt library preferred with source", func(t *testing.T) {
@@ -4634,7 +4660,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo", "libbar"],
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
}
java_import {
@@ -4657,6 +4689,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@@ -4667,7 +4700,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
}
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer)
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
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")
@@ -4703,7 +4736,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo", "libbar"],
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
}
java_import {
@@ -4724,6 +4763,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@@ -4734,7 +4774,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
}
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer)
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
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")
@@ -4770,7 +4810,13 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo", "libbar"],
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo", "libbar"],
apex_available: ["myapex"],
}
java_import {
@@ -4793,6 +4839,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@@ -4803,7 +4850,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
}
`
ctx := testDexpreoptWithApexes(t, bp, "", preparer)
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
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")
@@ -6378,7 +6425,7 @@ func TestAppSetBundlePrebuilt(t *testing.T) {
android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String())
}
func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer android.FixturePreparer) {
func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) {
t.Helper()
bp := `
@@ -6397,6 +6444,15 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi
apex_available: [
"some-non-updatable-apex",
],
compile_dex: true,
}
bootclasspath_fragment {
name: "some-non-updatable-fragment",
contents: ["some-non-updatable-apex-lib"],
apex_available: [
"some-non-updatable-apex",
],
}
java_library {
@@ -6428,7 +6484,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi
apex {
name: "some-non-updatable-apex",
key: "some-non-updatable-apex.key",
java_libs: ["some-non-updatable-apex-lib"],
bootclasspath_fragments: ["some-non-updatable-fragment"],
updatable: false,
}
@@ -6443,7 +6499,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi
apex {
name: "com.android.art.debug",
key: "com.android.art.debug.key",
java_libs: ["some-art-lib"],
bootclasspath_fragments: ["art-bootclasspath-fragment"],
updatable: true,
min_sdk_version: "current",
}
@@ -6476,10 +6532,10 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi
}
`
testDexpreoptWithApexes(t, bp, errmsg, preparer)
testDexpreoptWithApexes(t, bp, errmsg, preparer, fragments...)
}
func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.FixturePreparer) *android.TestContext {
func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) *android.TestContext {
t.Helper()
fs := android.MockFS{
@@ -6507,11 +6563,22 @@ func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.F
PrepareForTestWithApexBuildComponents,
preparer,
fs.AddToFixture(),
android.FixtureAddTextFile("frameworks/base/boot/Android.bp", `
platform_bootclasspath {
name: "platform-bootclasspath",
android.FixtureModifyMockFS(func(fs android.MockFS) {
if _, ok := fs["frameworks/base/boot/Android.bp"]; !ok {
insert := ""
for _, fragment := range fragments {
insert += fmt.Sprintf("{apex: %q, module: %q},\n", *fragment.Apex, *fragment.Module)
}
fs["frameworks/base/boot/Android.bp"] = []byte(fmt.Sprintf(`
platform_bootclasspath {
name: "platform-bootclasspath",
fragments: [
%s
],
}
`, insert))
}
`),
}),
).
ExtendWithErrorHandler(errorHandler).
RunTestWithBp(t, bp)
@@ -6619,7 +6686,11 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
preparer := java.FixtureConfigureBootJars("com.android.art.debug:some-art-lib")
testNoUpdatableJarsInBootImage(t, "", preparer)
fragment := java.ApexVariantReference{
Apex: proptools.StringPtr("com.android.art.debug"),
Module: proptools.StringPtr("art-bootclasspath-fragment"),
}
testNoUpdatableJarsInBootImage(t, "", preparer, fragment)
})
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
@@ -6651,7 +6722,11 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
preparer := java.FixtureConfigureBootJars("some-non-updatable-apex:some-non-updatable-apex-lib")
testNoUpdatableJarsInBootImage(t, "", preparer)
fragment := java.ApexVariantReference{
Apex: proptools.StringPtr("some-non-updatable-apex"),
Module: proptools.StringPtr("some-non-updatable-fragment"),
}
testNoUpdatableJarsInBootImage(t, "", preparer, fragment)
})
t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
@@ -6682,6 +6757,11 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) {
func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) {
preparer := java.FixtureConfigureBootJars("myapex:libfoo")
t.Run("prebuilt no source", func(t *testing.T) {
fragment := java.ApexVariantReference{
Apex: proptools.StringPtr("myapex"),
Module: proptools.StringPtr("my-bootclasspath-fragment"),
}
testDexpreoptWithApexes(t, `
prebuilt_apex {
name: "myapex" ,
@@ -6693,36 +6773,21 @@ func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo"],
}
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
}
java_import {
name: "libfoo",
jars: ["libfoo.jar"],
}
`, "", preparer)
})
prebuilt_bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["libfoo"],
apex_available: ["myapex"],
}
t.Run("prebuilt no source", func(t *testing.T) {
testDexpreoptWithApexes(t, `
prebuilt_apex {
name: "myapex" ,
arch: {
arm64: {
src: "myapex-arm64.apex",
},
arm: {
src: "myapex-arm.apex",
},
},
exported_java_libs: ["libfoo"],
}
java_import {
name: "libfoo",
jars: ["libfoo.jar"],
}
`, "", preparer)
java_import {
name: "libfoo",
jars: ["libfoo.jar"],
apex_available: ["myapex"],
}
`, "", preparer, fragment)
})
}

View File

@@ -234,12 +234,18 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
apex {
name: "myapex",
key: "myapex.key",
java_libs: [
"bar",
bootclasspath_fragments: [
"my-bootclasspath-fragment",
],
updatable: false,
}
bootclasspath_fragment {
name: "my-bootclasspath-fragment",
contents: ["bar"],
apex_available: ["myapex"],
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
@@ -267,6 +273,10 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
apex: "com.android.art",
module: "art-bootclasspath-fragment",
},
{
apex: "myapex",
module: "my-bootclasspath-fragment",
},
],
}
`,
@@ -283,7 +293,8 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
})
java.CheckPlatformBootclasspathFragments(t, result, "myplatform-bootclasspath", []string{
`com.android.art:art-bootclasspath-fragment`,
"com.android.art:art-bootclasspath-fragment",
"myapex:my-bootclasspath-fragment",
})
// Make sure that the myplatform-bootclasspath has the correct dependencies.
@@ -307,6 +318,7 @@ func TestPlatformBootclasspathDependencies(t *testing.T) {
// The fragments.
`com.android.art:art-bootclasspath-fragment`,
`myapex:my-bootclasspath-fragment`,
})
}
@@ -410,6 +422,12 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
platform_bootclasspath {
name: "myplatform-bootclasspath",
fragments: [
{
apex: "myapex",
module:"mybootclasspath-fragment",
},
],
}
`,
)
@@ -431,7 +449,7 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
"platform:legacy.core.platform.api.stubs",
// Needed for generating the boot image.
`platform:dex2oatd`,
"platform:dex2oatd",
// The platform_bootclasspath intentionally adds dependencies on both source and prebuilt
// modules when available as it does not know which one will be preferred.
@@ -442,6 +460,9 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) {
// Only a source module exists.
"myapex:bar",
// The fragments.
"myapex:mybootclasspath-fragment",
})
}

View File

@@ -43,22 +43,37 @@ type MonolithicHiddenAPIInfo struct {
// The paths to the generated all-flags.csv files.
AllFlagsPaths android.Paths
// The classes jars from the libraries on the platform bootclasspath.
ClassesJars android.Paths
}
// newMonolithicHiddenAPIInfo creates a new MonolithicHiddenAPIInfo from the flagFilesByCategory
// plus information provided by each of the fragments.
func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory FlagFilesByCategory, fragments []android.Module) MonolithicHiddenAPIInfo {
func newMonolithicHiddenAPIInfo(ctx android.ModuleContext, flagFilesByCategory FlagFilesByCategory, classpathElements ClasspathElements) MonolithicHiddenAPIInfo {
monolithicInfo := MonolithicHiddenAPIInfo{}
monolithicInfo.FlagsFilesByCategory = flagFilesByCategory
// Merge all the information from the fragments. The fragments form a DAG so it is possible that
// this will introduce duplicates so they will be resolved after processing all the fragments.
for _, fragment := range fragments {
if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) {
info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo)
monolithicInfo.append(&info)
// Merge all the information from the classpathElements. The fragments form a DAG so it is possible that
// this will introduce duplicates so they will be resolved after processing all the classpathElements.
for _, element := range classpathElements {
var classesJars android.Paths
switch e := element.(type) {
case *ClasspathLibraryElement:
classesJars = retrieveClassesJarsFromModule(e.Module())
case *ClasspathFragmentElement:
fragment := e.Module()
if ctx.OtherModuleHasProvider(fragment, HiddenAPIInfoProvider) {
info := ctx.OtherModuleProvider(fragment, HiddenAPIInfoProvider).(HiddenAPIInfo)
monolithicInfo.append(&info)
}
classesJars = extractClassesJarsFromModules(e.Contents)
}
monolithicInfo.ClassesJars = append(monolithicInfo.ClassesJars, classesJars...)
}
// Dedup paths.

View File

@@ -44,13 +44,9 @@ type platformBootclasspathModule struct {
properties platformBootclasspathProperties
// The apex:module pairs obtained from the configured modules.
//
// Currently only for testing.
configuredModules []android.Module
// The apex:module pairs obtained from the fragments.
//
// Currently only for testing.
fragments []android.Module
// Path to the monolithic hiddenapi-flags.csv file.
@@ -280,7 +276,15 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
return nil
}
monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, fragments)
// Construct a list of ClasspathElement objects from the modules and fragments.
classpathElements := CreateClasspathElements(ctx, modules, fragments)
monolithicInfo := b.createAndProvideMonolithicHiddenAPIInfo(ctx, classpathElements)
// Extract the classes jars only from those libraries that do not have corresponding fragments as
// the fragments will have already provided the flags that are needed.
classesJars := monolithicInfo.ClassesJars
// Create the input to pass to ruleToGenerateHiddenAPIStubFlagsFile
input := newHiddenAPIFlagInput()
@@ -297,9 +301,6 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJarByModule.bootDexJars(), input)
rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
// Extract the classes jars from the contents.
classesJars := extractClassesJarsFromModules(modules)
// Generate the annotation-flags.csv file from all the module annotations.
annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags.csv")
buildRuleToGenerateAnnotationFlags(ctx, "monolithic hiddenapi flags", classesJars, stubFlags, annotationFlags)
@@ -329,7 +330,7 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
// createAndProvideMonolithicHiddenAPIInfo creates a MonolithicHiddenAPIInfo and provides it for
// testing.
func (b *platformBootclasspathModule) createAndProvideMonolithicHiddenAPIInfo(ctx android.ModuleContext, fragments []android.Module) MonolithicHiddenAPIInfo {
func (b *platformBootclasspathModule) createAndProvideMonolithicHiddenAPIInfo(ctx android.ModuleContext, classpathElements ClasspathElements) MonolithicHiddenAPIInfo {
// Create a temporary input structure in which to collate information provided directly by this
// module, either through properties or direct dependencies.
temporaryInput := newHiddenAPIFlagInput()
@@ -339,7 +340,7 @@ func (b *platformBootclasspathModule) createAndProvideMonolithicHiddenAPIInfo(ct
// Create the monolithic info, by starting with the flag files specified on this and then merging
// in information from all the fragment dependencies of this.
monolithicInfo := newMonolithicHiddenAPIInfo(ctx, temporaryInput.FlagFilesByCategory, fragments)
monolithicInfo := newMonolithicHiddenAPIInfo(ctx, temporaryInput.FlagFilesByCategory, classpathElements)
// Store the information for testing.
ctx.SetProvider(MonolithicHiddenAPIInfoProvider, monolithicInfo)