diff --git a/compatibility_matrices/build/vintf_compatibility_matrix.go b/compatibility_matrices/build/vintf_compatibility_matrix.go index e48f9931ea..2772ba36e7 100644 --- a/compatibility_matrices/build/vintf_compatibility_matrix.go +++ b/compatibility_matrices/build/vintf_compatibility_matrix.go @@ -40,7 +40,15 @@ var ( Description: "assemble_vintf -i ${inputs}", }, "inputs") - kernelConfigTag = dependencyTag{name: "kernel-config"} + xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd", blueprint.RuleParams{ + Command: `$XmlLintCmd --schema $xsd $in > /dev/null && touch -a $out`, + CommandDeps: []string{"$XmlLintCmd"}, + Restat: true, + }, "xsd") + + kernelConfigTag = dependencyTag{name: "kernel-config"} + schemaTag = dependencyTag{name: "matrix-schema"} + schemaModuleName = "compatibility_matrix_schema" ) const ( @@ -62,11 +70,13 @@ type vintfCompatibilityMatrixRule struct { android.ModuleBase properties vintfCompatibilityMatrixProperties - genFile android.WritablePath + genFile android.WritablePath + additionalDependencies android.WritablePaths } func init() { pctx.HostBinToolVariable("assembleVintfCmd", "assemble_vintf") + pctx.HostBinToolVariable("XmlLintCmd", "xmllint") android.RegisterModuleType("vintf_compatibility_matrix", vintfCompatibilityMatrixFactory) } @@ -82,6 +92,42 @@ var _ android.AndroidMkDataProvider = (*vintfCompatibilityMatrixRule)(nil) func (g *vintfCompatibilityMatrixRule) DepsMutator(ctx android.BottomUpMutatorContext) { android.ExtractSourcesDeps(ctx, g.properties.Srcs) ctx.AddDependency(ctx.Module(), kernelConfigTag, g.properties.Kernel_configs...) + ctx.AddDependency(ctx.Module(), schemaTag, schemaModuleName) +} + +func (g *vintfCompatibilityMatrixRule) timestampFilePath(ctx android.ModuleContext, path android.Path) android.WritablePath { + return android.GenPathWithExt(ctx, "vintf-xmllint", path, "ts") +} + +func (g *vintfCompatibilityMatrixRule) generateValidateBuildAction(ctx android.ModuleContext, path android.Path, schema android.Path) { + timestamp := g.timestampFilePath(ctx, path) + ctx.Build(pctx, android.BuildParams{ + Rule: xmllintXsd, + Description: "xmllint-xsd", + Input: path, + Output: timestamp, + Implicit: schema, + Args: map[string]string{ + "xsd": schema.String(), + }, + }) + g.additionalDependencies = append(g.additionalDependencies, timestamp) +} + +func (g *vintfCompatibilityMatrixRule) getSchema(ctx android.ModuleContext) android.OptionalPath { + schemaModule := ctx.GetDirectDepWithTag(schemaModuleName, schemaTag) + sfp, ok := schemaModule.(android.SourceFileProducer) + if !ok { + ctx.ModuleErrorf("Implicit dependency %q has no srcs", ctx.OtherModuleName(schemaModule)) + return android.OptionalPath{} + } + + schemaSrcs := sfp.Srcs() + if len(schemaSrcs) != 1 { + ctx.PropertyErrorf(`srcs of implicit dependency %q has length %d != 1`, ctx.OtherModuleName(schemaModule), len(schemaSrcs)) + return android.OptionalPath{} + } + return android.OptionalPathForPath(schemaSrcs[0]) } func (g *vintfCompatibilityMatrixRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -91,7 +137,18 @@ func (g *vintfCompatibilityMatrixRule) GenerateAndroidBuildActions(ctx android.M outputFilename = g.Name() } + schema := g.getSchema(ctx) + if !schema.Valid() { + return + } + inputPaths := android.PathsForModuleSrc(ctx, g.properties.Srcs) + for _, srcPath := range inputPaths { + g.generateValidateBuildAction(ctx, srcPath, schema.Path()) + } + + // No need to validate matrices from kernel configs because they are generated by + // assemble_vintf. ctx.VisitDirectDepsWithTag(kernelConfigTag, func(m android.Module) { if k, ok := m.(*configs.KernelConfigRule); ok { inputPaths = append(inputPaths, k.OutputPath()) @@ -112,6 +169,7 @@ func (g *vintfCompatibilityMatrixRule) GenerateAndroidBuildActions(ctx android.M "inputs": strings.Join(inputPaths.Strings(), ":"), }, }) + g.generateValidateBuildAction(ctx, g.genFile, schema.Path()) ctx.InstallFile(android.PathForModuleInstall(ctx, "etc", relpath), outputFilename, g.genFile) } @@ -126,6 +184,9 @@ func (g *vintfCompatibilityMatrixRule) AndroidMk() android.AndroidMkData { if proptools.String(g.properties.Stem) != "" { fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", proptools.String(g.properties.Stem)) } + for _, path := range g.additionalDependencies { + fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", path.String()) + } }, }, }