Generate monolithic hidden API files direct from class jars

Previously, the monolithic hidden API files, e.g. hiddenapi-index.csv
file, were generated in two steps. First, each module created its own
files using the information in its class jars. Then, the monolithic
files were created by merging those module specific files into a larger
file.

This change switches to generating the monolithic files directly from
the class jar files and bypassing the intermediate files.

In order to ensure that this change did not change the monolithic files
it is necessary for the hiddenapi-metadata.csv to go through a
reformatting step. Hopefully, this will be able to be removed in a
follow up change.

Bug: 179354495
Test: verified that the monolithic out/soong/hiddenapi/... files are
      unchanged by this change
Change-Id: I5a78e747516014b7c0f402a4b4431b14be6a84b2
This commit is contained in:
Paul Duffin 2021-05-14 10:38:00 +01:00
parent 850e61f234
commit 537ea3d04c
6 changed files with 120 additions and 187 deletions

View File

@ -4564,7 +4564,7 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
checkHiddenAPIIndexInputs := func(t *testing.T, ctx *android.TestContext, expectedInputs string) {
t.Helper()
platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
indexRule := platformBootclasspath.Rule("platform-bootclasspath-monolithic-hiddenapi-index")
indexRule := platformBootclasspath.Rule("monolithic_hidden_API_index")
java.CheckHiddenAPIRuleInputs(t, expectedInputs, indexRule)
}
@ -4602,10 +4602,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
.intermediates/libbar/android_common_myapex/hiddenapi/index.csv
.intermediates/libfoo/android_common_myapex/hiddenapi/index.csv
.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar
.intermediates/libfoo/android_common_myapex/combined/libfoo.jar
`)
})
@ -4636,10 +4636,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the apex_set contributes to the hiddenapi index file.
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
.intermediates/libbar/android_common_myapex/hiddenapi/index.csv
.intermediates/libfoo/android_common_myapex/hiddenapi/index.csv
.intermediates/libbar.stubs/android_common/combined/libbar.stubs.jar
.intermediates/libfoo/android_common_myapex/combined/libfoo.jar
`)
})
@ -4743,10 +4743,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
.intermediates/prebuilt_libbar/android_common_myapex/hiddenapi/index.csv
.intermediates/prebuilt_libfoo/android_common_myapex/hiddenapi/index.csv
.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar
.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar
`)
})
@ -4810,10 +4810,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
.intermediates/libbar/android_common_myapex/hiddenapi/index.csv
.intermediates/libfoo/android_common_apex10000/hiddenapi/index.csv
.intermediates/libbar/android_common_myapex/javac/libbar.jar
.intermediates/libfoo/android_common_apex10000/javac/libfoo.jar
`)
})
@ -4879,10 +4879,10 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
// Verify the correct module jars contribute to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
.intermediates/prebuilt_libbar/android_common_myapex/hiddenapi/index.csv
.intermediates/prebuilt_libfoo/android_common_myapex/hiddenapi/index.csv
.intermediates/prebuilt_libbar.stubs/android_common/combined/libbar.stubs.jar
.intermediates/prebuilt_libfoo/android_common_myapex/combined/libfoo.jar
`)
})
}

View File

@ -129,7 +129,7 @@ type commonBootclasspathFragment interface {
// produceHiddenAPIAllFlagsFile produces the all-flags.csv and intermediate files.
//
// Updates the supplied flagFileInfo with the paths to the generated files set.
produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo)
produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo)
}
func bootclasspathFragmentFactory() android.Module {
@ -465,9 +465,11 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// Resolve the properties to paths.
flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)
// Delegate the production of the hidden API all flags file to a module type specific method.
common := ctx.Module().(commonBootclasspathFragment)
common.produceHiddenAPIAllFlagsFile(ctx, contents, stubJarsByKind, &flagFileInfo)
common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, stubJarsByKind, &flagFileInfo)
// Store the information for use by platform_bootclasspath.
ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
@ -475,7 +477,7 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
// for the fragment.
func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
// If no stubs have been provided then don't perform hidden API processing. This is a temporary
// workaround to avoid existing bootclasspath_fragments that do not provide stubs breaking the
// build.
@ -722,7 +724,7 @@ func (module *prebuiltBootclasspathFragmentModule) Name() string {
// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
// specified.
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, _ []android.Module, _ map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
pathsForOptionalSrc := func(src *string) android.Paths {
if src == nil {
// TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.

View File

@ -91,31 +91,22 @@ type hiddenAPI struct {
classesJarPaths android.Paths
}
func (h *hiddenAPI) flagsCSV() android.Path {
return h.flagsCSVPath
}
func (h *hiddenAPI) metadataCSV() android.Path {
return h.metadataCSVPath
}
func (h *hiddenAPI) bootDexJar() android.Path {
return h.bootDexJarPath
}
func (h *hiddenAPI) indexCSV() android.Path {
return h.indexCSVPath
}
func (h *hiddenAPI) classesJars() android.Paths {
return h.classesJarPaths
}
// hiddenAPIModule is the interface a module that embeds the hiddenAPI structure must implement.
type hiddenAPIModule interface {
android.Module
hiddenAPIIntf
}
type hiddenAPIIntf interface {
bootDexJar() android.Path
flagsCSV() android.Path
indexCSV() android.Path
metadataCSV() android.Path
classesJars() android.Paths
}
@ -312,6 +303,7 @@ func buildRuleToGenerateIndex(ctx android.ModuleContext, desc string, classesJar
BuiltTool("merge_csv").
Flag("--zip_input").
Flag("--key_field signature").
FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
FlagWithOutput("--output=", indexCSV).
Inputs(classesJars)
rule.Build(desc, desc)

View File

@ -417,12 +417,12 @@ func pathForValidation(ctx android.PathContext, path android.WritablePath) andro
// an entry for every single member in the dex implementation jars of the individual modules. Every
// signature in any of the other files MUST be included in this file.
//
// moduleSpecificFlagsPaths are the paths to the flags files generated by each module using
// information from the baseFlagsPath as well as from annotations within the source.
// annotationFlags is the path to the annotation flags file generated from annotation information
// in each module.
//
// augmentationInfo is a struct containing paths to files that augment the information provided by
// the moduleSpecificFlagsPaths.
func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, moduleSpecificFlagsPaths android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
// flagFileInfo is a struct containing paths to files that augment the information provided by
// the annotationFlags.
func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlags android.Path, flagFileInfo *hiddenAPIFlagFileInfo) {
// The file which is used to record that the flags file is valid.
var validFile android.WritablePath
@ -452,7 +452,7 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st
command := rule.Command().
BuiltTool("generate_hiddenapi_lists").
FlagWithInput("--csv ", baseFlagsPath).
Inputs(moduleSpecificFlagsPaths).
Input(annotationFlags).
FlagWithOutput("--output ", tempPath)
// Add the options for the different categories of flag files.
@ -490,31 +490,18 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st
// * metadata.csv
// * index.csv
// * all-flags.csv
func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []hiddenAPIModule, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
hiddenApiSubDir := "modular-hiddenapi"
bootDexJars := android.Paths{}
classesJars := android.Paths{}
for _, module := range contents {
if hiddenAPI, ok := module.(hiddenAPIIntf); ok {
classesJars = append(classesJars, hiddenAPI.classesJars()...)
bootDexJar := hiddenAPI.bootDexJar()
if bootDexJar == nil {
ctx.ModuleErrorf("module %s does not provide a dex jar", module)
} else {
bootDexJars = append(bootDexJars, bootDexJar)
}
} else {
ctx.ModuleErrorf("module %s does not implement hiddenAPIIntf", module)
}
}
// Generate the stub-flags.csv.
bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, contents)
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlagsCSV, bootDexJars, stubJarsByKind)
rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
// Extract the classes jars from the contents.
classesJars := extractClassJarsFromHiddenAPIModules(ctx, contents)
// Generate the set of flags from the annotations in the source code.
annotationFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "annotation-flags.csv")
buildRuleToGenerateAnnotationFlags(ctx, "modular hiddenapi annotation flags", classesJars, stubFlagsCSV, annotationFlagsCSV)
@ -523,7 +510,7 @@ func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext
metadataCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "metadata.csv")
buildRuleToGenerateMetadata(ctx, "modular hiddenapi metadata", classesJars, stubFlagsCSV, metadataCSV)
// Generate the index file from the annotations in the source code.
// Generate the index file from the CSV files in the classes jars.
indexCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "index.csv")
buildRuleToGenerateIndex(ctx, "modular hiddenapi index", classesJars, indexCSV)
@ -537,7 +524,7 @@ func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext
// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
// files.
outputPath := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, android.Paths{annotationFlagsCSV}, flagFileInfo)
buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, annotationFlagsCSV, flagFileInfo)
// Store the paths in the info for use by other modules and sdk snapshot generation.
flagFileInfo.StubFlagsPaths = android.Paths{stubFlagsCSV}
@ -546,3 +533,41 @@ func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext
flagFileInfo.IndexPaths = android.Paths{indexCSV}
flagFileInfo.AllFlagsPaths = android.Paths{outputPath}
}
// gatherHiddenAPIModuleFromContents gathers the hiddenAPIModule from the supplied contents.
func gatherHiddenAPIModuleFromContents(ctx android.ModuleContext, contents []android.Module) []hiddenAPIModule {
hiddenAPIModules := []hiddenAPIModule{}
for _, module := range contents {
if hiddenAPI, ok := module.(hiddenAPIModule); ok {
hiddenAPIModules = append(hiddenAPIModules, hiddenAPI)
} else if _, ok := module.(*DexImport); ok {
// Ignore this for the purposes of hidden API processing
} else {
ctx.ModuleErrorf("module %s does not implement hiddenAPIModule", module)
}
}
return hiddenAPIModules
}
// extractBootDexJarsFromHiddenAPIModules extracts the boot dex jars from the supplied modules.
func extractBootDexJarsFromHiddenAPIModules(ctx android.ModuleContext, contents []hiddenAPIModule) android.Paths {
bootDexJars := android.Paths{}
for _, module := range contents {
bootDexJar := module.bootDexJar()
if bootDexJar == nil {
ctx.ModuleErrorf("module %s does not provide a dex jar", module)
} else {
bootDexJars = append(bootDexJars, bootDexJar)
}
}
return bootDexJars
}
// extractClassJarsFromHiddenAPIModules extracts the class jars from the supplied modules.
func extractClassJarsFromHiddenAPIModules(ctx android.ModuleContext, contents []hiddenAPIModule) android.Paths {
classesJars := android.Paths{}
for _, module := range contents {
classesJars = append(classesJars, module.classesJars()...)
}
return classesJars
}

View File

@ -257,17 +257,6 @@ func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleCont
return defaultBootImageConfig(ctx)
}
// hiddenAPISupportingModule encapsulates the information provided by any module that contributes to
// the hidden API processing.
type hiddenAPISupportingModule struct {
module android.Module
bootDexJar android.Path
flagsCSV android.Path
indexCSV android.Path
metadataCSV android.Path
}
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) {
@ -290,67 +279,6 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
return
}
// nilPathHandler will check the supplied path and if it is nil then it will either immediately
// report an error, or it will defer the error reporting until it is actually used, depending
// whether missing dependencies are allowed.
var nilPathHandler func(path android.Path, name string, module android.Module) android.Path
if ctx.Config().AllowMissingDependencies() {
nilPathHandler = func(path android.Path, name string, module android.Module) android.Path {
if path == nil {
outputPath := android.PathForModuleOut(ctx, "missing", module.Name(), name)
path = outputPath
// Create an error rule that pretends to create the output file but will actually fail if it
// is run.
ctx.Build(pctx, android.BuildParams{
Rule: android.ErrorRule,
Output: outputPath,
Args: map[string]string{
"error": fmt.Sprintf("missing hidden API file: %s for %s", name, module),
},
})
}
return path
}
} else {
nilPathHandler = func(path android.Path, name string, module android.Module) android.Path {
if path == nil {
ctx.ModuleErrorf("module %s does not provide a %s file", module, name)
}
return path
}
}
hiddenAPISupportingModules := []hiddenAPISupportingModule{}
for _, module := range modules {
if h, ok := module.(hiddenAPIIntf); ok {
hiddenAPISupportingModule := hiddenAPISupportingModule{
module: module,
bootDexJar: nilPathHandler(h.bootDexJar(), "bootDexJar", module),
flagsCSV: nilPathHandler(h.flagsCSV(), "flagsCSV", module),
indexCSV: nilPathHandler(h.indexCSV(), "indexCSV", module),
metadataCSV: nilPathHandler(h.metadataCSV(), "metadataCSV", module),
}
// If any errors were reported when trying to populate the hiddenAPISupportingModule struct
// then don't add it to the list.
if ctx.Failed() {
continue
}
hiddenAPISupportingModules = append(hiddenAPISupportingModules, hiddenAPISupportingModule)
} else if _, ok := module.(*DexImport); ok {
// Ignore this for the purposes of hidden API processing
} else {
ctx.ModuleErrorf("module %s of type %s does not support hidden API processing", module, ctx.OtherModuleType(module))
}
}
moduleSpecificFlagsPaths := android.Paths{}
for _, module := range hiddenAPISupportingModules {
moduleSpecificFlagsPaths = append(moduleSpecificFlagsPaths, module.flagsCSV)
}
flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
for _, fragment := range fragments {
if ctx.OtherModuleHasProvider(fragment, hiddenAPIFlagFileInfoProvider) {
@ -362,61 +290,53 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
// Store the information for testing.
ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
outputPath := hiddenAPISingletonPaths(ctx).flags
baseFlagsPath := hiddenAPISingletonPaths(ctx).stubFlags
buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "hiddenapi flags", outputPath, baseFlagsPath, moduleSpecificFlagsPaths, &flagFileInfo)
b.generateHiddenAPIStubFlagsRules(ctx, hiddenAPISupportingModules)
b.generateHiddenAPIIndexRules(ctx, hiddenAPISupportingModules)
b.generatedHiddenAPIMetadataRules(ctx, hiddenAPISupportingModules)
}
func (b *platformBootclasspathModule) generateHiddenAPIStubFlagsRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
bootDexJars := android.Paths{}
for _, module := range modules {
bootDexJars = append(bootDexJars, module.bootDexJar)
}
hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, modules)
sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx, nil)
outputPath := hiddenAPISingletonPaths(ctx).stubFlags
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, outputPath, bootDexJars, sdkKindToStubPaths)
// Generate the monolithic stub-flags.csv file.
bootDexJars := extractBootDexJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJars, sdkKindToStubPaths)
rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
// Extract the classes jars from the contents.
classesJars := extractClassJarsFromHiddenAPIModules(ctx, hiddenAPIModules)
// Generate the annotation-flags.csv file from all the module annotations.
annotationFlags := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "annotation-flags.csv")
buildRuleToGenerateAnnotationFlags(ctx, "monolithic hiddenapi flags", classesJars, stubFlags, annotationFlags)
// Generate the monotlithic hiddenapi-flags.csv file.
allFlags := hiddenAPISingletonPaths(ctx).flags
buildRuleToGenerateHiddenApiFlags(ctx, "hiddenAPIFlagsFile", "hiddenapi flags", allFlags, stubFlags, annotationFlags, &flagFileInfo)
// Generate an intermediate monolithic hiddenapi-metadata.csv file directly from the annotations
// in the source code.
intermediateMetadataCSV := android.PathForModuleOut(ctx, "hiddenapi-monolithic", "intermediate-metadata.csv")
buildRuleToGenerateMetadata(ctx, "monolithic hidden API metadata", classesJars, stubFlags, intermediateMetadataCSV)
// Reformat the intermediate file to add | quotes just in case that is important for the tools
// that consume the metadata file.
// TODO(b/179354495): Investigate whether it is possible to remove this reformatting step.
metadataCSV := hiddenAPISingletonPaths(ctx).metadata
b.buildRuleMergeCSV(ctx, "reformat monolithic hidden API metadata", android.Paths{intermediateMetadataCSV}, metadataCSV)
// Generate the monolithic hiddenapi-index.csv file directly from the CSV files in the classes
// jars.
indexCSV := hiddenAPISingletonPaths(ctx).index
buildRuleToGenerateIndex(ctx, "monolithic hidden API index", classesJars, indexCSV)
}
func (b *platformBootclasspathModule) generateHiddenAPIIndexRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
indexes := android.Paths{}
for _, module := range modules {
indexes = append(indexes, module.indexCSV)
}
func (b *platformBootclasspathModule) buildRuleMergeCSV(ctx android.ModuleContext, desc string, inputPaths android.Paths, outputPath android.WritablePath) {
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
BuiltTool("merge_csv").
Flag("--key_field signature").
FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
Inputs(indexes)
rule.Build("platform-bootclasspath-monolithic-hiddenapi-index", "monolithic hidden API index")
}
func (b *platformBootclasspathModule) generatedHiddenAPIMetadataRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
metadataCSVFiles := android.Paths{}
for _, module := range modules {
metadataCSVFiles = append(metadataCSVFiles, module.metadataCSV)
}
rule := android.NewRuleBuilder(pctx, ctx)
outputPath := hiddenAPISingletonPaths(ctx).metadata
rule.Command().
BuiltTool("merge_csv").
Flag("--key_field signature").
FlagWithOutput("--output=", outputPath).
Inputs(metadataCSVFiles)
Inputs(inputPaths)
rule.Build("platform-bootclasspath-monolithic-hiddenapi-metadata", "monolithic hidden API metadata")
rule.Build(desc, desc)
}
// generateHiddenApiMakeVars generates make variables needed by hidden API related make rules, e.g.

View File

@ -427,20 +427,14 @@ func TestPlatformBootclasspath_HiddenAPIMonolithicFiles(t *testing.T) {
}
`)
platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
indexRule := platformBootclasspath.Rule("platform-bootclasspath-monolithic-hiddenapi-index")
CheckHiddenAPIRuleInputs(t, `
.intermediates/bar/android_common/hiddenapi/index.csv
.intermediates/foo/android_common/hiddenapi/index.csv
`,
indexRule)
// Make sure that the foo-hiddenapi-annotations.jar is included in the inputs to the rules that
// creates the index.csv file.
foo := result.ModuleForTests("foo", "android_common")
indexParams := foo.Output("hiddenapi/index.csv")
platformBootclasspath := result.ModuleForTests("myplatform-bootclasspath", "android_common")
indexRule := platformBootclasspath.Rule("monolithic_hidden_API_index")
CheckHiddenAPIRuleInputs(t, `
.intermediates/bar/android_common/javac/bar.jar
.intermediates/foo-hiddenapi-annotations/android_common/javac/foo-hiddenapi-annotations.jar
.intermediates/foo/android_common/javac/foo.jar
`, indexParams)
`,
indexRule)
}