Add support for order-only dependencies to RuleBuilder

Test: TestRuleBuilder
Change-Id: I1609a790dd4d0a03c8308b6e552622fe33fa2499
diff --git a/android/rule_builder.go b/android/rule_builder.go
index b4f144a..9005f07 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -162,9 +162,10 @@
 	r.Command().Text("rm").Flag("-f").Outputs(temporariesList)
 }
 
-// Inputs returns the list of paths that were passed to the RuleBuilderCommand methods that take input paths, such
-// as RuleBuilderCommand.Input, RuleBuilderComand.Implicit, or RuleBuilderCommand.FlagWithInput.  Inputs to a command
-// that are also outputs of another command in the same RuleBuilder are filtered out.
+// Inputs returns the list of paths that were passed to the RuleBuilderCommand methods that take
+// input paths, such as RuleBuilderCommand.Input, RuleBuilderComand.Implicit, or
+// RuleBuilderCommand.FlagWithInput.  Inputs to a command that are also outputs of another command
+// in the same RuleBuilder are filtered out.  The list is sorted and duplicates removed.
 func (r *RuleBuilder) Inputs() Paths {
 	outputs := r.outputSet()
 	depFiles := r.depFileSet()
@@ -193,6 +194,28 @@
 	return inputList
 }
 
+// OrderOnlys returns the list of paths that were passed to the RuleBuilderCommand.OrderOnly or
+// RuleBuilderCommand.OrderOnlys.  The list is sorted and duplicates removed.
+func (r *RuleBuilder) OrderOnlys() Paths {
+	orderOnlys := make(map[string]Path)
+	for _, c := range r.commands {
+		for _, orderOnly := range c.orderOnlys {
+			orderOnlys[orderOnly.String()] = orderOnly
+		}
+	}
+
+	var orderOnlyList Paths
+	for _, orderOnly := range orderOnlys {
+		orderOnlyList = append(orderOnlyList, orderOnly)
+	}
+
+	sort.Slice(orderOnlyList, func(i, j int) bool {
+		return orderOnlyList[i].String() < orderOnlyList[j].String()
+	})
+
+	return orderOnlyList
+}
+
 func (r *RuleBuilder) outputSet() map[string]WritablePath {
 	outputs := make(map[string]WritablePath)
 	for _, c := range r.commands {
@@ -203,8 +226,9 @@
 	return outputs
 }
 
-// Outputs returns the list of paths that were passed to the RuleBuilderCommand methods that take output paths, such
-// as RuleBuilderCommand.Output, RuleBuilderCommand.ImplicitOutput, or RuleBuilderCommand.FlagWithInput.
+// Outputs returns the list of paths that were passed to the RuleBuilderCommand methods that take
+// output paths, such as RuleBuilderCommand.Output, RuleBuilderCommand.ImplicitOutput, or
+// RuleBuilderCommand.FlagWithInput.  The list is sorted and duplicates removed.
 func (r *RuleBuilder) Outputs() WritablePaths {
 	outputs := r.outputSet()
 
@@ -262,7 +286,8 @@
 	return tools
 }
 
-// Tools returns the list of paths that were passed to the RuleBuilderCommand.Tool method.
+// Tools returns the list of paths that were passed to the RuleBuilderCommand.Tool method.  The
+// list is sorted and duplicates removed.
 func (r *RuleBuilder) Tools() Paths {
 	toolsSet := r.toolsSet()
 
@@ -337,6 +362,7 @@
 		ctx.Build(pctx, BuildParams{
 			Rule:        ErrorRule,
 			Outputs:     r.Outputs(),
+			OrderOnly:   r.OrderOnlys(),
 			Description: desc,
 			Args: map[string]string{
 				"error": "missing dependencies: " + strings.Join(r.missingDeps, ", "),
@@ -453,6 +479,7 @@
 type RuleBuilderCommand struct {
 	buf           strings.Builder
 	inputs        Paths
+	orderOnlys    Paths
 	outputs       WritablePaths
 	depFiles      WritablePaths
 	tools         Paths
@@ -475,6 +502,10 @@
 	return path.String()
 }
 
+func (c *RuleBuilderCommand) addOrderOnly(path Path) {
+	c.orderOnlys = append(c.orderOnlys, path)
+}
+
 func (c *RuleBuilderCommand) outputStr(path Path) string {
 	if c.sbox {
 		// Errors will be handled in RuleBuilder.Build where we have a context to report them
@@ -604,6 +635,22 @@
 	return c
 }
 
+// OrderOnly adds the specified input path to the dependencies returned by RuleBuilder.OrderOnlys
+// without modifying the command line.
+func (c *RuleBuilderCommand) OrderOnly(path Path) *RuleBuilderCommand {
+	c.addOrderOnly(path)
+	return c
+}
+
+// OrderOnlys adds the specified input paths to the dependencies returned by RuleBuilder.OrderOnlys
+// without modifying the command line.
+func (c *RuleBuilderCommand) OrderOnlys(paths Paths) *RuleBuilderCommand {
+	for _, path := range paths {
+		c.addOrderOnly(path)
+	}
+	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 {