Add exported_bootclasspath_fragments to prebuilt_apex/apex_set
This is needed to allow a prebuilt_bootclasspath_fragment to be used
interchangeably with a bootclasspath_fragment in the
platform_bootclasspath module.
The platform_bootclasspath module depends on APEX specific variants of
bootclasspath_fragment modules. That works because the
bootclasspath_fragment modules are part of an apex and so have an APEX
specific variant which the platform_bootclasspath can specify.
Using a prebuilt_bootclasspath_fragment in place of a
bootclasspath_fragment requires that the prebuilt also has an APEX
specific variant.
Specifying exported_bootclasspath_fragments on a prebuilt_apex/apex_set
will cause it to create an APEX variant for the named module whcih will
allow it to be selected by the platform_bootclasspath module.
Bug: 186034565
Bug: 177892522
Test: m nothing
Change-Id: I7ddacc6498ec3a4a9f26c5f78b7f9a033e494d78
diff --git a/apex/deapexer.go b/apex/deapexer.go
index 1db13f9..9bc5720 100644
--- a/apex/deapexer.go
+++ b/apex/deapexer.go
@@ -44,9 +44,13 @@
// module.`
type DeapexerProperties struct {
// List of java libraries that are embedded inside this prebuilt APEX bundle and for which this
- // APEX bundle will provide dex implementation jars for use by dexpreopt and boot jars package
- // check.
+ // APEX bundle will create an APEX variant and provide dex implementation jars for use by
+ // dexpreopt and boot jars package check.
Exported_java_libs []string
+
+ // List of bootclasspath fragments inside this prebuiltd APEX bundle and for which this APEX
+ // bundle will create an APEX variant.
+ Exported_bootclasspath_fragments []string
}
type SelectedApexProperties struct {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index a9d24a7..7830f95 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -97,10 +97,17 @@
func (p *prebuiltCommon) deapexerDeps(ctx android.BottomUpMutatorContext) {
// Add dependencies onto the java modules that represent the java libraries that are provided by
// and exported from this prebuilt apex.
- for _, lib := range p.deapexerProperties.Exported_java_libs {
- dep := prebuiltApexExportedModuleName(ctx, lib)
+ for _, exported := range p.deapexerProperties.Exported_java_libs {
+ dep := prebuiltApexExportedModuleName(ctx, exported)
ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedJavaLibTag, dep)
}
+
+ // Add dependencies onto the bootclasspath fragment modules that are exported from this prebuilt
+ // apex.
+ for _, exported := range p.deapexerProperties.Exported_bootclasspath_fragments {
+ dep := prebuiltApexExportedModuleName(ctx, exported)
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), exportedBootclasspathFragmentTag, dep)
+ }
}
// apexInfoMutator marks any modules for which this apex exports a file as requiring an apex
@@ -137,18 +144,19 @@
var dependencies []android.ApexModule
mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m)
- if tag == exportedJavaLibTag {
+ if exportedTag, ok := tag.(exportedDependencyTag); ok {
+ propertyName := exportedTag.name
depName := mctx.OtherModuleName(m)
// It is an error if the other module is not a prebuilt.
if _, ok := m.(android.PrebuiltInterface); !ok {
- mctx.PropertyErrorf("exported_java_libs", "%q is not a prebuilt module", depName)
+ mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName)
return
}
// It is an error if the other module is not an ApexModule.
if _, ok := m.(android.ApexModule); !ok {
- mctx.PropertyErrorf("exported_java_libs", "%q is not usable within an apex", depName)
+ mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName)
return
}
@@ -451,7 +459,8 @@
func (t exportedDependencyTag) ExcludeFromVisibilityEnforcement() {}
var (
- exportedJavaLibTag = exportedDependencyTag{name: "exported_java_lib"}
+ exportedJavaLibTag = exportedDependencyTag{name: "exported_java_libs"}
+ exportedBootclasspathFragmentTag = exportedDependencyTag{name: "exported_bootclasspath_fragments"}
)
func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/java/boot_image.go b/java/boot_image.go
index d0862a9..6f50c27 100644
--- a/java/boot_image.go
+++ b/java/boot_image.go
@@ -124,8 +124,22 @@
if m.properties.Image_name != nil && len(contents) != 0 {
ctx.ModuleErrorf(`both of the "image_name" and "contents" properties have been supplied, please supply exactly one`)
}
+
imageName := proptools.String(m.properties.Image_name)
if imageName == "art" {
+ // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property.
+ if m.MemberName() != "" {
+ // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons:
+ // 1. There is no way to use this at the moment so ignoring it is safe.
+ // 2. Attempting to initialize the contents property from the configuration will end up having
+ // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems
+ // as the unversioned prebuilt could end up with an APEX variant created for the source
+ // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in
+ // turn will prevent it from accessing the dex implementation jar from that which will
+ // break hidden API processing, amongst others.
+ return
+ }
+
// Get the configuration for the art apex jars. Do not use getImageConfig(ctx) here as this is
// too early in the Soong processing for that to work.
global := dexpreopt.GetGlobalConfig(ctx)
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 0ce4351..ef4d7cd 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -24,6 +24,7 @@
func TestSnapshotWithBootclasspathFragment_ImageName(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
prepareForSdkTestWithApex,
// Some additional files needed for the art apex.
@@ -32,6 +33,20 @@
"com.android.art.pem": nil,
"system/sepolicy/apex/com.android.art-file_contexts": nil,
}),
+
+ // platform_bootclasspath that depends on the fragment.
+ android.FixtureAddTextFile("frameworks/base/boot/Android.bp", `
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ fragments: [
+ {
+ apex: "com.android.art",
+ module: "mybootclasspathfragment",
+ },
+ ],
+ }
+ `),
+
java.FixtureConfigureBootJars("com.android.art:mybootlib"),
android.FixtureWithRootAndroidBp(`
sdk {
@@ -72,6 +87,23 @@
`),
).RunTest(t)
+ // A preparer to add a prebuilt apex to the test fixture.
+ prepareWithPrebuiltApex := android.GroupFixturePreparers(
+ android.FixtureAddTextFile("prebuilts/apex/Android.bp", `
+ prebuilt_apex {
+ name: "com.android.art",
+ src: "art.apex",
+ exported_java_libs: [
+ "mybootlib",
+ ],
+ exported_bootclasspath_fragments: [
+ "mybootclasspathfragment",
+ ],
+ }
+ `),
+ android.FixtureAddFile("prebuilts/apex/art.apex", nil),
+ )
+
CheckSnapshot(t, result, "mysdk", "",
checkUnversionedAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
@@ -121,19 +153,9 @@
checkAllCopyRules(`
.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar
`),
- snapshotTestPreparer(checkSnapshotPreferredWithSource, android.GroupFixturePreparers(
- android.FixtureAddTextFile("prebuilts/apex/Android.bp", `
- prebuilt_apex {
- name: "com.android.art",
- src: "art.apex",
- exported_java_libs: [
- "mybootlib",
- ],
- }
- `),
- android.FixtureAddFile("prebuilts/apex/art.apex", nil),
- ),
- ),
+ snapshotTestPreparer(checkSnapshotWithoutSource, prepareWithPrebuiltApex),
+ snapshotTestPreparer(checkSnapshotWithSourcePreferred, prepareWithPrebuiltApex),
+ snapshotTestPreparer(checkSnapshotPreferredWithSource, prepareWithPrebuiltApex),
)
}
diff --git a/sdk/testing.go b/sdk/testing.go
index bf59aed..f4e85c0 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -254,6 +254,7 @@
snapshotPreparer := android.GroupFixturePreparers(sourcePreparers, fs.AddToFixture())
var runSnapshotTestWithCheckers = func(t *testing.T, testConfig snapshotTest, extraPreparer android.FixturePreparer) {
+ t.Helper()
customization := snapshotBuildInfo.snapshotTestCustomization(testConfig)
customizedPreparers := android.GroupFixturePreparers(customization.preparers...)