diff options
Diffstat (limited to 'apex')
-rw-r--r-- | apex/apex.go | 174 | ||||
-rw-r--r-- | apex/apex_test.go | 100 | ||||
-rw-r--r-- | apex/bootclasspath_fragment_test.go | 16 | ||||
-rw-r--r-- | apex/builder.go | 2 | ||||
-rw-r--r-- | apex/classpath_element_test.go | 46 | ||||
-rw-r--r-- | apex/container_test.go | 3 | ||||
-rw-r--r-- | apex/dexpreopt_bootjars_test.go | 6 | ||||
-rw-r--r-- | apex/platform_bootclasspath_test.go | 63 | ||||
-rw-r--r-- | apex/prebuilt.go | 122 | ||||
-rw-r--r-- | apex/systemserver_classpath_fragment_test.go | 12 |
10 files changed, 216 insertions, 328 deletions
diff --git a/apex/apex.go b/apex/apex.go index cb9dc4905..04816580d 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -61,12 +61,11 @@ func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { } func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { - ctx.TopDown("apex_info", apexInfoMutator) ctx.BottomUp("apex_unique", apexUniqueVariationsMutator) // Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether // it should create a platform variant. ctx.BottomUp("mark_platform_availability", markPlatformAvailability) - ctx.Transition("apex", &apexTransitionMutator{}) + ctx.InfoBasedTransition("apex", android.NewGenericTransitionMutatorAdapter(&apexTransitionMutator{})) } type apexBundleProperties struct { @@ -768,6 +767,17 @@ var ( shBinaryTag = &dependencyTag{name: "shBinary", payload: true} ) +type fragmentInApexDepTag struct { + blueprint.BaseDependencyTag + android.FragmentInApexTag +} + +func (fragmentInApexDepTag) ExcludeFromVisibilityEnforcement() {} + +// fragmentInApexTag is used by apex modules to depend on their fragments. Java bootclasspath +// modules can traverse from the apex to the fragment using android.IsFragmentInApexTag. +var fragmentInApexTag = fragmentInApexDepTag{} + // TODO(jiyong): shorten this function signature func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ResolvedApexNativeDependencies, target android.Target, imageVariation string) { binVariations := target.Variations() @@ -916,6 +926,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { commonVariation := ctx.Config().AndroidCommonTarget.Variations() ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...) ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments.GetOrDefault(ctx, nil)...) + ctx.AddFarVariationDependencies(commonVariation, fragmentInApexTag, a.properties.Bootclasspath_fragments.GetOrDefault(ctx, nil)...) ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments.GetOrDefault(ctx, nil)...) ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...) ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...) @@ -984,45 +995,29 @@ func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato } } -var _ ApexInfoMutator = (*apexBundle)(nil) +var _ ApexTransitionMutator = (*apexBundle)(nil) func (a *apexBundle) ApexVariationName() string { return a.properties.ApexVariationName } -// ApexInfoMutator is responsible for collecting modules that need to have apex variants. They are -// identified by doing a graph walk starting from an apexBundle. Basically, all the (direct and -// indirect) dependencies are collected. But a few types of modules that shouldn't be included in -// the apexBundle (e.g. stub libraries) are not collected. Note that a single module can be depended -// on by multiple apexBundles. In that case, the module is collected for all of the apexBundles. -// -// For each dependency between an apex and an ApexModule an ApexInfo object describing the apex -// is passed to that module's BuildForApex(ApexInfo) method which collates them all in a list. -// The apexMutator uses that list to create module variants for the apexes to which it belongs. -// The relationship between module variants and apexes is not one-to-one as variants will be -// shared between compatible apexes. -func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { +type generateApexInfoContext interface { + android.MinSdkVersionFromValueContext + Module() android.Module + ModuleName() string +} +// generateApexInfo returns an android.ApexInfo configuration that should be used for dependencies of this apex. +func (a *apexBundle) generateApexInfo(ctx generateApexInfoContext) android.ApexInfo { // The VNDK APEX is special. For the APEX, the membership is described in a very different // way. There is no dependency from the VNDK APEX to the VNDK libraries. Instead, VNDK // libraries are self-identified by their vndk.enabled properties. There is no need to run - // this mutator for the APEX as nothing will be collected. So, let's return fast. + // this mutator for the APEX as nothing will be collected so return an empty ApexInfo. if a.vndkApex { - return + return android.ApexInfo{} } - continueApexDepsWalk := func(child, parent android.Module) bool { - am, ok := child.(android.ApexModule) - if !ok || !am.CanHaveApexVariants() { - return false - } - - return android.IsDepInSameApex(mctx, parent, child) - } - - android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{}) - - minSdkVersion := a.minSdkVersion(mctx) + minSdkVersion := a.minSdkVersion(ctx) // When min_sdk_version is not set, the apex is built against FutureApiLevel. if minSdkVersion.IsNone() { minSdkVersion = android.FutureApiLevel @@ -1031,56 +1026,45 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) { // This is the main part of this mutator. Mark the collected dependencies that they need to // be built for this apexBundle. - apexVariationName := mctx.ModuleName() // could be com.android.foo + apexVariationName := ctx.ModuleName() // could be com.android.foo if a.GetOverriddenBy() != "" { // use the overridden name com.mycompany.android.foo apexVariationName = a.GetOverriddenBy() } - a.properties.ApexVariationName = apexVariationName apexInfo := android.ApexInfo{ ApexVariationName: apexVariationName, MinSdkVersion: minSdkVersion, Updatable: a.Updatable(), UsePlatformApis: a.UsePlatformApis(), - InApexVariants: []string{apexVariationName}, - BaseApexName: mctx.ModuleName(), + BaseApexName: ctx.ModuleName(), ApexAvailableName: proptools.String(a.properties.Apex_available_name), } - mctx.WalkDeps(func(child, parent android.Module) bool { - if !continueApexDepsWalk(child, parent) { - return false - } - child.(android.ApexModule).BuildForApex(apexInfo) // leave a mark! - return true - }) + return apexInfo } -type ApexInfoMutator interface { - // ApexVariationName returns the name of the APEX variation to use in the apex - // mutator etc. It is the same name as ApexInfo.ApexVariationName. - ApexVariationName() string +func (a *apexBundle) ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo { + return []android.ApexInfo{a.generateApexInfo(ctx)} +} - // ApexInfoMutator implementations must call BuildForApex(ApexInfo) on any modules that are - // depended upon by an apex and which require an apex specific variant. - ApexInfoMutator(android.TopDownMutatorContext) +func (a *apexBundle) ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo { + return sourceInfo } -// apexInfoMutator delegates the work of identifying which modules need an ApexInfo and apex -// specific variant to modules that support the ApexInfoMutator. -// It also propagates updatable=true to apps of updatable apexes -func apexInfoMutator(mctx android.TopDownMutatorContext) { - if !mctx.Module().Enabled(mctx) { - return - } +func (a *apexBundle) ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo { + return a.generateApexInfo(ctx) +} - if a, ok := mctx.Module().(ApexInfoMutator); ok { - a.ApexInfoMutator(mctx) - } +func (a *apexBundle) ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) { + android.SetProvider(ctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{}) + a.properties.ApexVariationName = info.ApexVariationName +} - if am, ok := mctx.Module().(android.ApexModule); ok { - android.ApexInfoMutator(mctx, am) - } +type ApexTransitionMutator interface { + ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo + ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo + ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo + ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) } // TODO: b/215736885 Whittle the denylist @@ -1195,49 +1179,35 @@ func markPlatformAvailability(mctx android.BottomUpMutatorContext) { type apexTransitionMutator struct{} -func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []string { - // apexBundle itself is mutated so that it and its dependencies have the same apex variant. - if ai, ok := ctx.Module().(ApexInfoMutator); ok && apexModuleTypeRequiresVariant(ai) { - if overridable, ok := ctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" { - return []string{overridable.GetOverriddenBy()} - } - return []string{ai.ApexVariationName()} +func (a *apexTransitionMutator) Split(ctx android.BaseModuleContext) []android.ApexInfo { + if ai, ok := ctx.Module().(ApexTransitionMutator); ok { + return ai.ApexTransitionMutatorSplit(ctx) } - return []string{""} + return []android.ApexInfo{{}} } -func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { - return sourceVariation -} - -func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { - if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { - return android.IncomingApexTransition(ctx, incomingVariation) - } else if ai, ok := ctx.Module().(ApexInfoMutator); ok { - if overridable, ok := ctx.Module().(android.OverridableModule); ok && overridable.GetOverriddenBy() != "" { - return overridable.GetOverriddenBy() - } - return ai.ApexVariationName() +func (a *apexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo { + if ai, ok := ctx.Module().(ApexTransitionMutator); ok { + return ai.ApexTransitionMutatorOutgoing(ctx, sourceInfo) } - - return "" + return android.ApexInfo{} } -func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { - if am, ok := ctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { - android.MutateApexTransition(ctx, variation) +func (a *apexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo { + if ai, ok := ctx.Module().(ApexTransitionMutator); ok { + return ai.ApexTransitionMutatorIncoming(ctx, outgoingInfo) } + return android.ApexInfo{} } -// apexModuleTypeRequiresVariant determines whether the module supplied requires an apex specific -// variant. -func apexModuleTypeRequiresVariant(module ApexInfoMutator) bool { - if a, ok := module.(*apexBundle); ok { - // TODO(jiyong): document the reason why the VNDK APEX is an exception here. - return !a.vndkApex +func (a *apexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) { + if ai, ok := ctx.Module().(ApexTransitionMutator); ok { + ai.ApexTransitionMutatorMutate(ctx, info) } +} - return true +func (a *apexTransitionMutator) TransitionInfoFromVariation(variation string) android.ApexInfo { + panic(fmt.Errorf("adding dependencies on explicit apex variations is not supported")) } const ( @@ -1665,10 +1635,6 @@ func apexFileForFilesystem(ctx android.BaseModuleContext, buildFile android.Path // to the child modules. Returning false makes the visit to continue in the sibling or the parent // modules. This is used in check* functions below. func (a *apexBundle) WalkPayloadDeps(ctx android.BaseModuleContext, do android.PayloadDepsCallback) { - apexVariationName := ctx.ModuleName() - if overrideName := a.GetOverriddenBy(); overrideName != "" { - apexVariationName = overrideName - } ctx.WalkDeps(func(child, parent android.Module) bool { am, ok := child.(android.ApexModule) if !ok || !am.CanHaveApexVariants() { @@ -1687,8 +1653,7 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.BaseModuleContext, do android.P return false } - ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider) - externalDep := !android.InList(apexVariationName, ai.InApexVariants) + externalDep := !android.IsDepInSameApex(ctx, parent, child) // Visit actually return do(ctx, parent, am, externalDep) @@ -1713,8 +1678,7 @@ func (a *apexBundle) WalkPayloadDepsProxy(ctx android.BaseModuleContext, return false } - ai, _ := android.OtherModuleProvider(ctx, child, android.ApexInfoProvider) - externalDep := !android.InList(ctx.ModuleName(), ai.InApexVariants) + externalDep := !android.IsDepInSameApex(ctx, parent, child) // Visit actually return do(ctx, parent, child, externalDep) @@ -2567,7 +2531,7 @@ func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) { } // Returns apex's min_sdk_version string value, honoring overrides -func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string { +func (a *apexBundle) minSdkVersionValue(ctx android.MinSdkVersionFromValueContext) string { // Only override the minSdkVersion value on Apexes which already specify // a min_sdk_version (it's optional for non-updatable apexes), and that its // min_sdk_version value is lower than the one to override with. @@ -2591,7 +2555,7 @@ func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLe } // Returns apex's min_sdk_version ApiLevel, honoring overrides -func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { +func (a *apexBundle) minSdkVersion(ctx android.MinSdkVersionFromValueContext) android.ApiLevel { return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx)) } @@ -2607,7 +2571,7 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext librariesDirectlyInApex[ctx.OtherModuleName(dep)] = true }) - a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool { if info, ok := android.OtherModuleProvider(ctx, to, cc.LinkableInfoProvider); ok { // If `to` is not actually in the same APEX as `from` then it does not need // apex_available and neither do any of its dependencies. @@ -2721,7 +2685,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { return } - a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool { // As soon as the dependency graph crosses the APEX boundary, don't go further. if externalDep { return false @@ -2739,7 +2703,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { toName := ctx.OtherModuleName(to) if android.CheckAvailableForApex(apexName, - android.OtherModuleProviderOrDefault(ctx, to, android.ApexInfoProvider).ApexAvailableFor) { + android.OtherModuleProviderOrDefault(ctx, to, android.ApexAvailableInfoProvider).ApexAvailableFor) { return true } diff --git a/apex/apex_test.go b/apex/apex_test.go index 851579287..6c1a2d66b 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -5190,7 +5190,7 @@ func TestPrebuilt(t *testing.T) { } `) - testingModule := ctx.ModuleForTests("myapex", "android_common_myapex") + testingModule := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") prebuilt := testingModule.Module().(*Prebuilt) expectedInput := "myapex-arm64.apex" @@ -5211,7 +5211,7 @@ func TestPrebuilt(t *testing.T) { func TestPrebuiltMissingSrc(t *testing.T) { t.Parallel() - testApexError(t, `module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, ` + testApexError(t, `module "myapex" variant "android_common_prebuilt_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, ` prebuilt_apex { name: "myapex", } @@ -5228,7 +5228,7 @@ func TestPrebuiltFilenameOverride(t *testing.T) { } `) - testingModule := ctx.ModuleForTests("myapex", "android_common_myapex") + testingModule := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") p := testingModule.Module().(*Prebuilt) expected := "notmyapex.apex" @@ -5251,7 +5251,7 @@ func TestApexSetFilenameOverride(t *testing.T) { set: "company-myapex.apks", filename: "com.company.android.myapex.apex" } - `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") + `).ModuleForTests("com.company.android.myapex", "android_common_prebuilt_com.android.myapex") testApex(t, ` apex_set { @@ -5260,7 +5260,7 @@ func TestApexSetFilenameOverride(t *testing.T) { set: "company-myapex.apks", filename: "com.company.android.myapex.capex" } - `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") + `).ModuleForTests("com.company.android.myapex", "android_common_prebuilt_com.android.myapex") testApexError(t, `filename should end in .apex or .capex for apex_set`, ` apex_set { @@ -5284,7 +5284,7 @@ func TestPrebuiltOverrides(t *testing.T) { } `) - testingModule := ctx.ModuleForTests("myapex.prebuilt", "android_common_myapex.prebuilt") + testingModule := ctx.ModuleForTests("myapex.prebuilt", "android_common_prebuilt_myapex.prebuilt") p := testingModule.Module().(*Prebuilt) expected := []string{"myapex"} @@ -5307,7 +5307,7 @@ func TestPrebuiltApexName(t *testing.T) { apex_name: "com.android.myapex", src: "company-myapex-arm.apex", } - `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") + `).ModuleForTests("com.company.android.myapex", "android_common_prebuilt_com.android.myapex") testApex(t, ` apex_set { @@ -5315,7 +5315,7 @@ func TestPrebuiltApexName(t *testing.T) { apex_name: "com.android.myapex", set: "company-myapex.apks", } - `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex") + `).ModuleForTests("com.company.android.myapex", "android_common_prebuilt_com.android.myapex") } func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) { @@ -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", @@ -5549,7 +5555,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { out/soong/.intermediates/packages/modules/com.android.art/art-bootclasspath-fragment/android_common_com.android.art/modular-hiddenapi/index.csv `) - myApex := ctx.ModuleForTests("myapex", "android_common_myapex").Module() + myApex := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex").Module() overrideNames := []string{ "", @@ -5633,7 +5639,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, fragment) + testDexpreoptWithApexes(t, bp, `module "platform-bootclasspath" variant ".*": module libfoo{.*} does not provide a dex jar`, preparer, fragment) // dexbootjar check is skipped if AllowMissingDependencies is true preparerAllowMissingDeps := android.GroupFixturePreparers( preparer, @@ -5669,6 +5675,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { prebuilt_apex { name: "myapex", + prefer: true, arch: { arm64: { src: "myapex-arm64.apex", @@ -6603,16 +6610,10 @@ func TestApexAvailable_IndirectDep(t *testing.T) { testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path: .*via tag apex\.dependencyTag\{"sharedLib"\} .*-> libfoo.*link:shared.* -.*via tag cc\.dependencyTag.* -.*-> libfoo.*link:static.* .*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.* .*-> libbar.*link:shared.* -.*via tag cc\.dependencyTag.* -.*-> libbar.*link:static.* .*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.* -.*-> libbaz.*link:shared.* -.*via tag cc\.dependencyTag.* -.*-> libbaz.*link:static.*`, ` +.*-> libbaz.*link:shared.*`, ` apex { name: "myapex", key: "myapex.key", @@ -7872,7 +7873,7 @@ func TestJavaSDKLibrary_WithinApex(t *testing.T) { }) // The bar library should depend on the implementation jar. - barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac") + barLibrary := ctx.ModuleForTests("bar", "android_common_apex10000").Rule("javac") if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } @@ -8018,7 +8019,7 @@ func TestJavaSDKLibrary_ImportPreferred(t *testing.T) { }) // The bar library should depend on the implementation jar. - barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac") + barLibrary := ctx.ModuleForTests("bar", "android_common_apex10000").Rule("javac") if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { t.Errorf("expected %q, found %#q", expected, actual) } @@ -8498,31 +8499,6 @@ func TestApexWithJniLibs(t *testing.T) { ensureListContains(t, names(rule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so") } -func TestApexMutatorsDontRunIfDisabled(t *testing.T) { - t.Parallel() - ctx := testApex(t, ` - apex { - name: "myapex", - key: "myapex.key", - updatable: false, - } - apex_key { - name: "myapex.key", - public_key: "testkey.avbpubkey", - private_key: "testkey.pem", - } - `, - android.FixtureModifyConfig(func(config android.Config) { - delete(config.Targets, android.Android) - config.AndroidCommonTarget = android.Target{} - }), - ) - - if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) { - t.Errorf("Expected variants: %v, but got: %v", expected, got) - } -} - func TestAppBundle(t *testing.T) { t.Parallel() ctx := testApex(t, ` @@ -8609,16 +8585,16 @@ func TestAppSetBundlePrebuilt(t *testing.T) { ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress) // Check that the extractor produces the correct output file from the correct input file. - extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.hwasan.apks" + extractorOutput := "out/soong/.intermediates/myapex/android_common_prebuilt_myapex/extracted/myapex.hwasan.apks" - m := ctx.ModuleForTests("myapex", "android_common_myapex") + m := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") extractedApex := m.Output(extractorOutput) android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings()) // Ditto for the apex. - m = ctx.ModuleForTests("myapex", "android_common_myapex") - copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_myapex/foo_v2.apex") + m = ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") + copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_prebuilt_myapex/foo_v2.apex") android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String()) } @@ -8637,10 +8613,10 @@ func TestApexSetApksModuleAssignment(t *testing.T) { } `) - m := ctx.ModuleForTests("myapex", "android_common_myapex") + m := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") // Check that the extractor produces the correct apks file from the input module - extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.apks" + extractorOutput := "out/soong/.intermediates/myapex/android_common_prebuilt_myapex/extracted/myapex.apks" extractedApex := m.Output(extractorOutput) android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings()) @@ -9029,7 +9005,7 @@ func TestApexSet(t *testing.T) { }), ) - m := ctx.ModuleForTests("myapex", "android_common_myapex") + m := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") // Check extract_apks tool parameters. extractedApex := m.Output("extracted/myapex.apks") @@ -9044,7 +9020,7 @@ func TestApexSet(t *testing.T) { t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) } - m = ctx.ModuleForTests("myapex", "android_common_myapex") + m = ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") a := m.Module().(*ApexSet) expectedOverrides := []string{"foo"} actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] @@ -9071,7 +9047,7 @@ func TestApexSet_NativeBridge(t *testing.T) { }), ) - m := ctx.ModuleForTests("myapex", "android_common_myapex") + m := ctx.ModuleForTests("myapex", "android_common_prebuilt_myapex") // Check extract_apks tool parameters. No native bridge arch expected extractedApex := m.Output("extracted/myapex.apks") @@ -9179,7 +9155,7 @@ func TestApexKeysTxtOverrides(t *testing.T) { ctx.ModuleForTests("myapex", "android_common_myapex").Output("apexkeys.txt")) ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`) content = android.ContentFromFileRuleForTests(t, ctx, - ctx.ModuleForTests("myapex_set", "android_common_myapex_set").Output("apexkeys.txt")) + ctx.ModuleForTests("myapex_set", "android_common_prebuilt_myapex_set").Output("apexkeys.txt")) ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) } @@ -9358,7 +9334,7 @@ func TestApexSet_ShouldRespectCompressedApexFlag(t *testing.T) { }), ) - build := ctx.ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex").Output("com.company.android.myapex.apex") + build := ctx.ModuleForTests("com.company.android.myapex", "android_common_prebuilt_com.android.myapex").Output("com.company.android.myapex.apex") if compressionEnabled { ensureEquals(t, build.Rule.String(), "android/soong/android.Cp") } else { @@ -11305,12 +11281,12 @@ func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) { { desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt", selectedApexContributions: "foo.prebuilt.contributions", - expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_com.android.foo/deapexer/javalib/framework-foo.jar", + expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_prebuilt_com.android.foo/deapexer/javalib/framework-foo.jar", }, { desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt", selectedApexContributions: "foo.prebuilt.v2.contributions", - expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_com.android.foo/deapexer/javalib/framework-foo.jar", + expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_prebuilt_com.android.foo/deapexer/javalib/framework-foo.jar", }, } @@ -11355,7 +11331,7 @@ func TestInstallationRulesForMultipleApexPrebuilts(t *testing.T) { // for a mainline module family, check that only the flagged soong module is visible to make checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleName string, hiddenModuleNames []string) { variation := func(moduleName string) string { - ret := "android_common_com.android.foo" + ret := "android_common_prebuilt_com.android.foo" if moduleName == "com.google.android.foo" { ret = "android_common_com.google.android.foo" } @@ -11502,8 +11478,8 @@ func TestInstallationRulesForMultipleApexPrebuiltsWithoutSource(t *testing.T) { checkHideFromMake := func(t *testing.T, ctx *android.TestContext, visibleModuleNames []string, hiddenModuleNames []string) { variation := func(moduleName string) string { ret := "android_common_com.android.adservices" - if moduleName == "com.google.android.foo" { - ret = "android_common_com.google.android.foo_com.google.android.foo" + if moduleName == "com.google.android.adservices" || moduleName == "com.google.android.adservices.v2" { + ret = "android_common_prebuilt_com.android.adservices" } return ret } @@ -11578,13 +11554,13 @@ func TestInstallationRulesForMultipleApexPrebuiltsWithoutSource(t *testing.T) { expectedHiddenModuleNames: []string{"com.google.android.adservices", "com.google.android.adservices.v2"}, }, { - desc: "Prebuilt apex prebuilt_com.android.foo is selected", + desc: "Prebuilt apex prebuilt_com.android.adservices is selected", selectedApexContributions: "adservices.prebuilt.contributions", expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices"}, expectedHiddenModuleNames: []string{"com.google.android.adservices.v2"}, }, { - desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected", + desc: "Prebuilt apex prebuilt_com.android.adservices.v2 is selected", selectedApexContributions: "adservices.prebuilt.v2.contributions", expectedVisibleModuleNames: []string{"com.android.adservices", "com.google.android.adservices.v2"}, expectedHiddenModuleNames: []string{"com.google.android.adservices"}, diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index c7674b58a..60d111f67 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -292,6 +292,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) { apex_available: [ "com.android.art", ], + min_sdk_version: "33", compile_dex: true, } `, content, prefer) @@ -420,7 +421,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) { java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"), ).RunTest(t) - ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_com.android.art", []string{ + ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_prebuilt_com.android.art", []string{ "etc/boot-image.prof", "javalib/bar.jar", "javalib/foo.jar", @@ -431,6 +432,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) { `art-bootclasspath-fragment`, `com.android.art.key`, `dex2oatd`, + `prebuilt_art-bootclasspath-fragment`, `prebuilt_com.android.art`, }) @@ -589,13 +591,13 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { t.Parallel() result := preparers.RunTestWithBp(t, fmt.Sprintf(bp, "enabled: false,")) - java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{ + java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_prebuilt_com.android.art", []string{ `all_apex_contributions`, `dex2oatd`, `prebuilt_art-bootclasspath-fragment`, }) - java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{ + java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_prebuilt_com.android.art", []string{ `all_apex_contributions`, `dex2oatd`, `prebuilt_bar`, @@ -862,8 +864,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", }) @@ -1039,8 +1041,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", }) @@ -1213,8 +1215,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", }) @@ -1364,8 +1366,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/builder.go b/apex/builder.go index 63efa6332..03a0bb902 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -1105,7 +1105,7 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) { } depInfos := android.DepNameToDepInfoMap{} - a.WalkPayloadDepsProxy(ctx, func(ctx android.BaseModuleContext, from, to android.ModuleProxy, externalDep bool) bool { + a.WalkPayloadDeps(ctx, func(ctx android.BaseModuleContext, from android.Module, to android.ApexModule, externalDep bool) bool { if from.Name() == to.Name() { // This can happen for cc.reuseObjTag. We are not interested in tracking this. // As soon as the dependency graph crosses the APEX boundary, don't go further. diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go index 55f1475f7..c2f2fc5b9 100644 --- a/apex/classpath_element_test.go +++ b/apex/classpath_element_test.go @@ -205,8 +205,6 @@ func TestCreateClasspathElements(t *testing.T) { myFragment := result.Module("mybootclasspath-fragment", "android_common_myapex") myBar := result.Module("bar", "android_common_apex10000") - other := result.Module("othersdklibrary", "android_common_apex10000") - otherApexLibrary := result.Module("otherapexlibrary", "android_common_apex10000") platformFoo := result.Module("quuz", "android_common") @@ -240,7 +238,11 @@ func TestCreateClasspathElements(t *testing.T) { t.Run("art:baz, art:quuz, my:bar, foo", func(t *testing.T) { t.Parallel() ctx := newCtx() - elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, artQuuz, myBar, platformFoo}, []android.Module{artFragment, myFragment}) + elements := java.CreateClasspathElements(ctx, + []android.Module{artBaz, artQuuz, myBar, platformFoo}, + []android.Module{artFragment, myFragment}, + map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, + map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz, artQuuz), expectFragmentElement(myFragment, myBar), @@ -249,32 +251,16 @@ func TestCreateClasspathElements(t *testing.T) { assertElementsEquals(t, "elements", expectedElements, elements) }) - // Verify that CreateClasspathElements detects when an apex has multiple fragments. - t.Run("multiple fragments for same apex", func(t *testing.T) { - t.Parallel() - ctx := newCtx() - elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{artFragment, artFragment}) - android.FailIfNoMatchingErrors(t, "apex com.android.art has multiple fragments, art-bootclasspath-fragment{.*} and art-bootclasspath-fragment{.*}", ctx.errs) - expectedElements := java.ClasspathElements{} - assertElementsEquals(t, "elements", expectedElements, elements) - }) - - // Verify that CreateClasspathElements detects when a library is in multiple fragments. - t.Run("library from multiple fragments", func(t *testing.T) { - t.Parallel() - ctx := newCtx() - elements := java.CreateClasspathElements(ctx, []android.Module{other}, []android.Module{artFragment, myFragment}) - android.FailIfNoMatchingErrors(t, "library othersdklibrary{.*} is in two separate fragments, art-bootclasspath-fragment{.*} and mybootclasspath-fragment{.*}", ctx.errs) - expectedElements := java.ClasspathElements{} - assertElementsEquals(t, "elements", expectedElements, elements) - }) - // Verify that CreateClasspathElements detects when a fragment's contents are not contiguous and // are separated by a library from another fragment. t.Run("discontiguous separated by fragment", func(t *testing.T) { t.Parallel() ctx := newCtx() - elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, myBar, artQuuz, platformFoo}, []android.Module{artFragment, myFragment}) + elements := java.CreateClasspathElements(ctx, + []android.Module{artBaz, myBar, artQuuz, platformFoo}, + []android.Module{artFragment, myFragment}, + map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, + map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz, artQuuz), expectFragmentElement(myFragment, myBar), @@ -289,7 +275,11 @@ func TestCreateClasspathElements(t *testing.T) { t.Run("discontiguous separated by library", func(t *testing.T) { t.Parallel() ctx := newCtx() - elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, platformFoo, artQuuz, myBar}, []android.Module{artFragment, myFragment}) + elements := java.CreateClasspathElements(ctx, + []android.Module{artBaz, platformFoo, artQuuz, myBar}, + []android.Module{artFragment, myFragment}, + map[android.Module]string{artBaz: "com.android.art", artQuuz: "com.android.art", myBar: "myapex"}, + map[string]android.Module{"com.android.art": artFragment, "myapex": myFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz, artQuuz), expectLibraryElement(platformFoo), @@ -305,7 +295,11 @@ func TestCreateClasspathElements(t *testing.T) { t.Run("no fragment for apex", func(t *testing.T) { t.Parallel() ctx := newCtx() - elements := java.CreateClasspathElements(ctx, []android.Module{artBaz, otherApexLibrary}, []android.Module{artFragment}) + elements := java.CreateClasspathElements(ctx, + []android.Module{artBaz, otherApexLibrary}, + []android.Module{artFragment}, + map[android.Module]string{artBaz: "com.android.art", otherApexLibrary: "otherapex"}, + map[string]android.Module{"com.android.art": artFragment}) expectedElements := java.ClasspathElements{ expectFragmentElement(artFragment, artBaz), } diff --git a/apex/container_test.go b/apex/container_test.go index 395793f61..bf9445b49 100644 --- a/apex/container_test.go +++ b/apex/container_test.go @@ -29,6 +29,7 @@ var checkContainerMatch = func(t *testing.T, name string, container string, expe func TestApexDepsContainers(t *testing.T) { t.Parallel() + t.Skip("TODO(b/394955484): this probably has to be moved to a check by the apex") result := android.GroupFixturePreparers( prepareForApexTest, java.PrepareForTestWithJavaSdkLibraryFiles, @@ -166,6 +167,7 @@ func TestApexDepsContainers(t *testing.T) { func TestNonUpdatableApexDepsContainers(t *testing.T) { t.Parallel() + t.Skip("TODO(b/394955484): this probably has to be moved to a check by the apex") result := android.GroupFixturePreparers( prepareForApexTest, java.PrepareForTestWithJavaSdkLibraryFiles, @@ -281,6 +283,7 @@ func TestNonUpdatableApexDepsContainers(t *testing.T) { func TestUpdatableAndNonUpdatableApexesIdenticalMinSdkVersion(t *testing.T) { t.Parallel() + t.Skip("TODO(b/394955484): this probably has to be moved to a check by the apex") result := android.GroupFixturePreparers( prepareForApexTest, java.PrepareForTestWithJavaSdkLibraryFiles, diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go index 6fa1fe225..5abad81fc 100644 --- a/apex/dexpreopt_bootjars_test.go +++ b/apex/dexpreopt_bootjars_test.go @@ -215,7 +215,7 @@ func TestDexpreoptBootJarsWithPrebuiltArtApex(t *testing.T) { "out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar", "out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar", "out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar", - "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof", + "out/soong/.intermediates/prebuilt_com.android.art/android_common_prebuilt_com.android.art/deapexer/etc/boot-image.prof", "out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof", "out/soong/dexpreopt/uffd_gc_flag.txt", } @@ -401,12 +401,12 @@ func TestDexpreoptProfileWithMultiplePrebuiltArtApexes(t *testing.T) { { desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt", selectedArtApexContributions: "art.prebuilt.contributions", - expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof", + expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art/android_common_prebuilt_com.android.art/deapexer/etc/boot-image.prof", }, { desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt", selectedArtApexContributions: "art.prebuilt.v2.contributions", - expectedProfile: "out/soong/.intermediates/com.android.art.v2/android_common_com.android.art/deapexer/etc/boot-image.prof", + expectedProfile: "out/soong/.intermediates/com.android.art.v2/android_common_prebuilt_com.android.art/deapexer/etc/boot-image.prof", }, } for _, tc := range testCases { diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go index 8b5fce91c..d79af8660 100644 --- a/apex/platform_bootclasspath_test.go +++ b/apex/platform_bootclasspath_test.go @@ -23,7 +23,6 @@ import ( "android/soong/dexpreopt" "android/soong/java" - "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -240,8 +239,8 @@ func TestPlatformBootclasspath_LegacyPrebuiltFragment(t *testing.T) { pbcp := result.Module("myplatform-bootclasspath", "android_common") info, _ := android.OtherModuleProvider(result, pbcp, java.MonolithicHiddenAPIInfoProvider) - android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) - android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) + android.AssertArrayString(t, "stub flags", []string{"prebuilt-stub-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_prebuilt_myapex/modular-hiddenapi/signature-patterns.csv"}, info.StubFlagSubsets.RelativeToTop()) + android.AssertArrayString(t, "all flags", []string{"prebuilt-all-flags.csv:out/soong/.intermediates/mybootclasspath-fragment/android_common_prebuilt_myapex/modular-hiddenapi/signature-patterns.csv"}, info.FlagSubsets.RelativeToTop()) } func TestPlatformBootclasspathDependencies(t *testing.T) { @@ -388,7 +387,7 @@ func TestPlatformBootclasspathDependencies(t *testing.T) { }) // Make sure that the myplatform-bootclasspath has the correct dependencies. - CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ + java.CheckPlatformBootclasspathDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ // source vs prebuilt selection metadata module `platform:all_apex_contributions`, @@ -401,17 +400,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 +428,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) @@ -479,6 +478,7 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { name: "myapex", src: "myapex.apex", exported_bootclasspath_fragments: ["mybootclasspath-fragment"], + prefer: true, } // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred @@ -544,12 +544,11 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { java.CheckPlatformBootclasspathModules(t, result, "myplatform-bootclasspath", []string{ // The configured contents of BootJars. - "myapex:prebuilt_foo", - "myapex:bar", + "prebuilt_myapex:prebuilt_foo", }) // Make sure that the myplatform-bootclasspath has the correct dependencies. - CheckModuleDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ + java.CheckPlatformBootclasspathDependencies(t, result.TestContext, "myplatform-bootclasspath", "android_common", []string{ // source vs prebuilt selection metadata module `platform:all_apex_contributions`, @@ -561,39 +560,17 @@ 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 platform_bootclasspath intentionally adds dependencies on both source and prebuilt - // modules when available as it does not know which one will be preferred. - "myapex:foo", - "myapex:prebuilt_foo", - - // Only a source module exists. - "myapex:bar", + // The prebuilt library via the apex. + "platform:prebuilt_myapex", - // The fragments. - "myapex:mybootclasspath-fragment", - "myapex:prebuilt_mybootclasspath-fragment", + // The fragments via the apex. + "platform:prebuilt_myapex", // Impl lib of sdk_library for transitive srcjar generation "platform:foo.impl", }) } -// CheckModuleDependencies checks the dependencies of the selected module against the expected list. -// -// The expected list must be a list of strings of the form "<apex>:<module>", where <apex> is the -// name of the apex, or platform is it is not part of an apex and <module> is the module name. -func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) { - t.Helper() - module := ctx.ModuleForTests(name, variant).Module() - modules := []android.Module{} - ctx.VisitDirectDeps(module, func(m blueprint.Module) { - modules = append(modules, m.(android.Module)) - }) - - pairs := java.ApexNamePairsFromModules(ctx, modules) - android.AssertDeepEquals(t, "module dependencies", expected, pairs) -} - // TestPlatformBootclasspath_IncludesRemainingApexJars verifies that any apex boot jar is present in // platform_bootclasspath's classpaths.proto config, if the apex does not generate its own config // by setting generate_classpaths_proto property to false. @@ -665,7 +642,7 @@ func TestBootJarNotInApex(t *testing.T) { prepareForTestWithMyapex, java.FixtureConfigureApexBootJars("myapex:foo"), ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( - `dependency "foo" of "myplatform-bootclasspath" missing variant`)). + `module "myplatform-bootclasspath" variant ".*": failed to find module "foo" in apex "myapex"`)). RunTestWithBp(t, ` apex { name: "myapex", diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 4fa43bada..e7d92c3a4 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -291,6 +291,7 @@ func (p *prebuiltCommon) prebuiltApexContentsDeps(ctx android.BottomUpMutatorCon for _, dep := range p.prebuiltCommonProperties.Exported_bootclasspath_fragments { prebuiltDep := android.PrebuiltNameFromSource(dep) ctx.AddDependency(module, exportedBootclasspathFragmentTag, prebuiltDep) + ctx.AddDependency(module, fragmentInApexTag, prebuiltDep) } for _, dep := range p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments { @@ -309,89 +310,34 @@ func (p *prebuiltCommon) IncomingDepIsInSameApex(tag blueprint.DependencyTag) bo return true } -// apexInfoMutator marks any modules for which this apex exports a file as requiring an apex -// specific variant and checks that they are supported. -// -// The apexMutator will ensure that the ApexInfo objects passed to BuildForApex(ApexInfo) are -// associated with the apex specific variant using the ApexInfoProvider for later retrieval. -// -// Unlike the source apex module type the prebuilt_apex module type cannot share compatible variants -// across prebuilt_apex modules. That is because there is no way to determine whether two -// prebuilt_apex modules that export files for the same module are compatible. e.g. they could have -// been built from different source at different times or they could have been built with different -// build options that affect the libraries. -// -// While it may be possible to provide sufficient information to determine whether two prebuilt_apex -// modules were compatible it would be a lot of work and would not provide much benefit for a couple -// of reasons: -// - The number of prebuilt_apex modules that will be exporting files for the same module will be -// low as the prebuilt_apex only exports files for the direct dependencies that require it and -// very few modules are direct dependencies of multiple prebuilt_apex modules, e.g. there are a -// few com.android.art* apex files that contain the same contents and could export files for the -// same modules but only one of them needs to do so. Contrast that with source apex modules which -// need apex specific variants for every module that contributes code to the apex, whether direct -// or indirect. -// - The build cost of a prebuilt_apex variant is generally low as at worst it will involve some -// extra copying of files. Contrast that with source apex modules that has to build each variant -// from source. -func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) { - // Collect the list of dependencies. - var dependencies []android.ApexModule - mctx.WalkDeps(func(child, parent android.Module) bool { - // If the child is not in the same apex as the parent then exit immediately and do not visit - // any of the child's dependencies. - if !android.IsDepInSameApex(mctx, parent, child) { - return false - } - - tag := mctx.OtherModuleDependencyTag(child) - depName := mctx.OtherModuleName(child) +func (p *prebuiltCommon) checkExportedDependenciesArePrebuilts(ctx android.ModuleContext) { + ctx.VisitDirectDeps(func(dep android.Module) { + tag := ctx.OtherModuleDependencyTag(dep) + depName := ctx.OtherModuleName(dep) if exportedTag, ok := tag.(exportedDependencyTag); ok { propertyName := exportedTag.name // It is an error if the other module is not a prebuilt. - if !android.IsModulePrebuilt(child) { - mctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName) - return false + if !android.IsModulePrebuilt(dep) { + ctx.PropertyErrorf(propertyName, "%q is not a prebuilt module", depName) } // It is an error if the other module is not an ApexModule. - if _, ok := child.(android.ApexModule); !ok { - mctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName) - return false + if _, ok := dep.(android.ApexModule); !ok { + ctx.PropertyErrorf(propertyName, "%q is not usable within an apex", depName) } } - // Ignore any modules that do not implement ApexModule as they cannot have an APEX specific - // variant. - if _, ok := child.(android.ApexModule); !ok { - return false - } - - // Strip off the prebuilt_ prefix if present before storing content to ensure consistent - // behavior whether there is a corresponding source module present or not. - depName = android.RemoveOptionalPrebuiltPrefix(depName) - - // Add the module to the list of dependencies that need to have an APEX variant. - dependencies = append(dependencies, child.(android.ApexModule)) - - return true }) +} - android.SetProvider(mctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{}) - - // Create an ApexInfo for the prebuilt_apex. - apexVariationName := p.ApexVariationName() - apexInfo := android.ApexInfo{ - ApexVariationName: apexVariationName, - InApexVariants: []string{apexVariationName}, +// generateApexInfo returns an android.ApexInfo configuration suitable for dependencies of this apex. +func (p *prebuiltCommon) generateApexInfo(ctx generateApexInfoContext) android.ApexInfo { + return android.ApexInfo{ + ApexVariationName: "prebuilt_" + p.ApexVariationName(), + BaseApexName: p.ApexVariationName(), ForPrebuiltApex: true, } - - // Mark the dependencies of this module as requiring a variant for this module. - for _, am := range dependencies { - am.BuildForApex(apexInfo) - } } type Prebuilt struct { @@ -595,10 +541,22 @@ func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { p.prebuiltApexContentsDeps(ctx) } -var _ ApexInfoMutator = (*Prebuilt)(nil) +var _ ApexTransitionMutator = (*Prebuilt)(nil) + +func (p *Prebuilt) ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo { + return []android.ApexInfo{p.generateApexInfo(ctx)} +} + +func (p *Prebuilt) ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo { + return sourceInfo +} + +func (p *Prebuilt) ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo { + return p.generateApexInfo(ctx) +} -func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) { - p.apexInfoMutator(mctx) +func (p *Prebuilt) ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) { + android.SetProvider(ctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{}) } // creates the build rules to deapex the prebuilt, and returns a deapexerInfo @@ -664,6 +622,8 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { validateApexClasspathFragments(ctx) } + p.checkExportedDependenciesArePrebuilts(ctx) + p.apexKeysPath = writeApexKeys(ctx, p) // TODO(jungjw): Check the key validity. p.inputApex = android.PathForModuleSrc(ctx, p.properties.prebuiltApexSelector(ctx, ctx.Module())) @@ -824,10 +784,22 @@ func (a *ApexSet) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { a.prebuiltApexContentsDeps(ctx) } -var _ ApexInfoMutator = (*ApexSet)(nil) +var _ ApexTransitionMutator = (*ApexSet)(nil) + +func (a *ApexSet) ApexTransitionMutatorSplit(ctx android.BaseModuleContext) []android.ApexInfo { + return []android.ApexInfo{a.generateApexInfo(ctx)} +} + +func (a *ApexSet) ApexTransitionMutatorOutgoing(ctx android.OutgoingTransitionContext, sourceInfo android.ApexInfo) android.ApexInfo { + return sourceInfo +} + +func (a *ApexSet) ApexTransitionMutatorIncoming(ctx android.IncomingTransitionContext, outgoingInfo android.ApexInfo) android.ApexInfo { + return a.generateApexInfo(ctx) +} -func (a *ApexSet) ApexInfoMutator(mctx android.TopDownMutatorContext) { - a.apexInfoMutator(mctx) +func (a *ApexSet) ApexTransitionMutatorMutate(ctx android.BottomUpMutatorContext, info android.ApexInfo) { + android.SetProvider(ctx, android.ApexBundleInfoProvider, android.ApexBundleInfo{}) } func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index c643a8c98..81f287fd6 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -280,19 +280,19 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { ctx := result.TestContext - java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{ + java.CheckModuleDependencies(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{ `all_apex_contributions`, `dex2oatd`, `prebuilt_mysystemserverclasspathfragment`, }) - java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{ + java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_prebuilt_myapex", []string{ `all_apex_contributions`, `prebuilt_bar`, `prebuilt_foo`, }) - ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{ + ensureExactDeapexedContents(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{ "javalib/foo.jar", "javalib/bar.jar", "javalib/bar.jar.prof", @@ -440,13 +440,13 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) { ctx := result.TestContext - java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_myapex", []string{ + java.CheckModuleDependencies(t, ctx, "mysystemserverclasspathfragment", "android_common_prebuilt_myapex", []string{ `all_apex_contributions`, `prebuilt_bar`, `prebuilt_foo`, }) - ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{ + ensureExactDeapexedContents(t, ctx, "myapex", "android_common_prebuilt_myapex", []string{ "javalib/foo.jar", "javalib/bar.jar", "javalib/bar.jar.prof", @@ -465,7 +465,7 @@ func assertProfileGuided(t *testing.T, ctx *android.TestContext, moduleName stri } func assertProfileGuidedPrebuilt(t *testing.T, ctx *android.TestContext, apexName string, moduleName string, expected bool) { - dexpreopt := ctx.ModuleForTests(apexName, "android_common_"+apexName).Rule("dexpreopt." + moduleName) + dexpreopt := ctx.ModuleForTests(apexName, "android_common_prebuilt_"+apexName).Rule("dexpreopt." + moduleName) actual := strings.Contains(dexpreopt.RuleParams.Command, "--profile-file=") if expected != actual { t.Fatalf("Expected profile-guided to be %v, got %v", expected, actual) |