diff --git a/android/deapexer.go b/android/deapexer.go index 9290481d4..bed657464 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -69,6 +69,8 @@ import ( // The information exported by the `deapexer` module, access it using `DeapxerInfoProvider`. type DeapexerInfo struct { + apexModuleName string + // map from the name of an exported file from a prebuilt_apex to the path to that file. The // exported file name is the apex relative path, e.g. javalib/core-libart.jar. // @@ -76,6 +78,11 @@ type DeapexerInfo struct { exports map[string]WritablePath } +// ApexModuleName returns the name of the APEX module that provided the info. +func (i DeapexerInfo) ApexModuleName() string { + return i.apexModuleName +} + // PrebuiltExportPath provides the path, or nil if not available, of a file exported from the // prebuilt_apex that created this ApexInfo. // @@ -95,9 +102,10 @@ var DeapexerProvider = blueprint.NewProvider(DeapexerInfo{}) // for use with a prebuilt_apex module. // // See apex/deapexer.go for more information. -func NewDeapexerInfo(exports map[string]WritablePath) DeapexerInfo { +func NewDeapexerInfo(apexModuleName string, exports map[string]WritablePath) DeapexerInfo { return DeapexerInfo{ - exports: exports, + apexModuleName: apexModuleName, + exports: exports, } } @@ -133,3 +141,20 @@ type RequiresFilesFromPrebuiltApexTag interface { // Method that differentiates this interface from others. RequiresFilesFromPrebuiltApex() } + +// FindDeapexerProviderForModule searches through the direct dependencies of the current context +// module for a DeapexerTag dependency and returns its DeapexerInfo. If there is an error then it is +// reported with ctx.ModuleErrorf and nil is returned. +func FindDeapexerProviderForModule(ctx ModuleContext) *DeapexerInfo { + var di *DeapexerInfo + ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) { + p := ctx.OtherModuleProvider(m, DeapexerProvider).(DeapexerInfo) + di = &p + }) + if di != nil { + return di + } + ai := ctx.Provider(ApexInfoProvider).(ApexInfo) + ctx.ModuleErrorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName) + return nil +} diff --git a/apex/apex_test.go b/apex/apex_test.go index 1f9bd5a2e..420489e68 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4859,8 +4859,11 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { // Make sure that dexpreopt can access dex implementation files from the prebuilt. ctx := testDexpreoptWithApexes(t, bp, "", transform) + deapexerName := deapexerModuleName("myapex") + android.AssertStringEquals(t, "APEX module name from deapexer name", "myapex", apexModuleName(deapexerName)) + // Make sure that the deapexer has the correct input APEX. - deapexer := ctx.ModuleForTests("myapex.deapexer", "android_common") + deapexer := ctx.ModuleForTests(deapexerName, "android_common") rule := deapexer.Rule("deapexer") if expected, actual := []string{"myapex-arm64.apex"}, android.NormalizePathsForTesting(rule.Implicits); !reflect.DeepEqual(expected, actual) { t.Errorf("expected: %q, found: %q", expected, actual) diff --git a/apex/deapexer.go b/apex/deapexer.go index 2c1835aa4..8c9030a85 100644 --- a/apex/deapexer.go +++ b/apex/deapexer.go @@ -15,6 +15,8 @@ package apex import ( + "strings" + "android/soong/android" ) @@ -75,6 +77,17 @@ type Deapexer struct { inputApex android.Path } +// Returns the name of the deapexer module corresponding to an APEX module with the given name. +func deapexerModuleName(apexModuleName string) string { + return apexModuleName + ".deapexer" +} + +// Returns the name of the APEX module corresponding to an deapexer module with +// the given name. This reverses deapexerModuleName. +func apexModuleName(deapexerModuleName string) string { + return strings.TrimSuffix(deapexerModuleName, ".deapexer") +} + func privateDeapexerFactory() android.Module { module := &Deapexer{} module.AddProperties(&module.properties, &module.selectedApexProperties) @@ -113,7 +126,8 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { // apex relative path to extracted file path available for other modules. if len(exports) > 0 { // Make the information available for other modules. - ctx.SetProvider(android.DeapexerProvider, android.NewDeapexerInfo(exports)) + di := android.NewDeapexerInfo(apexModuleName(ctx.ModuleName()), exports) + ctx.SetProvider(android.DeapexerProvider, di) // Create a sorted list of the files that this exports. exportedPaths = android.SortedUniquePaths(exportedPaths) @@ -131,6 +145,6 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { for _, p := range exportedPaths { command.Output(p.(android.WritablePath)) } - builder.Build("deapexer", "deapex "+ctx.ModuleName()) + builder.Build("deapexer", "deapex "+apexModuleName(ctx.ModuleName())) } } diff --git a/apex/prebuilt.go b/apex/prebuilt.go index d7be9a9e1..d59f8bfec 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -631,10 +631,6 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam ) } -func deapexerModuleName(baseModuleName string) string { - return baseModuleName + ".deapexer" -} - func apexSelectorModuleName(baseModuleName string) string { return baseModuleName + ".apex.selector" } diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index b13e2dba4..79c73ca87 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -954,23 +954,11 @@ func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and return nil } - var deapexerModule android.Module - ctx.VisitDirectDeps(func(module android.Module) { - tag := ctx.OtherModuleDependencyTag(module) - // Save away the `deapexer` module on which this depends, if any. - if tag == android.DeapexerTag { - deapexerModule = module - } - }) - - if deapexerModule == nil { - // This should never happen as a variant for a prebuilt_apex is only created if the - // deapexer module has been configured to export the dex implementation jar for this module. - ctx.ModuleErrorf("internal error: module does not depend on a `deapexer` module") - return nil + di := android.FindDeapexerProviderForModule(ctx) + if di == nil { + return nil // An error has been reported by FindDeapexerProviderForModule. } - di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) files := bootImageFilesByArch{} for _, variant := range imageConfig.apexVariants() { arch := variant.target.Arch.ArchType diff --git a/java/java.go b/java/java.go index cfed1c893..b2c199992 100644 --- a/java/java.go +++ b/java/java.go @@ -1319,7 +1319,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) var flags javaBuilderFlags - var deapexerModule android.Module ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) @@ -1340,11 +1339,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } addCLCFromDep(ctx, module, j.classLoaderContexts) - - // Save away the `deapexer` module on which this depends, if any. - if tag == android.DeapexerTag { - deapexerModule = module - } }) if Bool(j.properties.Installable) { @@ -1359,16 +1353,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // obtained from the associated deapexer module. ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if ai.ForPrebuiltApex { - if deapexerModule == nil { - // This should never happen as a variant for a prebuilt_apex is only created if the - // deapexer module has been configured to export the dex implementation jar for this module. - ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q", - j.Name(), ai.ApexVariationName) - return - } - // Get the path of the dex implementation jar from the `deapexer` module. - di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) + di := android.FindDeapexerProviderForModule(ctx) + if di == nil { + return // An error has been reported by FindDeapexerProviderForModule. + } if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { dexJarFile := makeDexJarPathFromPath(dexOutputPath) j.dexJarFile = dexJarFile @@ -1379,7 +1368,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { // This should never happen as a variant for a prebuilt_apex is only created if the // prebuilt_apex has been configured to export the java library dex file. - ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name()) + ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) } } else if Bool(j.dexProperties.Compile_dex) { sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) diff --git a/java/sdk_library.go b/java/sdk_library.go index 0fcce1752..0c61f94fd 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2157,8 +2157,6 @@ func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) { func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { module.generateCommonBuildActions(ctx) - var deapexerModule android.Module - // Assume that source module(sdk_library) is installed in //framework module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar") @@ -2187,11 +2185,6 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to) } } - - // Save away the `deapexer` module on which this depends, if any. - if tag == android.DeapexerTag { - deapexerModule = to - } }) // Populate the scope paths with information from the properties. @@ -2210,15 +2203,11 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo // obtained from the associated deapexer module. ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) if ai.ForPrebuiltApex { - if deapexerModule == nil { - // This should never happen as a variant for a prebuilt_apex is only created if the - // deapxer module has been configured to export the dex implementation jar for this module. - ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q", - module.Name(), ai.ApexVariationName) - } - // Get the path of the dex implementation jar from the `deapexer` module. - di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) + di := android.FindDeapexerProviderForModule(ctx) + if di == nil { + return // An error has been reported by FindDeapexerProviderForModule. + } if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil { dexJarFile := makeDexJarPathFromPath(dexOutputPath) module.dexJarFile = dexJarFile @@ -2235,7 +2224,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo } else { // This should never happen as a variant for a prebuilt_apex is only created if the // prebuilt_apex has been configured to export the java library dex file. - ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name()) + ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) } } }