From 67b9d61ac22cec5bb44c32fe483459144257943c Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Wed, 21 Jul 2021 17:38:47 +0100 Subject: Separate creation of signature patterns from overlap checking Previously, the signatures used to select the subset of the monolithic flags were simply the signatures read from the modular flags file. This change moves the creation of the signature list into a separate script that outputs the signatures to a file and then passes the path through Soong from the bootclasspath_fragment modules that create it to the platform_bootclasspath module that uses it to compare the modular flags against the monolithic flags. Currently, the signatures are the full signatures but follow up changes will replace them with patterns (hence the name) that avoids having to include implementation details in the hidden API flags that are output as part of a bootclasspath_fragment's snapshot. This change moves the stub flags related code next to the all flags related code as they are treated in a similar way. Bug: 194063708 Test: atest --host verify_overlaps_test signature_patterns_test m out/soong/hiddenapi/hiddenapi-flags.csv - manually change files to cause difference in flags to check that it detects the differences. Change-Id: I2855bf6d05c91b8a09591664185750361c7e644f --- java/hiddenapi_modular.go | 90 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 13 deletions(-) (limited to 'java/hiddenapi_modular.go') diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 86ab8253e..8a06a9969 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -297,7 +297,7 @@ func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android. // // The rule is initialized but not built so that the caller can modify it and select an appropriate // name. -func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, moduleStubFlagsPaths android.Paths) { +func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, bootDexJars android.Paths, input HiddenAPIFlagInput, stubFlagSubsets SignatureCsvSubsets) { // Singleton rule which applies hiddenapi on all boot class path dex files. rule := android.NewRuleBuilder(pctx, ctx) @@ -317,7 +317,7 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, // If no module stub flags paths are provided then this must be being called for a // bootclasspath_fragment and not the whole platform_bootclasspath. - if moduleStubFlagsPaths == nil { + if stubFlagSubsets == nil { // This is being run on a fragment of the bootclasspath. command.Flag("--fragment") } @@ -342,8 +342,8 @@ func buildRuleToGenerateHiddenAPIStubFlagsFile(ctx android.BuilderContext, name, // If there are stub flag files that have been generated by fragments on which this depends then // use them to validate the stub flag file generated by the rules created by this method. - if len(moduleStubFlagsPaths) > 0 { - validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, moduleStubFlagsPaths) + if len(stubFlagSubsets) > 0 { + validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets) // Add the file that indicates that the file generated by this is valid. // @@ -546,6 +546,20 @@ func (i *HiddenAPIInfo) mergeFromFragmentDeps(ctx android.ModuleContext, fragmen } } +// StubFlagSubset returns a SignatureCsvSubset that contains a path to a stub-flags.csv file and a +// path to a signature-patterns.csv file that defines a subset of the monolithic stub flags file, +// i.e. out/soong/hiddenapi/hiddenapi-stub-flags.txt, against which it will be compared. +func (i *HiddenAPIInfo) StubFlagSubset() SignatureCsvSubset { + return SignatureCsvSubset{i.StubFlagsPath, i.SignaturePatternsPath} +} + +// FlagSubset returns a SignatureCsvSubset that contains a path to an all-flags.csv file and a +// path to a signature-patterns.csv file that defines a subset of the monolithic flags file, i.e. +// out/soong/hiddenapi/hiddenapi-flags.csv, against which it will be compared. +func (i *HiddenAPIInfo) FlagSubset() SignatureCsvSubset { + return SignatureCsvSubset{i.AllFlagsPath, i.SignaturePatternsPath} +} + var HiddenAPIInfoProvider = blueprint.NewProvider(HiddenAPIInfo{}) // ModuleStubDexJars contains the stub dex jars provided by a single module. @@ -782,6 +796,10 @@ type HiddenAPIFlagOutput struct { // The path to the generated all-flags.csv file. AllFlagsPath android.Path + + // The path to the generated signature-patterns.txt file which defines the subset of the + // monolithic hidden API files provided in this. + SignaturePatternsPath android.Path } // bootDexJarByModule is a map from base module name (without prebuilt_ prefix) to the boot dex @@ -848,7 +866,7 @@ func pathForValidation(ctx android.PathContext, path android.WritablePath) andro // the annotationFlags. func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc string, outputPath android.WritablePath, baseFlagsPath android.Path, annotationFlagPaths android.Paths, - flagFilesByCategory FlagFilesByCategory, allFlagsPaths android.Paths, generatedRemovedDexSignatures android.OptionalPath) { + flagFilesByCategory FlagFilesByCategory, flagSubsets SignatureCsvSubsets, generatedRemovedDexSignatures android.OptionalPath) { // Create the rule that will generate the flag files. tempPath := tempPathForRestat(ctx, outputPath) @@ -877,8 +895,8 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st // If there are flag files that have been generated by fragments on which this depends then use // them to validate the flag file generated by the rules created by this method. - if len(allFlagsPaths) > 0 { - validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, allFlagsPaths) + if len(flagSubsets) > 0 { + validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets) // Add the file that indicates that the file generated by this is valid. // @@ -890,20 +908,66 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st rule.Build(name, desc) } +// SignatureCsvSubset describes a subset of a monolithic flags file, i.e. either +// out/soong/hiddenapi/hiddenapi-stub-flags.txt or out/soong/hiddenapi/hiddenapi-flags.csv +type SignatureCsvSubset struct { + // The path to the CSV file containing hidden API flags. + // + // It has the dex member signature as the first column, with flags, one per column, in the + // subsequent columns. + CsvFile android.Path + + // The path to the CSV file containing the signature patterns. + // + // It is a single column CSV file with the column containing a signature pattern. + SignaturePatternsFile android.Path +} + +type SignatureCsvSubsets []SignatureCsvSubset + +func (s SignatureCsvSubsets) RelativeToTop() []string { + result := []string{} + for _, subset := range s { + result = append(result, fmt.Sprintf("%s:%s", subset.CsvFile.RelativeToTop(), subset.SignaturePatternsFile.RelativeToTop())) + } + return result +} + +// buildRuleSignaturePatternsFile creates a rule to generate a file containing the set of signature +// patterns that will select a subset of the monolithic flags. +func buildRuleSignaturePatternsFile(ctx android.ModuleContext, flagsPath android.Path) android.Path { + patternsFile := android.PathForModuleOut(ctx, "modular-hiddenapi", "signature-patterns.csv") + // Create a rule to validate the output from the following rule. + rule := android.NewRuleBuilder(pctx, ctx) + rule.Command(). + BuiltTool("signature_patterns"). + FlagWithInput("--flags ", flagsPath). + FlagWithOutput("--output ", patternsFile) + rule.Build("hiddenAPISignaturePatterns", "hidden API signature patterns") + + return patternsFile +} + // buildRuleValidateOverlappingCsvFiles checks that the modular CSV files, i.e. the files generated // by the individual bootclasspath_fragment modules are subsets of the monolithic CSV file. -func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, modularFilePaths android.Paths) android.WritablePath { +func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string, monolithicFilePath android.WritablePath, csvSubsets SignatureCsvSubsets) android.WritablePath { // The file which is used to record that the flags file is valid. validFile := pathForValidation(ctx, monolithicFilePath) // Create a rule to validate the output from the following rule. rule := android.NewRuleBuilder(pctx, ctx) - rule.Command(). + command := rule.Command(). BuiltTool("verify_overlaps"). - Input(monolithicFilePath). - Inputs(modularFilePaths). - // If validation passes then update the file that records that. - Text("&& touch").Output(validFile) + Input(monolithicFilePath) + + for _, subset := range csvSubsets { + command. + Textf("%s:%s", subset.CsvFile, subset.SignaturePatternsFile). + Implicit(subset.CsvFile).Implicit(subset.SignaturePatternsFile) + } + + // If validation passes then update the file that records that. + command.Text("&& touch").Output(validFile) rule.Build(name+"Validation", desc+" validation") return validFile -- cgit v1.2.3-59-g8ed1b