diff options
-rw-r--r-- | android/prebuilt.go | 7 | ||||
-rw-r--r-- | apex/apex.go | 10 | ||||
-rw-r--r-- | apex/apex_test.go | 6 | ||||
-rw-r--r-- | apex/bootclasspath_fragment_test.go | 8 | ||||
-rw-r--r-- | apex/platform_bootclasspath_test.go | 32 | ||||
-rw-r--r-- | java/bootclasspath.go | 73 | ||||
-rw-r--r-- | java/bootclasspath_fragment.go | 2 | ||||
-rw-r--r-- | java/dexpreopt_bootjars.go | 58 |
8 files changed, 142 insertions, 54 deletions
diff --git a/android/prebuilt.go b/android/prebuilt.go index defec1186..6b076b7b4 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -612,6 +612,13 @@ func hideUnflaggedModules(ctx BottomUpMutatorContext, psi PrebuiltSelectionInfoM } } +func IsDontReplaceSourceWithPrebuiltTag(tag blueprint.DependencyTag) bool { + if t, ok := tag.(ReplaceSourceWithPrebuilt); ok { + return !t.ReplaceSourceWithPrebuilt() + } + return false +} + // PrebuiltPostDepsMutator replaces dependencies on the source module with dependencies on the // prebuilt when both modules exist and the prebuilt should be used. When the prebuilt should not // be used, disable installing it. diff --git a/apex/apex.go b/apex/apex.go index 1d74466b7..24b3118a4 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1211,13 +1211,6 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { } } -type apexTransitionTag interface { - // ApexTransition is a temporary interface used to tag dependencies with the apex variation they should use - // when the dependency is added before the apex transition mutator has run. These will be replaced with - // dependencies on the apex instead, which will then be used to find the necessary module inside the apex. - ApexTransition() string -} - type apexTransitionMutator struct{} func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string { @@ -1232,9 +1225,6 @@ func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string { } func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { - if tag, ok := ctx.DepTag().(apexTransitionTag); ok { - return tag.ApexTransition() - } return sourceVariation } diff --git a/apex/apex_test.go b/apex/apex_test.go index 887767527..0d6d31999 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -5341,6 +5341,12 @@ func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) { exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], } + prebuilt_apex { + name: "com.android.art", + src: "com.android.art-arm.apex", + exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], + } + prebuilt_bootclasspath_fragment { name: "art-bootclasspath-fragment", image_name: "art", diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index 526e59696..e8e45adfc 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -863,8 +863,8 @@ func TestBootclasspathFragment_HiddenAPIList(t *testing.T) { java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{ "all_apex_contributions", - "art-bootclasspath-fragment", "bar", + "com.android.art", "dex2oatd", "foo", }) @@ -1040,8 +1040,8 @@ func TestBootclasspathFragment_AndroidNonUpdatable_FromSource(t *testing.T) { "android-non-updatable.stubs.module_lib", "android-non-updatable.stubs.system", "android-non-updatable.stubs.test", - "art-bootclasspath-fragment", "bar", + "com.android.art", "dex2oatd", "foo", }) @@ -1214,8 +1214,8 @@ func TestBootclasspathFragment_AndroidNonUpdatable_FromText(t *testing.T) { "android-non-updatable.stubs.system", "android-non-updatable.stubs.test", "android-non-updatable.stubs.test_module_lib", - "art-bootclasspath-fragment", "bar", + "com.android.art", "dex2oatd", "foo", }) @@ -1365,8 +1365,8 @@ func TestBootclasspathFragment_AndroidNonUpdatable_AlwaysUsePrebuiltSdks(t *test java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common_myapex", []string{ "all_apex_contributions", - "art-bootclasspath-fragment", "bar", + "com.android.art", "dex2oatd", "foo", "prebuilt_sdk_module-lib_current_android-non-updatable", diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go index 6ebd78fa2..cd8c320ed 100644 --- a/apex/platform_bootclasspath_test.go +++ b/apex/platform_bootclasspath_test.go @@ -401,17 +401,17 @@ func TestPlatformBootclasspathDependencies(t *testing.T) { // Needed for generating the boot image. `platform:dex2oatd`, - // The configured contents of BootJars. - `com.android.art:baz`, - `com.android.art:quuz`, + // The configured contents of BootJars, via their apexes if necessary. + `platform:com.android.art`, + `platform:com.android.art`, `platform:foo`, - // The configured contents of ApexBootJars. - `myapex:bar`, + // The configured contents of ApexBootJars, via their apex. + `platform:myapex`, - // The fragments. - `com.android.art:art-bootclasspath-fragment`, - `myapex:my-bootclasspath-fragment`, + // The fragments via their apexes. + `platform:com.android.art`, + `platform:myapex`, // Impl lib of sdk_library for transitive srcjar generation `platform:foo.impl`, @@ -429,7 +429,7 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { // of AlwaysUsePrebuiltsSdk(). The second is a normal library that is unaffected. The order // matters, so that the dependencies resolved by the platform_bootclasspath matches the // configured list. - java.FixtureConfigureApexBootJars("myapex:foo", "myapex:bar"), + java.FixtureConfigureApexBootJars("myapex:foo"), java.PrepareForTestWithJavaSdkLibraryFiles, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) @@ -545,7 +545,6 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ // The configured contents of BootJars. "myapex:prebuilt_foo", - "myapex:bar", }) // Make sure that the myplatform-bootclasspath has the correct dependencies. @@ -561,14 +560,11 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { // Not a prebuilt as no prebuilt existed when it was added. "platform:legacy.core.platform.api.stubs.exportable", - // The prebuilt. - "myapex:prebuilt_foo", - - // Only a source module exists. - "myapex:bar", + // The prebuilt library via the apex. + "platform:myapex", - // The fragments. - "myapex:prebuilt_mybootclasspath-fragment", + // The fragments via the apex. + "platform:myapex", // Impl lib of sdk_library for transitive srcjar generation "platform:foo.impl", @@ -662,7 +658,7 @@ func TestBootJarNotInApex(t *testing.T) { prepareForTestWithMyapex, java.FixtureConfigureApexBootJars("myapex:foo"), ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( - `module "myplatform-bootclasspath" variant ".*": module "foo" from platform is not allowed in the apex boot jars list`)). + `module "myplatform-bootclasspath" variant ".*": failed to find module "foo" in apex "myapex"`)). RunTestWithBp(t, ` apex { name: "myapex", diff --git a/java/bootclasspath.go b/java/bootclasspath.go index 856f43919..5500926e8 100644 --- a/java/bootclasspath.go +++ b/java/bootclasspath.go @@ -15,6 +15,8 @@ package java import ( + "fmt" + "android/soong/android" "github.com/google/blueprint" @@ -52,25 +54,76 @@ func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex st tag := bootclasspathDependencyTag{ typ: tagType, } - if !android.IsConfiguredJarForPlatform(apex) { - tag.apex = apex - } - target := ctx.Module().Target() + if android.IsConfiguredJarForPlatform(apex) { + // Platform variant, add a direct dependency. + ctx.AddFarVariationDependencies(target.Variations(), tag, name) + } else { + // A module in an apex. Dependencies can't be added directly onto an apex variation, as that would + // require constructing a full ApexInfo configuration, which can't be predicted here. Add a dependency + // on the apex instead, and annotate the dependency tag with the desired module in the apex. + tag.moduleInApex = name + ctx.AddFarVariationDependencies(target.Variations(), tag, apex) + } - ctx.AddFarVariationDependencies(target.Variations(), tag, name) } // gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was // added by addDependencyOntoApexModulePair. func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tagType bootclasspathDependencyTagType) []android.Module { var modules []android.Module + + type moduleInApex struct { + module string + apex string + } + + var modulesInApexes []moduleInApex + ctx.VisitDirectDeps(func(module android.Module) { t := ctx.OtherModuleDependencyTag(module) if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType { - modules = append(modules, module) + if bcpTag.moduleInApex != "" { + modulesInApexes = append(modulesInApexes, moduleInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)}) + } else { + modules = append(modules, module) + } } }) + + for _, moduleInApex := range modulesInApexes { + var found android.Module + ctx.WalkDeps(func(child, parent android.Module) bool { + t := ctx.OtherModuleDependencyTag(child) + if parent == ctx.Module() { + if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType && ctx.OtherModuleName(child) == moduleInApex.apex { + // recurse into the apex + return true + } + } else if tagType != fragment && android.IsFragmentInApexTag(t) { + return true + } else if android.IsDontReplaceSourceWithPrebuiltTag(t) { + return false + } else if t == android.PrebuiltDepTag { + return false + } else if IsBootclasspathFragmentContentDepTag(t) { + return false + } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module { + if found != nil && child != found { + panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s", + moduleInApex.module, moduleInApex.apex, found, child)) + } + found = child + } + return false + }) + if found != nil { + modules = append(modules, found) + } else if !ctx.Config().AllowMissingDependencies() { + ctx.ModuleErrorf("failed to find module %q in apex %q\n", + moduleInApex.module, moduleInApex.apex) + } + } return modules } @@ -111,7 +164,9 @@ type bootclasspathDependencyTag struct { typ bootclasspathDependencyTagType - apex string + // moduleInApex is set to the name of the desired module when this dependency points + // to the apex that the modules is contained in. + moduleInApex string } type bootclasspathDependencyTagType int @@ -130,8 +185,8 @@ const ( func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() { } -func (t bootclasspathDependencyTag) ApexTransition() string { - return t.apex +func (t bootclasspathDependencyTag) LicenseAnnotations() []android.LicenseAnnotation { + return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} } // Dependencies that use the bootclasspathDependencyTag instances are only added after all the diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 4d35b9fa5..f3bff12f2 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -621,7 +621,7 @@ func (b *BootclasspathFragmentModule) configuredJars(ctx android.ModuleContext) if android.IsModulePrebuilt(ctx.Module()) { // prebuilt bcpf. the validation of this will be done at the top-level apex providerClasspathFragmentValidationInfoProvider(ctx, unknown) - } else if !disableSourceApexVariant(ctx) { + } else if !disableSourceApexVariant(ctx) && android.IsModulePreferred(ctx.Module()) { // source bcpf, and prebuilt apex are not selected. ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_BOOT_JARS", unknown) } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 83b1f4df6..24bb99d7f 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -15,6 +15,7 @@ package java import ( + "fmt" "path/filepath" "strings" @@ -552,12 +553,8 @@ func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorConte tag := bootclasspathDependencyTag{ typ: dexpreoptBootJar, } - if !android.IsConfiguredJarForPlatform(apex) { - tag.apex = apex - } - if ctx.OtherModuleDependencyVariantExists(ctx.Target().Variations(), android.RemoveOptionalPrebuiltPrefix(selected)) { - ctx.AddFarVariationDependencies(ctx.Target().Variations(), tag, android.RemoveOptionalPrebuiltPrefix(selected)) - } + + ctx.AddFarVariationDependencies(ctx.Target().Variations(), tag, android.RemoveOptionalPrebuiltPrefix(selected)) } } } @@ -565,6 +562,15 @@ func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorConte func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module { return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} { fragments := make(map[string]android.Module) + + type moduleInApexPair struct { + module string + apex string + } + + var modulesInApexes []moduleInApexPair + + // Find the list of modules in apexes. ctx.WalkDeps(func(child, parent android.Module) bool { if !isActiveModule(ctx, child) { return false @@ -575,15 +581,36 @@ func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android. return true } if bcpTag.typ == fragment { - apexInfo, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider) - for _, apex := range apexInfo.InApexVariants { - fragments[apex] = child + if bcpTag.moduleInApex == "" { + panic(fmt.Errorf("expected fragment to be in apex")) } - return false + modulesInApexes = append(modulesInApexes, moduleInApexPair{bcpTag.moduleInApex, ctx.OtherModuleName(child)}) + return true } } return false }) + + for _, moduleInApex := range modulesInApexes { + // Find a desired module in an apex. + ctx.WalkDeps(func(child, parent android.Module) bool { + t := ctx.OtherModuleDependencyTag(child) + if bcpTag, ok := t.(bootclasspathDependencyTag); ok { + if bcpTag.typ == platform { + return true + } + if bcpTag.typ == fragment && ctx.OtherModuleName(child) == moduleInApex.apex { + // This is the dependency from this module to the apex, recurse into it. + return true + } + } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module { + // This is the desired module inside the apex. + fragments[android.RemoveOptionalPrebuiltPrefix(moduleInApex.apex)] = child + } + return false + }) + } + return fragments }).(map[string]android.Module) } @@ -957,11 +984,15 @@ func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameT func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap { apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{} + ctx.VisitDirectDeps(func(am android.Module) { tag := ctx.OtherModuleDependencyTag(am) if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar { - if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists { - apexNameToApexExportsInfoMap[info.ApexName] = info + if bcpTag.moduleInApex == "" { + info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider) + if exists { + apexNameToApexExportsInfoMap[info.ApexName] = info + } } } }) @@ -1455,6 +1486,9 @@ func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.VisitDirectDeps(func(m android.Module) { tag := ctx.OtherModuleDependencyTag(m) if bcpTag, ok := tag.(bootclasspathDependencyTag); ok && bcpTag.typ == dexpreoptBootJar { + if bcpTag.moduleInApex != "" { + panic("unhandled moduleInApex") + } hostInstallsInfo, ok := android.OtherModuleProvider(ctx, m, artBootImageHostInfoProvider) if !ok { ctx.ModuleErrorf("Could not find information about the host variant of ART boot image") |