Merge "Simplify deapexer support" am: 0d7f2d30b5

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1740316

Change-Id: I69b8e53916f848e9cb15f58756efba0b76c2bedd
This commit is contained in:
Paul Duffin 2021-06-20 18:29:09 +00:00 committed by Automerger Merge Worker
commit fd198583f0
6 changed files with 48 additions and 74 deletions

View file

@ -55,9 +55,9 @@ import (
// //
// The files that are passed to `deapexer` and those that are passed back have a unique identifier // 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: // 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: // 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 // The reason why the `deapexer` module is separate from the prebuilt_apex/apex_set is to avoid
// cycles. e.g. // cycles. e.g.
@ -70,7 +70,7 @@ import (
// The information exported by the `deapexer` module, access it using `DeapxerInfoProvider`. // The information exported by the `deapexer` module, access it using `DeapxerInfoProvider`.
type DeapexerInfo struct { type DeapexerInfo struct {
// map from the name of an exported file from a prebuilt_apex to the path to that file. The // 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 <module>{<tag>}. // exported file name is the apex relative path, e.g. javalib/core-libart.jar.
// //
// See Prebuilt.ApexInfoMutator for more information. // See Prebuilt.ApexInfoMutator for more information.
exports map[string]Path 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 // PrebuiltExportPath provides the path, or nil if not available, of a file exported from the
// prebuilt_apex that created this ApexInfo. // prebuilt_apex that created this ApexInfo.
// //
// The exported file is identified by the module name and the tag: // The exported file is identified by the apex relative path, e.g. "javalib/core-libart.jar".
// * 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.
// //
// See apex/deapexer.go for more information. // See apex/deapexer.go for more information.
func (i DeapexerInfo) PrebuiltExportPath(name, tag string) Path { func (i DeapexerInfo) PrebuiltExportPath(apexRelativePath string) Path {
path := i.exports[name+"{"+tag+"}"] path := i.exports[apexRelativePath]
return path return path
} }
@ -120,13 +116,13 @@ var DeapexerTag = deapexerTagStruct{}
// RequiredFilesFromPrebuiltApex must be implemented by modules that require files to be exported // RequiredFilesFromPrebuiltApex must be implemented by modules that require files to be exported
// from a prebuilt_apex/apex_set. // from a prebuilt_apex/apex_set.
type RequiredFilesFromPrebuiltApex interface { type RequiredFilesFromPrebuiltApex interface {
// RequiredFilesFromPrebuiltApex returns a map from the key (module name plus tag) to the required // RequiredFilesFromPrebuiltApex returns a list of the file paths (relative to the root of the
// path of the file within the prebuilt .apex file. // 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, // For each file path this will cause the file to be extracted out of the prebuilt .apex file, and
// and the path to the extracted file will be stored in the DeapexerInfo using that key, The path // the path to the extracted file will be stored in the DeapexerInfo using the APEX relative file
// can then be retrieved using the PrebuiltExportPath(name, tag) method. // path as the key, The path can then be retrieved using the PrebuiltExportPath(key) method.
RequiredFilesFromPrebuiltApex(ctx BaseModuleContext) map[string]string RequiredFilesFromPrebuiltApex(ctx BaseModuleContext) []string
} }
// Marker interface that identifies dependencies on modules that may require files from a prebuilt // Marker interface that identifies dependencies on modules that may require files from a prebuilt

View file

@ -40,16 +40,6 @@ import (
// This is intentionally not registered by name as it is not intended to be used from within an // This is intentionally not registered by name as it is not intended to be used from within an
// `Android.bp` file. // `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. // 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 // 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 CommonModules []string
// List of files exported from the .apex file by this module // 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 { type SelectedApexProperties struct {
@ -107,27 +99,23 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
exports := make(map[string]android.Path) exports := make(map[string]android.Path)
// Create mappings from name+tag to all the required exported paths. // Create mappings from apex relative path to the extracted file's path.
for _, e := range p.properties.ExportedFiles { exportedPaths := make(android.Paths, 0, len(exports))
tag := e.Tag for _, path := range p.properties.ExportedFiles {
path := e.Path
// Populate the exports that this makes available. // 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 // 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 // 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 { if len(exports) > 0 {
// Make the information available for other modules. // Make the information available for other modules.
ctx.SetProvider(android.DeapexerProvider, android.NewDeapexerInfo(exports)) ctx.SetProvider(android.DeapexerProvider, android.NewDeapexerInfo(exports))
// Create a sorted list of the files that this 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) exportedPaths = android.SortedUniquePaths(exportedPaths)
// The apex needs to export some files so create a ninja rule to unpack the apex and check that // The apex needs to export some files so create a ninja rule to unpack the apex and check that

View file

@ -554,8 +554,7 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam
// Compute the deapexer properties from the transitive dependencies of this module. // Compute the deapexer properties from the transitive dependencies of this module.
commonModules := []string{} commonModules := []string{}
exportedFilesByKey := map[string]string{} exportedFiles := []string{}
requiringModulesByKey := map[string]android.Module{}
ctx.WalkDeps(func(child, parent android.Module) bool { ctx.WalkDeps(func(child, parent android.Module) bool {
tag := ctx.OtherModuleDependencyTag(child) tag := ctx.OtherModuleDependencyTag(child)
@ -569,16 +568,7 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam
commonModules = append(commonModules, name) commonModules = append(commonModules, name)
requiredFiles := child.(android.RequiredFilesFromPrebuiltApex).RequiredFilesFromPrebuiltApex(ctx) requiredFiles := child.(android.RequiredFilesFromPrebuiltApex).RequiredFilesFromPrebuiltApex(ctx)
for k, v := range requiredFiles { exportedFiles = append(exportedFiles, 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
}
// Visit the dependencies of this module just in case they also require files from the // Visit the dependencies of this module just in case they also require files from the
// prebuilt apex. // prebuilt apex.
@ -596,12 +586,7 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam
} }
// Populate the exported files property in a fixed order. // Populate the exported files property in a fixed order.
for _, tag := range android.SortedStringKeys(exportedFilesByKey) { deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles)
deapexerProperties.ExportedFiles = append(deapexerProperties.ExportedFiles, DeapexerExportedFile{
Tag: tag,
Path: exportedFilesByKey[tag],
})
}
props := struct { props := struct {
Name *string Name *string

View file

@ -930,13 +930,12 @@ func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx and
} }
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo)
name := module.BaseModuleName()
for _, variant := range imageConfig.apexVariants() { for _, variant := range imageConfig.apexVariants() {
arch := variant.target.Arch.ArchType arch := variant.target.Arch.ArchType
for _, toPath := range variant.imagesDeps { 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. // Get the path to the file that the deapexer extracted from the prebuilt apex file.
tag := createBootImageTag(arch, toPath.Base()) fromPath := di.PrebuiltExportPath(apexRelativePath)
fromPath := di.PrebuiltExportPath(name, tag)
// Copy the file to the predefined location. // Copy the file to the predefined location.
ctx.Build(pctx, android.BuildParams{ 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 // 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. // 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) imageConfig := module.getImageConfig(ctx)
if imageConfig != nil { if imageConfig != nil {
// Add the boot image files, e.g. .art, .oat and .vdex files. // Add the boot image files, e.g. .art, .oat and .vdex files.
files := map[string]string{} files := []string{}
name := module.BaseModuleName()
for _, variant := range imageConfig.apexVariants() { for _, variant := range imageConfig.apexVariants() {
arch := variant.target.Arch.ArchType arch := variant.target.Arch.ArchType
for _, path := range variant.imagesDeps.Paths() { for _, path := range variant.imagesDeps.Paths() {
base := path.Base() base := path.Base()
tag := createBootImageTag(arch, base) files = append(files, apexRootRelativePathToBootImageFile(arch, base))
key := fmt.Sprintf("%s{%s}", name, tag)
files[key] = filepath.Join("javalib", arch.String(), base)
} }
} }
return files return files
@ -987,6 +983,10 @@ func (module *prebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex
return nil return nil
} }
func apexRootRelativePathToBootImageFile(arch android.ArchType, base string) string {
return filepath.Join("javalib", arch.String(), base)
}
var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltBootclasspathFragmentModule)(nil) var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltBootclasspathFragmentModule)(nil)
func prebuiltBootclasspathFragmentFactory() android.Module { func prebuiltBootclasspathFragmentFactory() android.Module {

View file

@ -1309,7 +1309,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Get the path of the dex implementation jar from the `deapexer` module. // Get the path of the dex implementation jar from the `deapexer` module.
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) 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 j.dexJarFile = dexOutputPath
// Initialize the hiddenapi structure. // 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 // 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 // java_sdk_library_import with the specified base module name requires to be exported from a
// prebuilt_apex/apex_set. // prebuilt_apex/apex_set.
func requiredFilesFromPrebuiltApexForImport(name string) map[string]string { func requiredFilesFromPrebuiltApexForImport(name string) []string {
// Add the dex implementation jar to the set of exported files. The path here must match the // Add the dex implementation jar to the set of exported files.
// path of the file in the APEX created by apexFileForJavaModule(...). return []string{
return map[string]string{ apexRootRelativePathToJavaLib(name),
name + "{.dexjar}": filepath.Join("javalib", name+".jar"),
} }
} }
// 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) 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() name := j.BaseModuleName()
return requiredFilesFromPrebuiltApexForImport(name) return requiredFilesFromPrebuiltApexForImport(name)
} }

View file

@ -2144,7 +2144,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
// Get the path of the dex implementation jar from the `deapexer` module. // Get the path of the dex implementation jar from the `deapexer` module.
di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) 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.dexJarFile = dexOutputPath
module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
} else { } else {
@ -2271,7 +2271,7 @@ func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths {
var _ android.RequiredFilesFromPrebuiltApex = (*SdkLibraryImport)(nil) 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() name := module.BaseModuleName()
return requiredFilesFromPrebuiltApexForImport(name) return requiredFilesFromPrebuiltApexForImport(name)
} }