diff --git a/android/rule_builder.go b/android/rule_builder.go index 1438fcac3..2507c4c83 100644 --- a/android/rule_builder.go +++ b/android/rule_builder.go @@ -283,6 +283,28 @@ func (r *RuleBuilder) OrderOnlys() Paths { return orderOnlyList } +// Validations returns the list of paths that were passed to RuleBuilderCommand.Validation or +// RuleBuilderCommand.Validations. The list is sorted and duplicates removed. +func (r *RuleBuilder) Validations() Paths { + validations := make(map[string]Path) + for _, c := range r.commands { + for _, validation := range c.validations { + validations[validation.String()] = validation + } + } + + var validationList Paths + for _, validation := range validations { + validationList = append(validationList, validation) + } + + sort.Slice(validationList, func(i, j int) bool { + return validationList[i].String() < validationList[j].String() + }) + + return validationList +} + func (r *RuleBuilder) outputSet() map[string]WritablePath { outputs := make(map[string]WritablePath) for _, c := range r.commands { @@ -707,6 +729,7 @@ func (r *RuleBuilder) Build(name string, desc string) { Inputs: rspFileInputs, Implicits: inputs, OrderOnly: r.OrderOnlys(), + Validations: r.Validations(), Output: output, ImplicitOutputs: implicitOutputs, SymlinkOutputs: r.SymlinkOutputs(), @@ -727,6 +750,7 @@ type RuleBuilderCommand struct { inputs Paths implicits Paths orderOnlys Paths + validations Paths outputs WritablePaths symlinkOutputs WritablePaths depFiles WritablePaths @@ -1061,6 +1085,20 @@ func (c *RuleBuilderCommand) OrderOnlys(paths Paths) *RuleBuilderCommand { return c } +// Validation adds the specified input path to the validation dependencies by +// RuleBuilder.Validations without modifying the command line. +func (c *RuleBuilderCommand) Validation(path Path) *RuleBuilderCommand { + c.validations = append(c.validations, path) + return c +} + +// Validations adds the specified input paths to the validation dependencies by +// RuleBuilder.Validations without modifying the command line. +func (c *RuleBuilderCommand) Validations(paths Paths) *RuleBuilderCommand { + c.validations = append(c.validations, paths...) + return c +} + // Output adds the specified output path to the command line. The path will also be added to the outputs returned by // RuleBuilder.Outputs. func (c *RuleBuilderCommand) Output(path WritablePath) *RuleBuilderCommand { diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go index 24c8976a3..feee90f29 100644 --- a/android/rule_builder_test.go +++ b/android/rule_builder_test.go @@ -322,6 +322,7 @@ func TestRuleBuilder(t *testing.T) { Input(PathForSource(ctx, "Input")). Output(PathForOutput(ctx, "module/Output")). OrderOnly(PathForSource(ctx, "OrderOnly")). + Validation(PathForSource(ctx, "Validation")). SymlinkOutput(PathForOutput(ctx, "module/SymlinkOutput")). ImplicitSymlinkOutput(PathForOutput(ctx, "module/ImplicitSymlinkOutput")). Text("Text"). @@ -333,6 +334,7 @@ func TestRuleBuilder(t *testing.T) { Input(PathForSource(ctx, "input2")). Output(PathForOutput(ctx, "module/output2")). OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})). + Validations(PathsForSource(ctx, []string{"Validations"})). Tool(PathForSource(ctx, "tool2")) // Test updates to the first command after the second command has been started @@ -360,6 +362,7 @@ func TestRuleBuilder(t *testing.T) { "module/DepFile", "module/depfile", "module/ImplicitDepFile", "module/depfile2"}) wantTools := PathsForSource(ctx, []string{"Tool", "tool2"}) wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"}) + wantValidations := PathsForSource(ctx, []string{"Validation", "Validations"}) wantSymlinkOutputs := PathsForOutput(ctx, []string{ "module/ImplicitSymlinkOutput", "module/SymlinkOutput"}) @@ -387,6 +390,7 @@ func TestRuleBuilder(t *testing.T) { AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) + AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) @@ -416,6 +420,7 @@ func TestRuleBuilder(t *testing.T) { AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) + AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) @@ -445,6 +450,7 @@ func TestRuleBuilder(t *testing.T) { AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) + AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) @@ -474,6 +480,7 @@ func TestRuleBuilder(t *testing.T) { AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) + AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) }) @@ -501,6 +508,7 @@ func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) { in := PathsForSource(ctx, t.properties.Srcs) implicit := PathForSource(ctx, "implicit") orderOnly := PathForSource(ctx, "orderonly") + validation := PathForSource(ctx, "validation") out := PathForModuleOut(ctx, "gen", ctx.ModuleName()) outDep := PathForModuleOut(ctx, "gen", ctx.ModuleName()+".d") outDir := PathForModuleOut(ctx, "gen") @@ -510,7 +518,7 @@ func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) { rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) manifestPath := PathForModuleOut(ctx, "sbox.textproto") - testRuleBuilder_Build(ctx, in, implicit, orderOnly, out, outDep, outDir, + testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir, manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, rspFile, rspFileContents, rspFile2, rspFileContents2) } @@ -525,6 +533,7 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) { in := PathsForSource(ctx, []string{"in"}) implicit := PathForSource(ctx, "implicit") orderOnly := PathForSource(ctx, "orderonly") + validation := PathForSource(ctx, "validation") out := PathForOutput(ctx, "singleton/gen/baz") outDep := PathForOutput(ctx, "singleton/gen/baz.d") outDir := PathForOutput(ctx, "singleton/gen") @@ -534,12 +543,12 @@ func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) { rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) manifestPath := PathForOutput(ctx, "singleton/sbox.textproto") - testRuleBuilder_Build(ctx, in, implicit, orderOnly, out, outDep, outDir, + testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir, manifestPath, true, false, false, rspFile, rspFileContents, rspFile2, rspFileContents2) } -func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly Path, +func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path, out, outDep, outDir, manifestPath WritablePath, restat, sbox, sboxInputs bool, rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) { @@ -558,6 +567,7 @@ func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly Pat Inputs(in). Implicit(implicit). OrderOnly(orderOnly). + Validation(validation). Output(out). ImplicitDepFile(outDep). FlagWithRspFileInputList("@", rspFile, rspFileContents). @@ -633,6 +643,9 @@ func TestRuleBuilder_Build(t *testing.T) { wantOrderOnlys := []string{"orderonly"} AssertPathsRelativeToTopEquals(t, "OrderOnly", wantOrderOnlys, params.OrderOnly) + wantValidations := []string{"validation"} + AssertPathsRelativeToTopEquals(t, "Validations", wantValidations, params.Validations) + wantRspFileContent := "$in" AssertStringEquals(t, "RspfileContent", wantRspFileContent, params.RuleParams.RspfileContent)