From b4bbf2ca10cc8509e3ae0ab104e9e3b55861831b Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Thu, 17 Jun 2021 15:59:07 +0100 Subject: [PATCH] Simplify deapexer support Uses the apex relative path to the file as the identifier that is used to obtain the path to the corresponding file extracted from the apex. That is instead of a special constructed string id. Bug: 177892522 Test: m nothing Change-Id: I5dc77c8fb272bac289b8891d1eac801e541af1f5 --- android/deapexer.go | 28 ++++++++++++---------------- apex/deapexer.go | 32 ++++++++++---------------------- apex/prebuilt.go | 21 +++------------------ java/bootclasspath_fragment.go | 18 +++++++++--------- java/java.go | 19 ++++++++++++------- java/sdk_library.go | 4 ++-- 6 files changed, 48 insertions(+), 74 deletions(-) diff --git a/android/deapexer.go b/android/deapexer.go index c189dc114..de3f63582 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -55,9 +55,9 @@ import ( // // The files that are passed to `deapexer` and those that are passed back have a unique identifier // that links them together. e.g. If the `deapexer` is passed something like this: -// core-libart{.dexjar} -> javalib/core-libart.jar +// javalib/core-libart.jar -> javalib/core-libart.jar // it will return something like this: -// core-libart{.dexjar} -> out/soong/.....deapexer.../javalib/core-libart.jar +// javalib/core-libart.jar -> out/soong/.....deapexer.../javalib/core-libart.jar // // The reason why the `deapexer` module is separate from the prebuilt_apex/apex_set is to avoid // cycles. e.g. @@ -70,7 +70,7 @@ import ( // The information exported by the `deapexer` module, access it using `DeapxerInfoProvider`. type DeapexerInfo struct { // map from the name of an exported file from a prebuilt_apex to the path to that file. The - // exported file name is of the form {}. + // exported file name is the apex relative path, e.g. javalib/core-libart.jar. // // See Prebuilt.ApexInfoMutator for more information. exports map[string]Path @@ -79,15 +79,11 @@ type DeapexerInfo struct { // PrebuiltExportPath provides the path, or nil if not available, of a file exported from the // prebuilt_apex that created this ApexInfo. // -// The exported file is identified by the module name and the tag: -// * The module name is the name of the module that contributed the file when the .apex file -// referenced by the prebuilt_apex was built. It must be specified in one of the exported_... -// properties on the prebuilt_apex module. -// * The tag identifies the type of file and is dependent on the module type. +// The exported file is identified by the apex relative path, e.g. "javalib/core-libart.jar". // // See apex/deapexer.go for more information. -func (i DeapexerInfo) PrebuiltExportPath(name, tag string) Path { - path := i.exports[name+"{"+tag+"}"] +func (i DeapexerInfo) PrebuiltExportPath(apexRelativePath string) Path { + path := i.exports[apexRelativePath] return path } @@ -120,13 +116,13 @@ var DeapexerTag = deapexerTagStruct{} // RequiredFilesFromPrebuiltApex must be implemented by modules that require files to be exported // from a prebuilt_apex/apex_set. type RequiredFilesFromPrebuiltApex interface { - // RequiredFilesFromPrebuiltApex returns a map from the key (module name plus tag) to the required - // path of the file within the prebuilt .apex file. + // RequiredFilesFromPrebuiltApex returns a list of the file paths (relative to the root of the + // APEX's contents) that the implementing module requires from within a prebuilt .apex file. // - // For each key/file pair this will cause the file to be extracted out of the prebuilt .apex file, - // and the path to the extracted file will be stored in the DeapexerInfo using that key, The path - // can then be retrieved using the PrebuiltExportPath(name, tag) method. - RequiredFilesFromPrebuiltApex(ctx BaseModuleContext) map[string]string + // For each file path this will cause the file to be extracted out of the prebuilt .apex file, and + // the path to the extracted file will be stored in the DeapexerInfo using the APEX relative file + // path as the key, The path can then be retrieved using the PrebuiltExportPath(key) method. + RequiredFilesFromPrebuiltApex(ctx BaseModuleContext) []string } // Marker interface that identifies dependencies on modules that may require files from a prebuilt diff --git a/apex/deapexer.go b/apex/deapexer.go index 9088c4932..c70da1542 100644 --- a/apex/deapexer.go +++ b/apex/deapexer.go @@ -40,16 +40,6 @@ import ( // This is intentionally not registered by name as it is not intended to be used from within an // `Android.bp` file. -// DeapexerExportedFile defines the properties needed to expose a file from the deapexer module. -type DeapexerExportedFile struct { - // The tag parameter which must be passed to android.DeapexerInfo's PrebuiltExportPath(name, tag) - // method to retrieve the path to the unpacked file. - Tag string - - // The path within the APEX that needs to be exported. - Path string `android:"path"` -} - // DeapexerProperties specifies the properties supported by the deapexer module. // // As these are never intended to be supplied in a .bp file they use a different naming convention @@ -62,7 +52,9 @@ type DeapexerProperties struct { CommonModules []string // List of files exported from the .apex file by this module - ExportedFiles []DeapexerExportedFile + // + // Each entry is a path from the apex root, e.g. javalib/core-libart.jar. + ExportedFiles []string } type SelectedApexProperties struct { @@ -107,27 +99,23 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { exports := make(map[string]android.Path) - // Create mappings from name+tag to all the required exported paths. - for _, e := range p.properties.ExportedFiles { - tag := e.Tag - path := e.Path - + // Create mappings from apex relative path to the extracted file's path. + exportedPaths := make(android.Paths, 0, len(exports)) + for _, path := range p.properties.ExportedFiles { // Populate the exports that this makes available. - exports[tag] = deapexerOutput.Join(ctx, path) + extractedPath := deapexerOutput.Join(ctx, path) + exports[path] = extractedPath + exportedPaths = append(exportedPaths, extractedPath) } // If the prebuilt_apex exports any files then create a build rule that unpacks the apex using // deapexer and verifies that all the required files were created. Also, make the mapping from - // name+tag to path available for other modules. + // 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)) // Create a sorted list of the files that this exports. - exportedPaths := make(android.Paths, 0, len(exports)) - for _, p := range exports { - exportedPaths = append(exportedPaths, p) - } exportedPaths = android.SortedUniquePaths(exportedPaths) // The apex needs to export some files so create a ninja rule to unpack the apex and check that diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 435b6616b..32dcf54a4 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -549,8 +549,7 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam // Compute the deapexer properties from the transitive dependencies of this module. commonModules := []string{} - exportedFilesByKey := map[string]string{} - requiringModulesByKey := map[string]android.Module{} + exportedFiles := []string{} ctx.WalkDeps(func(child, parent android.Module) bool { tag := ctx.OtherModuleDependencyTag(child) @@ -564,16 +563,7 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam commonModules = append(commonModules, name) requiredFiles := child.(android.RequiredFilesFromPrebuiltApex).RequiredFilesFromPrebuiltApex(ctx) - for k, v := range requiredFiles { - if f, ok := exportedFilesByKey[k]; ok && f != v { - otherModule := requiringModulesByKey[k] - ctx.ModuleErrorf("inconsistent paths have been requested for key %q, %s requires path %s while %s requires path %s", - k, child, v, otherModule, f) - continue - } - exportedFilesByKey[k] = v - requiringModulesByKey[k] = child - } + exportedFiles = append(exportedFiles, requiredFiles...) // Visit the dependencies of this module just in case they also require files from the // prebuilt apex. @@ -591,12 +581,7 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam } // Populate the exported files property in a fixed order. - for _, tag := range android.SortedStringKeys(exportedFilesByKey) { - deapexerProperties.ExportedFiles = append(deapexerProperties.ExportedFiles, DeapexerExportedFile{ - Tag: tag, - Path: exportedFilesByKey[tag], - }) - } + deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles) props := struct { Name *string diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 317f3d2a0..cd0a216ca 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -930,13 +930,12 @@ func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and } di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) - name := module.BaseModuleName() for _, variant := range imageConfig.apexVariants() { arch := variant.target.Arch.ArchType for _, toPath := range variant.imagesDeps { + apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base()) // Get the path to the file that the deapexer extracted from the prebuilt apex file. - tag := createBootImageTag(arch, toPath.Base()) - fromPath := di.PrebuiltExportPath(name, tag) + fromPath := di.PrebuiltExportPath(apexRelativePath) // Copy the file to the predefined location. ctx.Build(pctx, android.BuildParams{ @@ -967,19 +966,16 @@ func createBootImageTag(arch android.ArchType, baseName string) string { // // If there is no image config associated with this fragment then it returns nil. Otherwise, it // returns the files that are listed in the image config. -func (module *prebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) map[string]string { +func (module *prebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { imageConfig := module.getImageConfig(ctx) if imageConfig != nil { // Add the boot image files, e.g. .art, .oat and .vdex files. - files := map[string]string{} - name := module.BaseModuleName() + files := []string{} for _, variant := range imageConfig.apexVariants() { arch := variant.target.Arch.ArchType for _, path := range variant.imagesDeps.Paths() { base := path.Base() - tag := createBootImageTag(arch, base) - key := fmt.Sprintf("%s{%s}", name, tag) - files[key] = filepath.Join("javalib", arch.String(), base) + files = append(files, apexRootRelativePathToBootImageFile(arch, base)) } } return files @@ -987,6 +983,10 @@ func (module *prebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex return nil } +func apexRootRelativePathToBootImageFile(arch android.ArchType, base string) string { + return filepath.Join("javalib", arch.String(), base) +} + var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltBootclasspathFragmentModule)(nil) func prebuiltBootclasspathFragmentFactory() android.Module { diff --git a/java/java.go b/java/java.go index 3b6c9c884..ae8adf277 100644 --- a/java/java.go +++ b/java/java.go @@ -1309,7 +1309,7 @@ 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(j.BaseModuleName(), ".dexjar"); dexOutputPath != nil { + if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { j.dexJarFile = dexOutputPath // Initialize the hiddenapi structure. @@ -1429,17 +1429,22 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, // requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or // java_sdk_library_import with the specified base module name requires to be exported from a // prebuilt_apex/apex_set. -func requiredFilesFromPrebuiltApexForImport(name string) map[string]string { - // Add the dex implementation jar to the set of exported files. The path here must match the - // path of the file in the APEX created by apexFileForJavaModule(...). - return map[string]string{ - name + "{.dexjar}": filepath.Join("javalib", name+".jar"), +func requiredFilesFromPrebuiltApexForImport(name string) []string { + // Add the dex implementation jar to the set of exported files. + return []string{ + apexRootRelativePathToJavaLib(name), } } +// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for +// the java library with the specified name. +func apexRootRelativePathToJavaLib(name string) string { + return filepath.Join("javalib", name+".jar") +} + var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil) -func (j *Import) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) map[string]string { +func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string { name := j.BaseModuleName() return requiredFilesFromPrebuiltApexForImport(name) } diff --git a/java/sdk_library.go b/java/sdk_library.go index 8bb7e0fcc..41097ca13 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2144,7 +2144,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo // Get the path of the dex implementation jar from the `deapexer` module. di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) - if dexOutputPath := di.PrebuiltExportPath(module.BaseModuleName(), ".dexjar"); dexOutputPath != nil { + if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil { module.dexJarFile = dexOutputPath module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) } else { @@ -2271,7 +2271,7 @@ func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths { var _ android.RequiredFilesFromPrebuiltApex = (*SdkLibraryImport)(nil) -func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) map[string]string { +func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { name := module.BaseModuleName() return requiredFilesFromPrebuiltApexForImport(name) }