Merge "Use classpath elements in platform_bootclasspath"

This commit is contained in:
Paul Duffin 2021-06-21 16:16:00 +00:00 committed by Gerrit Code Review
commit 9d31361873
4 changed files with 174 additions and 72 deletions

View file

@ -4646,6 +4646,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 {
@ -4658,7 +4663,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 {
@ -4673,10 +4684,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")
@ -4692,7 +4704,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 {
@ -4707,10 +4725,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")
@ -4733,7 +4752,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 {
@ -4754,6 +4779,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@ -4769,7 +4795,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) {
@ -4784,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 {
@ -4807,6 +4839,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@ -4817,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")
@ -4853,7 +4886,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 {
@ -4874,6 +4913,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@ -4884,7 +4924,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")
@ -4920,7 +4960,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 {
@ -4943,6 +4989,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
jars: ["libbar.jar"],
},
apex_available: ["myapex"],
shared_library: false,
}
java_sdk_library {
@ -4953,7 +5000,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")
@ -6528,7 +6575,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 := `
@ -6547,6 +6594,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 {
@ -6578,7 +6634,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,
}
@ -6593,7 +6649,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",
}
@ -6626,10 +6682,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{
@ -6657,11 +6713,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)
@ -6769,7 +6836,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) {
@ -6801,7 +6872,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) {
@ -6832,6 +6907,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" ,
@ -6843,36 +6923,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)