| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 1 | // Copyright 2019 Google Inc. All rights reserved. | 
|  | 2 | // | 
|  | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | // you may not use this file except in compliance with the License. | 
|  | 5 | // You may obtain a copy of the License at | 
|  | 6 | // | 
|  | 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | // | 
|  | 9 | // Unless required by applicable law or agreed to in writing, software | 
|  | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | // See the License for the specific language governing permissions and | 
|  | 13 | // limitations under the License. | 
|  | 14 |  | 
|  | 15 | package android | 
|  | 16 |  | 
|  | 17 | import ( | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 18 | "crypto/sha256" | 
|  | 19 | "encoding/hex" | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 20 | "fmt" | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 21 | "path/filepath" | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 22 | "regexp" | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 23 | "strings" | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 24 | "testing" | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 25 |  | 
|  | 26 | "github.com/google/blueprint" | 
|  | 27 |  | 
|  | 28 | "android/soong/shared" | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 29 | ) | 
|  | 30 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 31 | func builderContext() BuilderContext { | 
|  | 32 | return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{ | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 33 | "ld":      nil, | 
|  | 34 | "a.o":     nil, | 
|  | 35 | "b.o":     nil, | 
|  | 36 | "cp":      nil, | 
|  | 37 | "a":       nil, | 
|  | 38 | "b":       nil, | 
|  | 39 | "ls":      nil, | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 40 | "ln":      nil, | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 41 | "turbine": nil, | 
|  | 42 | "java":    nil, | 
|  | 43 | "javac":   nil, | 
|  | 44 | })) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 45 | } | 
|  | 46 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 47 | func ExampleRuleBuilder() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 48 | ctx := builderContext() | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 49 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 50 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 51 |  | 
|  | 52 | rule.Command(). | 
|  | 53 | Tool(PathForSource(ctx, "ld")). | 
|  | 54 | Inputs(PathsForTesting("a.o", "b.o")). | 
|  | 55 | FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 56 | rule.Command().Text("echo success") | 
|  | 57 |  | 
|  | 58 | // To add the command to the build graph: | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 59 | // rule.Build("link", "link") | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 60 |  | 
|  | 61 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 62 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 63 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 64 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 65 |  | 
|  | 66 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 67 | // commands: "ld a.o b.o -o out/soong/linked && echo success" | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 68 | // tools: ["ld"] | 
|  | 69 | // inputs: ["a.o" "b.o"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 70 | // outputs: ["out/soong/linked"] | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 71 | } | 
|  | 72 |  | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 73 | func ExampleRuleBuilder_SymlinkOutputs() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 74 | ctx := builderContext() | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 75 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 76 | rule := NewRuleBuilder(pctx, ctx) | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 77 |  | 
|  | 78 | rule.Command(). | 
|  | 79 | Tool(PathForSource(ctx, "ln")). | 
|  | 80 | FlagWithInput("-s ", PathForTesting("a.o")). | 
|  | 81 | SymlinkOutput(PathForOutput(ctx, "a")) | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 82 | rule.Command().Text("cp out/soong/a out/soong/b"). | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 83 | ImplicitSymlinkOutput(PathForOutput(ctx, "b")) | 
|  | 84 |  | 
|  | 85 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 86 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 87 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 88 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 89 | fmt.Printf("symlink_outputs: %q\n", rule.SymlinkOutputs()) | 
|  | 90 |  | 
|  | 91 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 92 | // commands: "ln -s a.o out/soong/a && cp out/soong/a out/soong/b" | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 93 | // tools: ["ln"] | 
|  | 94 | // inputs: ["a.o"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 95 | // outputs: ["out/soong/a" "out/soong/b"] | 
|  | 96 | // symlink_outputs: ["out/soong/a" "out/soong/b"] | 
| Jingwen Chen | ce679d2 | 2020-09-23 04:30:02 +0000 | [diff] [blame] | 97 | } | 
|  | 98 |  | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 99 | func ExampleRuleBuilder_Temporary() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 100 | ctx := builderContext() | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 101 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 102 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 103 |  | 
|  | 104 | rule.Command(). | 
|  | 105 | Tool(PathForSource(ctx, "cp")). | 
|  | 106 | Input(PathForSource(ctx, "a")). | 
|  | 107 | Output(PathForOutput(ctx, "b")) | 
|  | 108 | rule.Command(). | 
|  | 109 | Tool(PathForSource(ctx, "cp")). | 
|  | 110 | Input(PathForOutput(ctx, "b")). | 
|  | 111 | Output(PathForOutput(ctx, "c")) | 
|  | 112 | rule.Temporary(PathForOutput(ctx, "b")) | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 113 |  | 
|  | 114 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 115 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 116 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 117 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 118 |  | 
|  | 119 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 120 | // commands: "cp a out/soong/b && cp out/soong/b out/soong/c" | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 121 | // tools: ["cp"] | 
|  | 122 | // inputs: ["a"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 123 | // outputs: ["out/soong/c"] | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 124 | } | 
|  | 125 |  | 
|  | 126 | func ExampleRuleBuilder_DeleteTemporaryFiles() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 127 | ctx := builderContext() | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 128 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 129 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 130 |  | 
|  | 131 | rule.Command(). | 
|  | 132 | Tool(PathForSource(ctx, "cp")). | 
|  | 133 | Input(PathForSource(ctx, "a")). | 
|  | 134 | Output(PathForOutput(ctx, "b")) | 
|  | 135 | rule.Command(). | 
|  | 136 | Tool(PathForSource(ctx, "cp")). | 
|  | 137 | Input(PathForOutput(ctx, "b")). | 
|  | 138 | Output(PathForOutput(ctx, "c")) | 
|  | 139 | rule.Temporary(PathForOutput(ctx, "b")) | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 140 | rule.DeleteTemporaryFiles() | 
|  | 141 |  | 
|  | 142 | fmt.Printf("commands: %q\n", strings.Join(rule.Commands(), " && ")) | 
|  | 143 | fmt.Printf("tools: %q\n", rule.Tools()) | 
|  | 144 | fmt.Printf("inputs: %q\n", rule.Inputs()) | 
|  | 145 | fmt.Printf("outputs: %q\n", rule.Outputs()) | 
|  | 146 |  | 
|  | 147 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 148 | // commands: "cp a out/soong/b && cp out/soong/b out/soong/c && rm -f out/soong/b" | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 149 | // tools: ["cp"] | 
|  | 150 | // inputs: ["a"] | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 151 | // outputs: ["out/soong/c"] | 
| Colin Cross | 5cb5b09 | 2019-02-02 21:25:18 -0800 | [diff] [blame] | 152 | } | 
|  | 153 |  | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 154 | func ExampleRuleBuilder_Installs() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 155 | ctx := builderContext() | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 156 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 157 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 158 |  | 
|  | 159 | out := PathForOutput(ctx, "linked") | 
|  | 160 |  | 
|  | 161 | rule.Command(). | 
|  | 162 | Tool(PathForSource(ctx, "ld")). | 
|  | 163 | Inputs(PathsForTesting("a.o", "b.o")). | 
|  | 164 | FlagWithOutput("-o ", out) | 
|  | 165 | rule.Install(out, "/bin/linked") | 
|  | 166 | rule.Install(out, "/sbin/linked") | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 167 |  | 
|  | 168 | fmt.Printf("rule.Installs().String() = %q\n", rule.Installs().String()) | 
|  | 169 |  | 
|  | 170 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 171 | // rule.Installs().String() = "out/soong/linked:/bin/linked out/soong/linked:/sbin/linked" | 
| Colin Cross | deabb94 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 172 | } | 
|  | 173 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 174 | func ExampleRuleBuilderCommand() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 175 | ctx := builderContext() | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 176 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 177 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 178 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 179 | // chained | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 180 | rule.Command(). | 
|  | 181 | Tool(PathForSource(ctx, "ld")). | 
|  | 182 | Inputs(PathsForTesting("a.o", "b.o")). | 
|  | 183 | FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 184 |  | 
|  | 185 | // unchained | 
|  | 186 | cmd := rule.Command() | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 187 | cmd.Tool(PathForSource(ctx, "ld")) | 
|  | 188 | cmd.Inputs(PathsForTesting("a.o", "b.o")) | 
|  | 189 | cmd.FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 190 |  | 
|  | 191 | // mixed: | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 192 | cmd = rule.Command().Tool(PathForSource(ctx, "ld")) | 
|  | 193 | cmd.Inputs(PathsForTesting("a.o", "b.o")) | 
|  | 194 | cmd.FlagWithOutput("-o ", PathForOutput(ctx, "linked")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 195 | } | 
|  | 196 |  | 
|  | 197 | func ExampleRuleBuilderCommand_Flag() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 198 | ctx := builderContext() | 
|  | 199 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 200 | Tool(PathForSource(ctx, "ls")).Flag("-l")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 201 | // Output: | 
|  | 202 | // ls -l | 
|  | 203 | } | 
|  | 204 |  | 
| Colin Cross | 92b7d58 | 2019-03-29 15:32:51 -0700 | [diff] [blame] | 205 | func ExampleRuleBuilderCommand_Flags() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 206 | ctx := builderContext() | 
|  | 207 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 92b7d58 | 2019-03-29 15:32:51 -0700 | [diff] [blame] | 208 | Tool(PathForSource(ctx, "ls")).Flags([]string{"-l", "-a"})) | 
|  | 209 | // Output: | 
|  | 210 | // ls -l -a | 
|  | 211 | } | 
|  | 212 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 213 | func ExampleRuleBuilderCommand_FlagWithArg() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 214 | ctx := builderContext() | 
|  | 215 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 216 | Tool(PathForSource(ctx, "ls")). | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 217 | FlagWithArg("--sort=", "time")) | 
|  | 218 | // Output: | 
|  | 219 | // ls --sort=time | 
|  | 220 | } | 
|  | 221 |  | 
| Colin Cross | c7ed004 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 222 | func ExampleRuleBuilderCommand_FlagForEachArg() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 223 | ctx := builderContext() | 
|  | 224 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 225 | Tool(PathForSource(ctx, "ls")). | 
| Colin Cross | c7ed004 | 2019-02-11 14:11:09 -0800 | [diff] [blame] | 226 | FlagForEachArg("--sort=", []string{"time", "size"})) | 
|  | 227 | // Output: | 
|  | 228 | // ls --sort=time --sort=size | 
|  | 229 | } | 
|  | 230 |  | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 231 | func ExampleRuleBuilderCommand_FlagForEachInput() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 232 | ctx := builderContext() | 
|  | 233 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 234 | Tool(PathForSource(ctx, "turbine")). | 
|  | 235 | FlagForEachInput("--classpath ", PathsForTesting("a.jar", "b.jar"))) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 236 | // Output: | 
|  | 237 | // turbine --classpath a.jar --classpath b.jar | 
|  | 238 | } | 
|  | 239 |  | 
|  | 240 | func ExampleRuleBuilderCommand_FlagWithInputList() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 241 | ctx := builderContext() | 
|  | 242 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 243 | Tool(PathForSource(ctx, "java")). | 
|  | 244 | FlagWithInputList("-classpath=", PathsForTesting("a.jar", "b.jar"), ":")) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 245 | // Output: | 
|  | 246 | // java -classpath=a.jar:b.jar | 
|  | 247 | } | 
|  | 248 |  | 
|  | 249 | func ExampleRuleBuilderCommand_FlagWithInput() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 250 | ctx := builderContext() | 
|  | 251 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 252 | Tool(PathForSource(ctx, "java")). | 
|  | 253 | FlagWithInput("-classpath=", PathForSource(ctx, "a"))) | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 254 | // Output: | 
|  | 255 | // java -classpath=a | 
|  | 256 | } | 
|  | 257 |  | 
|  | 258 | func ExampleRuleBuilderCommand_FlagWithList() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 259 | ctx := builderContext() | 
|  | 260 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 261 | Tool(PathForSource(ctx, "ls")). | 
| Colin Cross | 758290d | 2019-02-01 16:42:32 -0800 | [diff] [blame] | 262 | FlagWithList("--sort=", []string{"time", "size"}, ",")) | 
|  | 263 | // Output: | 
|  | 264 | // ls --sort=time,size | 
|  | 265 | } | 
|  | 266 |  | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 267 | func ExampleRuleBuilderCommand_FlagWithRspFileInputList() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 268 | ctx := builderContext() | 
|  | 269 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 270 | Tool(PathForSource(ctx, "javac")). | 
| Colin Cross | 70c4741 | 2021-03-12 17:48:14 -0800 | [diff] [blame] | 271 | FlagWithRspFileInputList("@", PathForOutput(ctx, "foo.rsp"), PathsForTesting("a.java", "b.java")). | 
|  | 272 | String()) | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 273 | // Output: | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 274 | // javac @out/soong/foo.rsp | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 275 | } | 
|  | 276 |  | 
|  | 277 | func ExampleRuleBuilderCommand_String() { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 278 | ctx := builderContext() | 
|  | 279 | fmt.Println(NewRuleBuilder(pctx, ctx).Command(). | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 280 | Text("FOO=foo"). | 
|  | 281 | Text("echo $FOO"). | 
|  | 282 | String()) | 
|  | 283 | // Output: | 
|  | 284 | // FOO=foo echo $FOO | 
|  | 285 | } | 
|  | 286 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 287 | func TestRuleBuilder(t *testing.T) { | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 288 | fs := map[string][]byte{ | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 289 | "dep_fixer":  nil, | 
|  | 290 | "input":      nil, | 
|  | 291 | "Implicit":   nil, | 
|  | 292 | "Input":      nil, | 
|  | 293 | "OrderOnly":  nil, | 
|  | 294 | "OrderOnlys": nil, | 
|  | 295 | "Tool":       nil, | 
|  | 296 | "input2":     nil, | 
|  | 297 | "tool2":      nil, | 
|  | 298 | "input3":     nil, | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 299 | } | 
|  | 300 |  | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 301 | pathCtx := PathContextForTesting(TestConfig("out_local", nil, "", fs)) | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 302 | ctx := builderContextForTests{ | 
|  | 303 | PathContext: pathCtx, | 
|  | 304 | } | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 305 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 306 | addCommands := func(rule *RuleBuilder) { | 
|  | 307 | cmd := rule.Command(). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 308 | DepFile(PathForOutput(ctx, "module/DepFile")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 309 | Flag("Flag"). | 
|  | 310 | FlagWithArg("FlagWithArg=", "arg"). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 311 | FlagWithDepFile("FlagWithDepFile=", PathForOutput(ctx, "module/depfile")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 312 | FlagWithInput("FlagWithInput=", PathForSource(ctx, "input")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 313 | FlagWithOutput("FlagWithOutput=", PathForOutput(ctx, "module/output")). | 
|  | 314 | FlagWithRspFileInputList("FlagWithRspFileInputList=", PathForOutput(ctx, "rsp"), | 
|  | 315 | Paths{ | 
|  | 316 | PathForSource(ctx, "RspInput"), | 
|  | 317 | PathForOutput(ctx, "other/RspOutput2"), | 
|  | 318 | }). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 319 | Implicit(PathForSource(ctx, "Implicit")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 320 | ImplicitDepFile(PathForOutput(ctx, "module/ImplicitDepFile")). | 
|  | 321 | ImplicitOutput(PathForOutput(ctx, "module/ImplicitOutput")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 322 | Input(PathForSource(ctx, "Input")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 323 | Output(PathForOutput(ctx, "module/Output")). | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 324 | OrderOnly(PathForSource(ctx, "OrderOnly")). | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 325 | Validation(PathForSource(ctx, "Validation")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 326 | SymlinkOutput(PathForOutput(ctx, "module/SymlinkOutput")). | 
|  | 327 | ImplicitSymlinkOutput(PathForOutput(ctx, "module/ImplicitSymlinkOutput")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 328 | Text("Text"). | 
|  | 329 | Tool(PathForSource(ctx, "Tool")) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 330 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 331 | rule.Command(). | 
|  | 332 | Text("command2"). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 333 | DepFile(PathForOutput(ctx, "module/depfile2")). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 334 | Input(PathForSource(ctx, "input2")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 335 | Output(PathForOutput(ctx, "module/output2")). | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 336 | OrderOnlys(PathsForSource(ctx, []string{"OrderOnlys"})). | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 337 | Validations(PathsForSource(ctx, []string{"Validations"})). | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 338 | Tool(PathForSource(ctx, "tool2")) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 339 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 340 | // Test updates to the first command after the second command has been started | 
|  | 341 | cmd.Text("after command2") | 
|  | 342 | // Test updating a command when the previous update did not replace the cmd variable | 
|  | 343 | cmd.Text("old cmd") | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 344 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 345 | // Test a command that uses the output of a previous command as an input | 
|  | 346 | rule.Command(). | 
|  | 347 | Text("command3"). | 
|  | 348 | Input(PathForSource(ctx, "input3")). | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 349 | Input(PathForOutput(ctx, "module/output2")). | 
|  | 350 | Output(PathForOutput(ctx, "module/output3")). | 
|  | 351 | Text(cmd.PathForInput(PathForSource(ctx, "input3"))). | 
|  | 352 | Text(cmd.PathForOutput(PathForOutput(ctx, "module/output2"))) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 353 | } | 
| Colin Cross | 1d2cf04 | 2019-03-29 15:33:06 -0700 | [diff] [blame] | 354 |  | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 355 | wantInputs := PathsForSource(ctx, []string{"Implicit", "Input", "input", "input2", "input3"}) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 356 | wantRspFileInputs := Paths{PathForSource(ctx, "RspInput"), | 
|  | 357 | PathForOutput(ctx, "other/RspOutput2")} | 
|  | 358 | wantOutputs := PathsForOutput(ctx, []string{ | 
|  | 359 | "module/ImplicitOutput", "module/ImplicitSymlinkOutput", "module/Output", "module/SymlinkOutput", | 
|  | 360 | "module/output", "module/output2", "module/output3"}) | 
|  | 361 | wantDepFiles := PathsForOutput(ctx, []string{ | 
|  | 362 | "module/DepFile", "module/depfile", "module/ImplicitDepFile", "module/depfile2"}) | 
| Colin Cross | 69f59a3 | 2019-02-15 10:39:37 -0800 | [diff] [blame] | 363 | wantTools := PathsForSource(ctx, []string{"Tool", "tool2"}) | 
| Colin Cross | da71eda | 2020-02-21 16:55:19 -0800 | [diff] [blame] | 364 | wantOrderOnlys := PathsForSource(ctx, []string{"OrderOnly", "OrderOnlys"}) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 365 | wantValidations := PathsForSource(ctx, []string{"Validation", "Validations"}) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 366 | wantSymlinkOutputs := PathsForOutput(ctx, []string{ | 
|  | 367 | "module/ImplicitSymlinkOutput", "module/SymlinkOutput"}) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 368 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 369 | t.Run("normal", func(t *testing.T) { | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 370 | rule := NewRuleBuilder(pctx, ctx) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 371 | addCommands(rule) | 
| Colin Cross | 1d2cf04 | 2019-03-29 15:33:06 -0700 | [diff] [blame] | 372 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 373 | wantCommands := []string{ | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 374 | "out_local/soong/module/DepFile Flag FlagWithArg=arg FlagWithDepFile=out_local/soong/module/depfile " + | 
|  | 375 | "FlagWithInput=input FlagWithOutput=out_local/soong/module/output FlagWithRspFileInputList=out_local/soong/rsp " + | 
|  | 376 | "Input out_local/soong/module/Output out_local/soong/module/SymlinkOutput Text Tool after command2 old cmd", | 
|  | 377 | "command2 out_local/soong/module/depfile2 input2 out_local/soong/module/output2 tool2", | 
|  | 378 | "command3 input3 out_local/soong/module/output2 out_local/soong/module/output3 input3 out_local/soong/module/output2", | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 379 | } | 
| Colin Cross | 1d2cf04 | 2019-03-29 15:33:06 -0700 | [diff] [blame] | 380 |  | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 381 | wantDepMergerCommand := "out_local/soong/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer " + | 
|  | 382 | "out_local/soong/module/DepFile out_local/soong/module/depfile out_local/soong/module/ImplicitDepFile out_local/soong/module/depfile2" | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 383 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 384 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 385 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 386 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 387 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 388 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
|  | 389 | AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs()) | 
|  | 390 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 391 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 392 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 393 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 394 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 395 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 396 | }) | 
|  | 397 |  | 
|  | 398 | t.Run("sbox", func(t *testing.T) { | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 399 | rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"), | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 400 | PathForOutput(ctx, "sbox.textproto")) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 401 | addCommands(rule) | 
|  | 402 |  | 
|  | 403 | wantCommands := []string{ | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 404 | "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " + | 
|  | 405 | "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " + | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 406 | "FlagWithRspFileInputList=out_local/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " + | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 407 | "__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text Tool after command2 old cmd", | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 408 | "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 tool2", | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 409 | "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2", | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 410 | } | 
|  | 411 |  | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 412 | wantDepMergerCommand := "out_local/soong/host/" + ctx.Config().PrebuiltOS() + "/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 413 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 414 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 415 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 416 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 417 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 418 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 419 | AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 420 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 421 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 422 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 423 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 424 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 425 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 426 | }) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 427 |  | 
|  | 428 | t.Run("sbox tools", func(t *testing.T) { | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 429 | rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"), | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 430 | PathForOutput(ctx, "sbox.textproto")).SandboxTools() | 
|  | 431 | addCommands(rule) | 
|  | 432 |  | 
|  | 433 | wantCommands := []string{ | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 434 | "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " + | 
|  | 435 | "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " + | 
| Colin Cross | 7b6a55f | 2021-11-09 12:34:39 -0800 | [diff] [blame] | 436 | "FlagWithRspFileInputList=out_local/soong/rsp Input __SBOX_SANDBOX_DIR__/out/Output " + | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 437 | "__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd", | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 438 | "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2", | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 439 | "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2", | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 440 | } | 
|  | 441 |  | 
|  | 442 | wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" | 
|  | 443 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 444 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 445 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 446 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 447 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 448 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
| Colin Cross | ab020a7 | 2021-03-12 17:52:23 -0800 | [diff] [blame] | 449 | AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs()) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 450 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 451 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 452 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 453 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 454 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 455 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
| Colin Cross | ba9e403 | 2020-11-24 16:32:22 -0800 | [diff] [blame] | 456 | }) | 
| Colin Cross | 045bfd9 | 2021-03-24 16:38:03 -0700 | [diff] [blame] | 457 |  | 
|  | 458 | t.Run("sbox inputs", func(t *testing.T) { | 
|  | 459 | rule := NewRuleBuilder(pctx, ctx).Sbox(PathForOutput(ctx, "module"), | 
|  | 460 | PathForOutput(ctx, "sbox.textproto")).SandboxInputs() | 
|  | 461 | addCommands(rule) | 
|  | 462 |  | 
|  | 463 | wantCommands := []string{ | 
|  | 464 | "__SBOX_SANDBOX_DIR__/out/DepFile Flag FlagWithArg=arg FlagWithDepFile=__SBOX_SANDBOX_DIR__/out/depfile " + | 
|  | 465 | "FlagWithInput=input FlagWithOutput=__SBOX_SANDBOX_DIR__/out/output " + | 
|  | 466 | "FlagWithRspFileInputList=__SBOX_SANDBOX_DIR__/out/rsp Input __SBOX_SANDBOX_DIR__/out/Output " + | 
|  | 467 | "__SBOX_SANDBOX_DIR__/out/SymlinkOutput Text __SBOX_SANDBOX_DIR__/tools/src/Tool after command2 old cmd", | 
|  | 468 | "command2 __SBOX_SANDBOX_DIR__/out/depfile2 input2 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/tools/src/tool2", | 
|  | 469 | "command3 input3 __SBOX_SANDBOX_DIR__/out/output2 __SBOX_SANDBOX_DIR__/out/output3 input3 __SBOX_SANDBOX_DIR__/out/output2", | 
|  | 470 | } | 
|  | 471 |  | 
|  | 472 | wantDepMergerCommand := "__SBOX_SANDBOX_DIR__/tools/out/bin/dep_fixer __SBOX_SANDBOX_DIR__/out/DepFile __SBOX_SANDBOX_DIR__/out/depfile __SBOX_SANDBOX_DIR__/out/ImplicitDepFile __SBOX_SANDBOX_DIR__/out/depfile2" | 
|  | 473 |  | 
|  | 474 | AssertDeepEquals(t, "rule.Commands()", wantCommands, rule.Commands()) | 
|  | 475 |  | 
|  | 476 | AssertDeepEquals(t, "rule.Inputs()", wantInputs, rule.Inputs()) | 
|  | 477 | AssertDeepEquals(t, "rule.RspfileInputs()", wantRspFileInputs, rule.RspFileInputs()) | 
|  | 478 | AssertDeepEquals(t, "rule.Outputs()", wantOutputs, rule.Outputs()) | 
|  | 479 | AssertDeepEquals(t, "rule.SymlinkOutputs()", wantSymlinkOutputs, rule.SymlinkOutputs()) | 
|  | 480 | AssertDeepEquals(t, "rule.DepFiles()", wantDepFiles, rule.DepFiles()) | 
|  | 481 | AssertDeepEquals(t, "rule.Tools()", wantTools, rule.Tools()) | 
|  | 482 | AssertDeepEquals(t, "rule.OrderOnlys()", wantOrderOnlys, rule.OrderOnlys()) | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 483 | AssertDeepEquals(t, "rule.Validations()", wantValidations, rule.Validations()) | 
| Colin Cross | 045bfd9 | 2021-03-24 16:38:03 -0700 | [diff] [blame] | 484 |  | 
|  | 485 | AssertSame(t, "rule.depFileMergerCmd()", wantDepMergerCommand, rule.depFileMergerCmd(rule.DepFiles()).String()) | 
|  | 486 | }) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 487 | } | 
|  | 488 |  | 
|  | 489 | func testRuleBuilderFactory() Module { | 
|  | 490 | module := &testRuleBuilderModule{} | 
|  | 491 | module.AddProperties(&module.properties) | 
|  | 492 | InitAndroidModule(module) | 
|  | 493 | return module | 
|  | 494 | } | 
|  | 495 |  | 
|  | 496 | type testRuleBuilderModule struct { | 
|  | 497 | ModuleBase | 
|  | 498 | properties struct { | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 499 | Srcs []string | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 500 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 501 | Restat      bool | 
|  | 502 | Sbox        bool | 
|  | 503 | Sbox_inputs bool | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 504 | } | 
|  | 505 | } | 
|  | 506 |  | 
|  | 507 | func (t *testRuleBuilderModule) GenerateAndroidBuildActions(ctx ModuleContext) { | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 508 | in := PathsForSource(ctx, t.properties.Srcs) | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 509 | implicit := PathForSource(ctx, "implicit") | 
|  | 510 | orderOnly := PathForSource(ctx, "orderonly") | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 511 | validation := PathForSource(ctx, "validation") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 512 | out := PathForModuleOut(ctx, "gen", ctx.ModuleName()) | 
|  | 513 | outDep := PathForModuleOut(ctx, "gen", ctx.ModuleName()+".d") | 
|  | 514 | outDir := PathForModuleOut(ctx, "gen") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 515 | rspFile := PathForModuleOut(ctx, "rsp") | 
|  | 516 | rspFile2 := PathForModuleOut(ctx, "rsp2") | 
|  | 517 | rspFileContents := PathsForSource(ctx, []string{"rsp_in"}) | 
|  | 518 | rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 519 | manifestPath := PathForModuleOut(ctx, "sbox.textproto") | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 520 |  | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 521 | testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir, | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 522 | manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, | 
|  | 523 | rspFile, rspFileContents, rspFile2, rspFileContents2) | 
| Colin Cross | 786cd6d | 2019-02-01 16:41:11 -0800 | [diff] [blame] | 524 | } | 
|  | 525 |  | 
|  | 526 | type testRuleBuilderSingleton struct{} | 
|  | 527 |  | 
|  | 528 | func testRuleBuilderSingletonFactory() Singleton { | 
|  | 529 | return &testRuleBuilderSingleton{} | 
|  | 530 | } | 
|  | 531 |  | 
|  | 532 | func (t *testRuleBuilderSingleton) GenerateBuildActions(ctx SingletonContext) { | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 533 | in := PathsForSource(ctx, []string{"in"}) | 
|  | 534 | implicit := PathForSource(ctx, "implicit") | 
|  | 535 | orderOnly := PathForSource(ctx, "orderonly") | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 536 | validation := PathForSource(ctx, "validation") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 537 | out := PathForOutput(ctx, "singleton/gen/baz") | 
|  | 538 | outDep := PathForOutput(ctx, "singleton/gen/baz.d") | 
|  | 539 | outDir := PathForOutput(ctx, "singleton/gen") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 540 | rspFile := PathForOutput(ctx, "singleton/rsp") | 
|  | 541 | rspFile2 := PathForOutput(ctx, "singleton/rsp2") | 
|  | 542 | rspFileContents := PathsForSource(ctx, []string{"rsp_in"}) | 
|  | 543 | rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"}) | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 544 | manifestPath := PathForOutput(ctx, "singleton/sbox.textproto") | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 545 |  | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 546 | testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir, | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 547 | manifestPath, true, false, false, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 548 | rspFile, rspFileContents, rspFile2, rspFileContents2) | 
| Colin Cross | 786cd6d | 2019-02-01 16:41:11 -0800 | [diff] [blame] | 549 | } | 
|  | 550 |  | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 551 | func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path, | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 552 | out, outDep, outDir, manifestPath WritablePath, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 553 | restat, sbox, sboxInputs bool, | 
|  | 554 | rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) { | 
|  | 555 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 556 | rule := NewRuleBuilder(pctx, ctx) | 
| Colin Cross | 786cd6d | 2019-02-01 16:41:11 -0800 | [diff] [blame] | 557 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 558 | if sbox { | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 559 | rule.Sbox(outDir, manifestPath) | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 560 | if sboxInputs { | 
|  | 561 | rule.SandboxInputs() | 
|  | 562 | } | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 563 | } | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 564 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 565 | rule.Command(). | 
|  | 566 | Tool(PathForSource(ctx, "cp")). | 
|  | 567 | Inputs(in). | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 568 | Implicit(implicit). | 
|  | 569 | OrderOnly(orderOnly). | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 570 | Validation(validation). | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 571 | Output(out). | 
|  | 572 | ImplicitDepFile(outDep). | 
|  | 573 | FlagWithRspFileInputList("@", rspFile, rspFileContents). | 
|  | 574 | FlagWithRspFileInputList("@", rspFile2, rspFileContents2) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 575 |  | 
|  | 576 | if restat { | 
|  | 577 | rule.Restat() | 
|  | 578 | } | 
| Colin Cross | baa676f | 2019-02-25 14:56:01 -0800 | [diff] [blame] | 579 |  | 
| Colin Cross | f1a035e | 2020-11-16 17:32:30 -0800 | [diff] [blame] | 580 | rule.Build("rule", "desc") | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 581 | } | 
|  | 582 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 583 | var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) { | 
|  | 584 | ctx.RegisterModuleType("rule_builder_test", testRuleBuilderFactory) | 
|  | 585 | ctx.RegisterSingletonType("rule_builder_test", testRuleBuilderSingletonFactory) | 
|  | 586 | }) | 
|  | 587 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 588 | func TestRuleBuilder_Build(t *testing.T) { | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 589 | fs := MockFS{ | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 590 | "in": nil, | 
|  | 591 | "cp": nil, | 
| Colin Cross | 98be1bb | 2019-12-13 20:41:13 -0800 | [diff] [blame] | 592 | } | 
|  | 593 |  | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 594 | bp := ` | 
|  | 595 | rule_builder_test { | 
|  | 596 | name: "foo", | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 597 | srcs: ["in"], | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 598 | restat: true, | 
|  | 599 | } | 
|  | 600 | rule_builder_test { | 
|  | 601 | name: "foo_sbox", | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 602 | srcs: ["in"], | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 603 | sbox: true, | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 604 | } | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 605 | rule_builder_test { | 
|  | 606 | name: "foo_sbox_inputs", | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 607 | srcs: ["in"], | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 608 | sbox: true, | 
|  | 609 | sbox_inputs: true, | 
|  | 610 | } | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 611 | ` | 
|  | 612 |  | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 613 | result := GroupFixturePreparers( | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 614 | prepareForRuleBuilderTest, | 
|  | 615 | FixtureWithRootAndroidBp(bp), | 
|  | 616 | fs.AddToFixture(), | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 617 | ).RunTest(t) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 618 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 619 | check := func(t *testing.T, params TestingBuildParams, rspFile2Params TestingBuildParams, | 
|  | 620 | wantCommand, wantOutput, wantDepfile, wantRspFile, wantRspFile2 string, | 
|  | 621 | wantRestat bool, extraImplicits, extraCmdDeps []string) { | 
|  | 622 |  | 
| Dan Willemsen | c89b6f1 | 2019-08-29 14:47:40 -0700 | [diff] [blame] | 623 | t.Helper() | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 624 | command := params.RuleParams.Command | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 625 | re := regexp.MustCompile(" # hash of input list: [a-z0-9]*$") | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 626 | command = re.ReplaceAllLiteralString(command, "") | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 627 |  | 
|  | 628 | AssertStringEquals(t, "RuleParams.Command", wantCommand, command) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 629 |  | 
|  | 630 | wantDeps := append([]string{"cp"}, extraCmdDeps...) | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 631 | AssertArrayString(t, "RuleParams.CommandDeps", wantDeps, params.RuleParams.CommandDeps) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 632 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 633 | AssertBoolEquals(t, "RuleParams.Restat", wantRestat, params.RuleParams.Restat) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 634 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 635 | wantInputs := []string{"rsp_in"} | 
|  | 636 | AssertArrayString(t, "Inputs", wantInputs, params.Inputs.Strings()) | 
|  | 637 |  | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 638 | wantImplicits := append([]string{"implicit", "in"}, extraImplicits...) | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 639 | // The second rsp file and the files listed in it should be in implicits | 
|  | 640 | wantImplicits = append(wantImplicits, "rsp_in2", wantRspFile2) | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 641 | AssertPathsRelativeToTopEquals(t, "Implicits", wantImplicits, params.Implicits) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 642 |  | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 643 | wantOrderOnlys := []string{"orderonly"} | 
|  | 644 | AssertPathsRelativeToTopEquals(t, "OrderOnly", wantOrderOnlys, params.OrderOnly) | 
|  | 645 |  | 
| Colin Cross | ae89abe | 2021-04-21 11:45:23 -0700 | [diff] [blame] | 646 | wantValidations := []string{"validation"} | 
|  | 647 | AssertPathsRelativeToTopEquals(t, "Validations", wantValidations, params.Validations) | 
|  | 648 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 649 | wantRspFileContent := "$in" | 
|  | 650 | AssertStringEquals(t, "RspfileContent", wantRspFileContent, params.RuleParams.RspfileContent) | 
|  | 651 |  | 
|  | 652 | AssertStringEquals(t, "Rspfile", wantRspFile, params.RuleParams.Rspfile) | 
|  | 653 |  | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 654 | AssertPathRelativeToTopEquals(t, "Output", wantOutput, params.Output) | 
| Colin Cross | baa676f | 2019-02-25 14:56:01 -0800 | [diff] [blame] | 655 |  | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 656 | if len(params.ImplicitOutputs) != 0 { | 
|  | 657 | t.Errorf("want ImplicitOutputs = [], got %q", params.ImplicitOutputs.Strings()) | 
|  | 658 | } | 
|  | 659 |  | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 660 | AssertPathRelativeToTopEquals(t, "Depfile", wantDepfile, params.Depfile) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 661 |  | 
|  | 662 | if params.Deps != blueprint.DepsGCC { | 
|  | 663 | t.Errorf("want Deps = %q, got %q", blueprint.DepsGCC, params.Deps) | 
| Colin Cross | baa676f | 2019-02-25 14:56:01 -0800 | [diff] [blame] | 664 | } | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 665 |  | 
|  | 666 | rspFile2Content := ContentFromFileRuleForTests(t, rspFile2Params) | 
|  | 667 | AssertStringEquals(t, "rspFile2 content", "rsp_in2\n", rspFile2Content) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 668 | } | 
|  | 669 |  | 
| Colin Cross | 4c83e5c | 2019-02-25 14:54:28 -0800 | [diff] [blame] | 670 | t.Run("module", func(t *testing.T) { | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 671 | outFile := "out/soong/.intermediates/foo/gen/foo" | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 672 | rspFile := "out/soong/.intermediates/foo/rsp" | 
|  | 673 | rspFile2 := "out/soong/.intermediates/foo/rsp2" | 
|  | 674 | module := result.ModuleForTests("foo", "") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 675 | check(t, module.Rule("rule"), module.Output(rspFile2), | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 676 | "cp in "+outFile+" @"+rspFile+" @"+rspFile2, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 677 | outFile, outFile+".d", rspFile, rspFile2, true, nil, nil) | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 678 | }) | 
|  | 679 | t.Run("sbox", func(t *testing.T) { | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 680 | outDir := "out/soong/.intermediates/foo_sbox" | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 681 | sboxOutDir := filepath.Join(outDir, "gen") | 
|  | 682 | outFile := filepath.Join(sboxOutDir, "foo_sbox") | 
|  | 683 | depFile := filepath.Join(sboxOutDir, "foo_sbox.d") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 684 | rspFile := filepath.Join(outDir, "rsp") | 
|  | 685 | rspFile2 := filepath.Join(outDir, "rsp2") | 
|  | 686 | manifest := filepath.Join(outDir, "sbox.textproto") | 
|  | 687 | sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox") | 
|  | 688 | sandboxPath := shared.TempDirForOutDir("out/soong") | 
|  | 689 |  | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 690 | cmd := sbox + ` --sandbox-path ` + sandboxPath + ` --output-dir ` + sboxOutDir + ` --manifest ` + manifest | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 691 | module := result.ModuleForTests("foo_sbox", "") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 692 | check(t, module.Output("gen/foo_sbox"), module.Output(rspFile2), | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 693 | cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox}) | 
|  | 694 | }) | 
|  | 695 | t.Run("sbox_inputs", func(t *testing.T) { | 
|  | 696 | outDir := "out/soong/.intermediates/foo_sbox_inputs" | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 697 | sboxOutDir := filepath.Join(outDir, "gen") | 
|  | 698 | outFile := filepath.Join(sboxOutDir, "foo_sbox_inputs") | 
|  | 699 | depFile := filepath.Join(sboxOutDir, "foo_sbox_inputs.d") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 700 | rspFile := filepath.Join(outDir, "rsp") | 
|  | 701 | rspFile2 := filepath.Join(outDir, "rsp2") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 702 | manifest := filepath.Join(outDir, "sbox.textproto") | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 703 | sbox := filepath.Join("out", "soong", "host", result.Config.PrebuiltOS(), "bin/sbox") | 
|  | 704 | sandboxPath := shared.TempDirForOutDir("out/soong") | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 705 |  | 
| Colin Cross | e52c2ac | 2022-03-28 17:03:35 -0700 | [diff] [blame] | 706 | cmd := sbox + ` --sandbox-path ` + sandboxPath + ` --output-dir ` + sboxOutDir + ` --manifest ` + manifest | 
| Dan Willemsen | 633c502 | 2019-04-12 11:11:38 -0700 | [diff] [blame] | 707 |  | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 708 | module := result.ModuleForTests("foo_sbox_inputs", "") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 709 | check(t, module.Output("gen/foo_sbox_inputs"), module.Output(rspFile2), | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 710 | cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox}) | 
| Colin Cross | 4c83e5c | 2019-02-25 14:54:28 -0800 | [diff] [blame] | 711 | }) | 
|  | 712 | t.Run("singleton", func(t *testing.T) { | 
| Paul Duffin | 709e0e3 | 2021-03-22 10:09:02 +0000 | [diff] [blame] | 713 | outFile := filepath.Join("out/soong/singleton/gen/baz") | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 714 | rspFile := filepath.Join("out/soong/singleton/rsp") | 
|  | 715 | rspFile2 := filepath.Join("out/soong/singleton/rsp2") | 
|  | 716 | singleton := result.SingletonForTests("rule_builder_test") | 
| Paul Duffin | a71a67a | 2021-03-29 00:42:57 +0100 | [diff] [blame] | 717 | check(t, singleton.Rule("rule"), singleton.Output(rspFile2), | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 718 | "cp in "+outFile+" @"+rspFile+" @"+rspFile2, | 
| Colin Cross | ce3a51d | 2021-03-19 16:22:12 -0700 | [diff] [blame] | 719 | outFile, outFile+".d", rspFile, rspFile2, true, nil, nil) | 
| Colin Cross | 4c83e5c | 2019-02-25 14:54:28 -0800 | [diff] [blame] | 720 | }) | 
| Colin Cross | feec25b | 2019-01-30 17:32:39 -0800 | [diff] [blame] | 721 | } | 
| Colin Cross | 0cb0d7b | 2019-07-11 10:59:15 -0700 | [diff] [blame] | 722 |  | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 723 | func TestRuleBuilderHashInputs(t *testing.T) { | 
|  | 724 | // The basic idea here is to verify that the command (in the case of a | 
|  | 725 | // non-sbox rule) or the sbox textproto manifest contain a hash of the | 
|  | 726 | // inputs. | 
|  | 727 |  | 
|  | 728 | // By including a hash of the inputs, we cause the rule to re-run if | 
|  | 729 | // the list of inputs changes because the command line or a dependency | 
|  | 730 | // changes. | 
|  | 731 |  | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 732 | hashOf := func(s string) string { | 
|  | 733 | sum := sha256.Sum256([]byte(s)) | 
|  | 734 | return hex.EncodeToString(sum[:]) | 
|  | 735 | } | 
|  | 736 |  | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 737 | bp := ` | 
|  | 738 | rule_builder_test { | 
|  | 739 | name: "hash0", | 
|  | 740 | srcs: ["in1.txt", "in2.txt"], | 
|  | 741 | } | 
|  | 742 | rule_builder_test { | 
|  | 743 | name: "hash0_sbox", | 
|  | 744 | srcs: ["in1.txt", "in2.txt"], | 
|  | 745 | sbox: true, | 
|  | 746 | } | 
|  | 747 | rule_builder_test { | 
|  | 748 | name: "hash1", | 
|  | 749 | srcs: ["in1.txt", "in2.txt", "in3.txt"], | 
|  | 750 | } | 
|  | 751 | rule_builder_test { | 
|  | 752 | name: "hash1_sbox", | 
|  | 753 | srcs: ["in1.txt", "in2.txt", "in3.txt"], | 
|  | 754 | sbox: true, | 
|  | 755 | } | 
|  | 756 | ` | 
|  | 757 | testcases := []struct { | 
|  | 758 | name         string | 
|  | 759 | expectedHash string | 
|  | 760 | }{ | 
|  | 761 | { | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 762 | name:         "hash0", | 
|  | 763 | expectedHash: hashOf("implicit\nin1.txt\nin2.txt"), | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 764 | }, | 
|  | 765 | { | 
| Colin Cross | da6401b | 2021-04-21 11:32:19 -0700 | [diff] [blame] | 766 | name:         "hash1", | 
|  | 767 | expectedHash: hashOf("implicit\nin1.txt\nin2.txt\nin3.txt"), | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 768 | }, | 
|  | 769 | } | 
|  | 770 |  | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 771 | result := GroupFixturePreparers( | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 772 | prepareForRuleBuilderTest, | 
|  | 773 | FixtureWithRootAndroidBp(bp), | 
| Paul Duffin | 30ac3e7 | 2021-03-20 00:36:14 +0000 | [diff] [blame] | 774 | ).RunTest(t) | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 775 |  | 
|  | 776 | for _, test := range testcases { | 
|  | 777 | t.Run(test.name, func(t *testing.T) { | 
|  | 778 | t.Run("sbox", func(t *testing.T) { | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 779 | gen := result.ModuleForTests(test.name+"_sbox", "") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 780 | manifest := RuleBuilderSboxProtoForTests(t, gen.Output("sbox.textproto")) | 
|  | 781 | hash := manifest.Commands[0].GetInputHash() | 
|  | 782 |  | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 783 | AssertStringEquals(t, "hash", test.expectedHash, hash) | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 784 | }) | 
|  | 785 | t.Run("", func(t *testing.T) { | 
| Paul Duffin | d250ff6 | 2021-03-16 21:51:29 +0000 | [diff] [blame] | 786 | gen := result.ModuleForTests(test.name+"", "") | 
| Colin Cross | e16ce36 | 2020-11-12 08:29:30 -0800 | [diff] [blame] | 787 | command := gen.Output("gen/" + test.name).RuleParams.Command | 
| Colin Cross | 3d68051 | 2020-11-13 16:23:53 -0800 | [diff] [blame] | 788 | if g, w := command, " # hash of input list: "+test.expectedHash; !strings.HasSuffix(g, w) { | 
|  | 789 | t.Errorf("Expected command line to end with %q, got %q", w, g) | 
|  | 790 | } | 
|  | 791 | }) | 
|  | 792 | }) | 
|  | 793 | } | 
|  | 794 | } |