Validate monolithic and modular hidden API flags are consistent
This makes sure that where there is overlap between the hidden API
flags generated for a module and the monolithic flags that they are
identical. That ensures that the modular hidden API flags will be
compatible with previous releases that relied on the monolithic flags.
Bug: 179354495
Test: m out/soong/.intermediates/art/build/boot/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv
m out/soong/hiddenapi/hiddenapi-flags.csv
- Create some inconsistencies between the above two files.
m out/soong/hiddenapi/hiddenapi-flags.csv.valid
Change-Id: Iaf9e23cef63e221608955d89dc8d496bcc70c86e
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 8174524..d1d9a75 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -15,6 +15,8 @@
package java
import (
+ "strings"
+
"android/soong/android"
"github.com/google/blueprint"
)
@@ -378,6 +380,16 @@
var hiddenAPIFlagFileInfoProvider = blueprint.NewProvider(hiddenAPIFlagFileInfo{})
+// pathForValidation creates a path of the same type as the supplied type but with a name of
+// <path>.valid.
+//
+// e.g. If path is an OutputPath for out/soong/hiddenapi/hiddenapi-flags.csv then this will return
+// an OutputPath for out/soong/hiddenapi/hiddenapi-flags.csv.valid
+func pathForValidation(ctx android.PathContext, path android.WritablePath) android.WritablePath {
+ extWithoutLeadingDot := strings.TrimPrefix(path.Ext(), ".")
+ return path.ReplaceExtension(ctx, extWithoutLeadingDot+".valid")
+}
+
// buildRuleToGenerateHiddenApiFlags creates a rule to create the monolithic hidden API flags from
// the flags from all the modules, the stub flags, augmented with some additional configuration
// files.
@@ -392,6 +404,30 @@
// 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) {
+
+ // The file which is used to record that the flags file is valid.
+ var validFile android.WritablePath
+
+ // 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 allFlagsPaths := flagFileInfo.AllFlagsPaths; len(allFlagsPaths) > 0 {
+ // The flags file generated by the rule created by this method needs to be validated to ensure
+ // that it is consistent with the flag files generated by the individual fragments.
+
+ validFile = pathForValidation(ctx, outputPath)
+
+ // Create a rule to validate the output from the following rule.
+ rule := android.NewRuleBuilder(pctx, ctx)
+ rule.Command().
+ BuiltTool("verify_overlaps").
+ Input(outputPath).
+ Inputs(allFlagsPaths).
+ // If validation passes then update the file that records that.
+ Text("&& touch").Output(validFile)
+ rule.Build(name+"Validation", desc+" validation")
+ }
+
+ // Create the rule that will generate the flag files.
tempPath := tempPathForRestat(ctx, outputPath)
rule := android.NewRuleBuilder(pctx, ctx)
command := rule.Command().
@@ -410,6 +446,14 @@
commitChangeForRestat(rule, tempPath, outputPath)
+ if validFile != nil {
+ // Add the file that indicates that the file generated by this is valid.
+ //
+ // This will cause the validation rule above to be run any time that the output of this rule
+ // changes but the validation will run in parallel with other rules that depend on this file.
+ command.Validation(validFile)
+ }
+
rule.Build(name, desc)
}