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