From 8be1e6db1640d51ca4478fec2c4f20d71b115734 Mon Sep 17 00:00:00 2001 From: Martin Stjernholm Date: Wed, 15 Sep 2021 03:34:04 +0100 Subject: Propagate the dex jar path as an OptionalPath which is either valid or invalid with a message. This will allow propagating any error from the deapexer module for prebuilt APEXes to the location where the dex jars get used. It's only at those points that we can raise errors about not being able to extract files from the deapexer modules if they are invalid, and this way we avoid encoding knowledge there about why they may be invalid. To keep the refactoring limited it intentionally does not change any of the existing logic for when dexJarFiles are set or not (non-nil vs nil prior to this change), although there may be opportunity to use this for more conditions when dex jars aren't available. The refactoring is also not extended to dexpreopt.ClassLoaderContextMap. Test: m nothing Bug: 192006406 Change-Id: I68986dccd9a9b3fee4d24caa1947ea17a36caedc --- java/java.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'java/java.go') diff --git a/java/java.go b/java/java.go index 4a4486658..cfed1c893 100644 --- a/java/java.go +++ b/java/java.go @@ -219,7 +219,7 @@ type ApexDependency interface { // Provides build path and install path to DEX jars. type UsesLibraryDependency interface { - DexJarBuildPath() android.Path + DexJarBuildPath() OptionalDexJarPath DexJarInstallPath() android.Path ClassLoaderContexts() dexpreopt.ClassLoaderContextMap } @@ -1215,7 +1215,7 @@ type Import struct { properties ImportProperties // output file containing classes.dex and resources - dexJarFile android.Path + dexJarFile OptionalDexJarPath dexJarInstallFile android.Path combinedClasspathFile android.Path @@ -1370,11 +1370,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Get the path of the dex implementation jar from the `deapexer` module. di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { - j.dexJarFile = dexOutputPath + dexJarFile := makeDexJarPathFromPath(dexOutputPath) + j.dexJarFile = dexJarFile j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) // Initialize the hiddenapi structure. - j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil) + j.initHiddenAPI(ctx, dexJarFile, outputFile, nil) } 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. @@ -1407,12 +1408,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } // Initialize the hiddenapi structure. - j.initHiddenAPI(ctx, dexOutputFile, outputFile, j.dexProperties.Uncompress_dex) + j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex) // Encode hidden API flags in dex file. dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) } } @@ -1450,7 +1451,7 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths { return android.Paths{j.combinedClasspathFile} } -func (j *Import) DexJarBuildPath() android.Path { +func (j *Import) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } @@ -1595,7 +1596,7 @@ type DexImport struct { properties DexImportProperties - dexJarFile android.Path + dexJarFile OptionalDexJarPath dexpreopter @@ -1686,7 +1687,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { }) } - j.dexJarFile = dexOutputFile + j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) j.dexpreopt(ctx, dexOutputFile) @@ -1696,7 +1697,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -func (j *DexImport) DexJarBuildPath() android.Path { +func (j *DexImport) DexJarBuildPath() OptionalDexJarPath { return j.dexJarFile } @@ -1865,7 +1866,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, // from its CLC should be added to the current CLC. if sdkLib != nil { clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true, - dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) + dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) } -- cgit v1.2.3-59-g8ed1b From 4482560cc73f16f09eecda42751cf2f8dc72e7de Mon Sep 17 00:00:00 2001 From: Martin Stjernholm Date: Fri, 17 Sep 2021 01:44:12 +0100 Subject: Consolidate the code to resolve a deapexer module dependency. It will get more logic in upcoming CLs. Add a property to DeapexerInfo for the APEX name, for use in error messages. Test: m nothing Bug: 192006406 Change-Id: I957f3df8b34543a38cde38768dac93e78132d672 --- android/deapexer.go | 29 +++++++++++++++++++++++++++-- apex/apex_test.go | 5 ++++- apex/deapexer.go | 18 ++++++++++++++++-- apex/prebuilt.go | 4 ---- java/bootclasspath_fragment.go | 18 +++--------------- java/java.go | 21 +++++---------------- java/sdk_library.go | 21 +++++---------------- 7 files changed, 60 insertions(+), 56 deletions(-) (limited to 'java/java.go') 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()) } } } -- cgit v1.2.3-59-g8ed1b