From 3bae068ee572036457213026742878a209d3f45c Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 5 May 2021 18:03:47 +0100 Subject: [PATCH] Generalize deapexer module to export any files Previously, the deapexer module had to duplicate the java library specific logic for constructing the path to the library's dex file in the .apex file. That is not something that the deapexer needs to be aware of, all it needs is a list of files that should be exported. This change moves that logic into the prebuilt_apex/apex_set modules and generalizes the deapexer module so that it can export any files that are requested. The deapexer module does still need to know which java modules need access to exported files so it can add dependencies from them onto itself. However, it does not need to know what the type of the module is. Bug: 186455808 Test: m nothing m SOONG_CONFIG_art_module_source_build=false nothing Change-Id: I71c6f0f761efe3b6d66d54273786e98cd545811c --- apex/deapexer.go | 44 +++++++++++++++++++++++++++++--------------- apex/prebuilt.go | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/apex/deapexer.go b/apex/deapexer.go index 9bc57209e..c7cdbfabb 100644 --- a/apex/deapexer.go +++ b/apex/deapexer.go @@ -40,17 +40,29 @@ import ( // This is intentionally not registered by name as it is not intended to be used from within an // `Android.bp` file. -// Properties that are specific to `deapexer` but which need to be provided on the `prebuilt_apex` -// module.` -type DeapexerProperties struct { - // List of java libraries that are embedded inside this prebuilt APEX bundle and for which this - // APEX bundle will create an APEX variant and provide dex implementation jars for use by - // dexpreopt and boot jars package check. - Exported_java_libs []string +// 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.OutputFileProducer OutputFiles(tag) method + // to retrieve the path to the unpacked file. + Tag string - // List of bootclasspath fragments inside this prebuiltd APEX bundle and for which this APEX - // bundle will create an APEX variant. - Exported_bootclasspath_fragments []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 +// to make it clear that they are different. +type DeapexerProperties struct { + // List of common modules that may need access to files exported by this module. + // + // A common module in this sense is one that is not arch specific but uses a common variant for + // all architectures, e.g. java. + CommonModules []string + + // List of files exported from the .apex file by this module + ExportedFiles []DeapexerExportedFile } type SelectedApexProperties struct { @@ -81,7 +93,7 @@ func privateDeapexerFactory() android.Module { func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) { // Add dependencies from the java modules to which this exports files from the `.apex` file onto // this module so that they can access the `DeapexerInfo` object that this provides. - for _, lib := range p.properties.Exported_java_libs { + for _, lib := range p.properties.CommonModules { dep := prebuiltApexExportedModuleName(ctx, lib) ctx.AddReverseDependency(ctx.Module(), android.DeapexerTag, dep) } @@ -96,10 +108,12 @@ 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 _, l := range p.properties.Exported_java_libs { - // Populate the exports that this makes available. The path here must match the path of the - // file in the APEX created by apexFileForJavaModule(...). - exports[l+"{.dexjar}"] = deapexerOutput.Join(ctx, "javalib", l+".jar") + for _, e := range p.properties.ExportedFiles { + tag := e.Tag + path := e.Path + + // Populate the exports that this makes available. + exports[tag] = deapexerOutput.Join(ctx, path) } // If the prebuilt_apex exports any files then create a build rule that unpacks the apex using diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 92694c986..9d632a9b1 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -16,6 +16,7 @@ package apex import ( "fmt" + "path/filepath" "strconv" "strings" @@ -57,10 +58,18 @@ type sanitizedPrebuilt interface { } type prebuiltCommonProperties struct { - DeapexerProperties SelectedApexProperties ForceDisable bool `blueprint:"mutated"` + + // List of java libraries that are embedded inside this prebuilt APEX bundle and for which this + // APEX bundle will create an APEX variant and provide dex implementation jars for use by + // dexpreopt and boot jars package check. + Exported_java_libs []string + + // List of bootclasspath fragments inside this prebuilt APEX bundle and for which this APEX + // bundle will create an APEX variant. + Exported_bootclasspath_fragments []string } func (p *prebuiltCommon) Prebuilt() *android.Prebuilt { @@ -411,15 +420,20 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam } // Compute the deapexer properties from the transitive dependencies of this module. - deapexerProperties := &DeapexerProperties{} + javaModules := []string{} + exportedFiles := map[string]string{} ctx.WalkDeps(func(child, parent android.Module) bool { tag := ctx.OtherModuleDependencyTag(child) name := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) if java.IsBootclasspathFragmentContentDepTag(tag) || tag == exportedJavaLibTag { - deapexerProperties.Exported_java_libs = append(deapexerProperties.Exported_java_libs, name) + javaModules = append(javaModules, name) + + // 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(...). + exportedFiles[name+"{.dexjar}"] = filepath.Join("javalib", name+".jar") + } else if tag == exportedBootclasspathFragmentTag { - deapexerProperties.Exported_bootclasspath_fragments = append(deapexerProperties.Exported_bootclasspath_fragments, name) // Only visit the children of the bootclasspath_fragment for now. return true } @@ -427,9 +441,20 @@ func createDeapexerModuleIfNeeded(ctx android.TopDownMutatorContext, deapexerNam return false }) - // Remove any duplicates from the deapexer lists. - deapexerProperties.Exported_bootclasspath_fragments = android.FirstUniqueStrings(deapexerProperties.Exported_bootclasspath_fragments) - deapexerProperties.Exported_java_libs = android.FirstUniqueStrings(deapexerProperties.Exported_java_libs) + // Create properties for deapexer module. + deapexerProperties := &DeapexerProperties{ + // Remove any duplicates from the java modules lists as a module may be included via a direct + // dependency as well as transitive ones. + CommonModules: android.SortedUniqueStrings(javaModules), + } + + // Populate the exported files property in a fixed order. + for _, tag := range android.SortedStringKeys(exportedFiles) { + deapexerProperties.ExportedFiles = append(deapexerProperties.ExportedFiles, DeapexerExportedFile{ + Tag: tag, + Path: exportedFiles[tag], + }) + } props := struct { Name *string