blob: 7c17db1be4e8d76f5a2131fa20e397a0b9c91d8b [file] [log] [blame]
Colin Cross2a076922018-10-04 23:28:25 -07001// Copyright 2018 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
15package genrule
16
17import (
Vinh Tran140d5882022-06-10 14:23:27 -040018 "fmt"
Colin Cross2a076922018-10-04 23:28:25 -070019 "os"
Paul Duffin672cb9f2021-03-03 02:30:37 +000020 "regexp"
Colin Cross2a076922018-10-04 23:28:25 -070021 "testing"
22
23 "android/soong/android"
Colin Crossba71a3f2019-03-18 12:12:48 -070024
25 "github.com/google/blueprint/proptools"
Colin Cross2a076922018-10-04 23:28:25 -070026)
27
Colin Cross2a076922018-10-04 23:28:25 -070028func TestMain(m *testing.M) {
Paul Duffine66946b2021-03-16 12:38:33 +000029 os.Exit(m.Run())
Colin Cross2a076922018-10-04 23:28:25 -070030}
31
Paul Duffin89648f92021-03-20 00:36:55 +000032var prepareForGenRuleTest = android.GroupFixturePreparers(
Paul Duffin672cb9f2021-03-03 02:30:37 +000033 android.PrepareForTestWithArchMutator,
34 android.PrepareForTestWithDefaults,
Paul Duffin672cb9f2021-03-03 02:30:37 +000035 android.PrepareForTestWithFilegroup,
36 PrepareForTestWithGenRuleBuildComponents,
37 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
Martin Stjernholmdbd814d2022-01-12 23:18:30 +000038 android.RegisterPrebuiltMutators(ctx)
Paul Duffin672cb9f2021-03-03 02:30:37 +000039 ctx.RegisterModuleType("tool", toolFactory)
Martin Stjernholmdbd814d2022-01-12 23:18:30 +000040 ctx.RegisterModuleType("prebuilt_tool", prebuiltToolFactory)
Colin Crossfa65cee2021-03-22 17:05:59 -070041 ctx.RegisterModuleType("output", outputProducerFactory)
Jooyung Han8c7e3ed2021-06-28 17:35:58 +090042 ctx.RegisterModuleType("use_source", useSourceFactory)
Paul Duffin672cb9f2021-03-03 02:30:37 +000043 }),
44 android.FixtureMergeMockFs(android.MockFS{
45 "tool": nil,
46 "tool_file1": nil,
47 "tool_file2": nil,
48 "in1": nil,
49 "in2": nil,
50 "in1.txt": nil,
51 "in2.txt": nil,
52 "in3.txt": nil,
53 }),
54)
Martin Stjernholm710ec3a2020-01-16 15:12:04 +000055
Paul Duffin672cb9f2021-03-03 02:30:37 +000056func testGenruleBp() string {
57 return `
Colin Cross2a076922018-10-04 23:28:25 -070058 tool {
59 name: "tool",
60 }
61
62 filegroup {
63 name: "tool_files",
64 srcs: [
65 "tool_file1",
66 "tool_file2",
67 ],
68 }
69
70 filegroup {
71 name: "1tool_file",
72 srcs: [
73 "tool_file1",
74 ],
75 }
76
77 filegroup {
78 name: "ins",
79 srcs: [
80 "in1",
81 "in2",
82 ],
83 }
84
85 filegroup {
86 name: "1in",
87 srcs: [
88 "in1",
89 ],
90 }
91
92 filegroup {
93 name: "empty",
94 }
95 `
Colin Cross2a076922018-10-04 23:28:25 -070096}
97
98func TestGenruleCmd(t *testing.T) {
99 testcases := []struct {
Yu Liu6a7940c2023-05-09 17:12:22 -0700100 name string
101 moduleName string
102 prop string
Colin Cross2a076922018-10-04 23:28:25 -0700103
Colin Crossba71a3f2019-03-18 12:12:48 -0700104 allowMissingDependencies bool
105
Colin Cross2a076922018-10-04 23:28:25 -0700106 err string
107 expect string
108 }{
109 {
110 name: "empty location tool",
111 prop: `
112 tools: ["tool"],
113 out: ["out"],
114 cmd: "$(location) > $(out)",
115 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800116 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700117 },
118 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700119 name: "empty location tool2",
120 prop: `
121 tools: [":tool"],
122 out: ["out"],
123 cmd: "$(location) > $(out)",
124 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800125 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700126 },
127 {
Colin Cross2a076922018-10-04 23:28:25 -0700128 name: "empty location tool file",
129 prop: `
130 tool_files: ["tool_file1"],
131 out: ["out"],
132 cmd: "$(location) > $(out)",
133 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800134 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700135 },
136 {
137 name: "empty location tool file fg",
138 prop: `
139 tool_files: [":1tool_file"],
140 out: ["out"],
141 cmd: "$(location) > $(out)",
142 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800143 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700144 },
145 {
146 name: "empty location tool and tool file",
147 prop: `
148 tools: ["tool"],
149 tool_files: ["tool_file1"],
150 out: ["out"],
151 cmd: "$(location) > $(out)",
152 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800153 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700154 },
155 {
156 name: "tool",
157 prop: `
158 tools: ["tool"],
159 out: ["out"],
160 cmd: "$(location tool) > $(out)",
161 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800162 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700163 },
164 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700165 name: "tool2",
166 prop: `
167 tools: [":tool"],
168 out: ["out"],
169 cmd: "$(location :tool) > $(out)",
170 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800171 expect: "__SBOX_SANDBOX_DIR__/tools/out/bin/tool > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700172 },
173 {
Colin Cross2a076922018-10-04 23:28:25 -0700174 name: "tool file",
175 prop: `
176 tool_files: ["tool_file1"],
177 out: ["out"],
178 cmd: "$(location tool_file1) > $(out)",
179 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800180 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700181 },
182 {
183 name: "tool file fg",
184 prop: `
185 tool_files: [":1tool_file"],
186 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700187 cmd: "$(location :1tool_file) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700188 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800189 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700190 },
191 {
192 name: "tool files",
193 prop: `
194 tool_files: [":tool_files"],
195 out: ["out"],
Colin Cross08f15ab2018-10-04 23:29:14 -0700196 cmd: "$(locations :tool_files) > $(out)",
Colin Cross2a076922018-10-04 23:28:25 -0700197 `,
Colin Crossba9e4032020-11-24 16:32:22 -0800198 expect: "__SBOX_SANDBOX_DIR__/tools/src/tool_file1 __SBOX_SANDBOX_DIR__/tools/src/tool_file2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700199 },
200 {
201 name: "in1",
202 prop: `
203 srcs: ["in1"],
204 out: ["out"],
205 cmd: "cat $(in) > $(out)",
206 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800207 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700208 },
209 {
210 name: "in1 fg",
211 prop: `
212 srcs: [":1in"],
213 out: ["out"],
214 cmd: "cat $(in) > $(out)",
215 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800216 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700217 },
218 {
219 name: "ins",
220 prop: `
221 srcs: ["in1", "in2"],
222 out: ["out"],
223 cmd: "cat $(in) > $(out)",
224 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800225 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700226 },
227 {
228 name: "ins fg",
229 prop: `
230 srcs: [":ins"],
231 out: ["out"],
232 cmd: "cat $(in) > $(out)",
233 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800234 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700235 },
236 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700237 name: "location in1",
238 prop: `
239 srcs: ["in1"],
240 out: ["out"],
241 cmd: "cat $(location in1) > $(out)",
242 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800243 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700244 },
245 {
246 name: "location in1 fg",
247 prop: `
248 srcs: [":1in"],
249 out: ["out"],
250 cmd: "cat $(location :1in) > $(out)",
251 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800252 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700253 },
254 {
255 name: "location ins",
256 prop: `
257 srcs: ["in1", "in2"],
258 out: ["out"],
259 cmd: "cat $(location in1) > $(out)",
260 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800261 expect: "cat in1 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700262 },
263 {
264 name: "location ins fg",
265 prop: `
266 srcs: [":ins"],
267 out: ["out"],
268 cmd: "cat $(locations :ins) > $(out)",
269 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800270 expect: "cat in1 in2 > __SBOX_SANDBOX_DIR__/out/out",
Colin Cross08f15ab2018-10-04 23:29:14 -0700271 },
272 {
Colin Cross2a076922018-10-04 23:28:25 -0700273 name: "outs",
274 prop: `
275 out: ["out", "out2"],
276 cmd: "echo foo > $(out)",
277 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800278 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross2a076922018-10-04 23:28:25 -0700279 },
280 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700281 name: "location out",
282 prop: `
283 out: ["out", "out2"],
284 cmd: "echo foo > $(location out2)",
285 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800286 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out2",
Colin Cross08f15ab2018-10-04 23:29:14 -0700287 },
288 {
Yu Liu6a7940c2023-05-09 17:12:22 -0700289 name: "depfile",
290 moduleName: "depfile_allowed_for_test",
Colin Cross2a076922018-10-04 23:28:25 -0700291 prop: `
292 out: ["out"],
293 depfile: true,
294 cmd: "echo foo > $(out) && touch $(depfile)",
295 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800296 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/out && touch __SBOX_DEPFILE__",
Colin Cross2a076922018-10-04 23:28:25 -0700297 },
298 {
299 name: "gendir",
300 prop: `
301 out: ["out"],
302 cmd: "echo foo > $(genDir)/foo && cp $(genDir)/foo $(out)",
303 `,
Colin Crosse16ce362020-11-12 08:29:30 -0800304 expect: "echo foo > __SBOX_SANDBOX_DIR__/out/foo && cp __SBOX_SANDBOX_DIR__/out/foo __SBOX_SANDBOX_DIR__/out/out",
Colin Cross2a076922018-10-04 23:28:25 -0700305 },
Colin Cross70c47412021-03-12 17:48:14 -0800306 {
307 name: "$",
308 prop: `
309 out: ["out"],
310 cmd: "echo $$ > $(out)",
311 `,
312 expect: "echo $ > __SBOX_SANDBOX_DIR__/out/out",
313 },
Colin Cross2a076922018-10-04 23:28:25 -0700314
315 {
316 name: "error empty location",
317 prop: `
318 out: ["out"],
319 cmd: "$(location) > $(out)",
320 `,
321 err: "at least one `tools` or `tool_files` is required if $(location) is used",
322 },
323 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700324 name: "error empty location no files",
325 prop: `
326 tool_files: [":empty"],
327 out: ["out"],
328 cmd: "$(location) > $(out)",
329 `,
330 err: `default label ":empty" has no files`,
331 },
332 {
333 name: "error empty location multiple files",
334 prop: `
335 tool_files: [":tool_files"],
336 out: ["out"],
337 cmd: "$(location) > $(out)",
338 `,
339 err: `default label ":tool_files" has multiple files`,
340 },
341 {
Colin Cross2a076922018-10-04 23:28:25 -0700342 name: "error location",
343 prop: `
344 out: ["out"],
345 cmd: "echo foo > $(location missing)",
346 `,
Anton Hanssonbebf5262022-02-23 11:42:38 +0000347 err: `unknown location label "missing" is not in srcs, out, tools or tool_files.`,
Colin Cross2a076922018-10-04 23:28:25 -0700348 },
349 {
Colin Cross08f15ab2018-10-04 23:29:14 -0700350 name: "error locations",
351 prop: `
352 out: ["out"],
353 cmd: "echo foo > $(locations missing)",
354 `,
Anton Hanssonbebf5262022-02-23 11:42:38 +0000355 err: `unknown locations label "missing" is not in srcs, out, tools or tool_files`,
Colin Cross08f15ab2018-10-04 23:29:14 -0700356 },
357 {
358 name: "error location no files",
359 prop: `
360 out: ["out"],
361 srcs: [":empty"],
362 cmd: "echo $(location :empty) > $(out)",
363 `,
364 err: `label ":empty" has no files`,
365 },
366 {
367 name: "error locations no files",
368 prop: `
369 out: ["out"],
370 srcs: [":empty"],
371 cmd: "echo $(locations :empty) > $(out)",
372 `,
373 err: `label ":empty" has no files`,
374 },
375 {
376 name: "error location multiple files",
377 prop: `
378 out: ["out"],
379 srcs: [":ins"],
380 cmd: "echo $(location :ins) > $(out)",
381 `,
382 err: `label ":ins" has multiple files`,
383 },
384 {
Colin Cross2a076922018-10-04 23:28:25 -0700385 name: "error variable",
386 prop: `
387 out: ["out"],
388 srcs: ["in1"],
389 cmd: "echo $(foo) > $(out)",
390 `,
391 err: `unknown variable '$(foo)'`,
392 },
393 {
394 name: "error depfile",
395 prop: `
396 out: ["out"],
397 cmd: "echo foo > $(out) && touch $(depfile)",
398 `,
399 err: "$(depfile) used without depfile property",
400 },
401 {
Yu Liu6a7940c2023-05-09 17:12:22 -0700402 name: "error no depfile",
403 moduleName: "depfile_allowed_for_test",
Colin Cross2a076922018-10-04 23:28:25 -0700404 prop: `
405 out: ["out"],
406 depfile: true,
407 cmd: "echo foo > $(out)",
408 `,
409 err: "specified depfile=true but did not include a reference to '${depfile}' in cmd",
410 },
411 {
412 name: "error no out",
413 prop: `
414 cmd: "echo foo > $(out)",
415 `,
416 err: "must have at least one output file",
417 },
Colin Crossba71a3f2019-03-18 12:12:48 -0700418 {
419 name: "srcs allow missing dependencies",
420 prop: `
421 srcs: [":missing"],
422 out: ["out"],
423 cmd: "cat $(location :missing) > $(out)",
424 `,
425
426 allowMissingDependencies: true,
427
Jihoon Kangc170af42022-08-20 05:26:38 +0000428 expect: "cat '***missing srcs :missing***' > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700429 },
430 {
431 name: "tool allow missing dependencies",
432 prop: `
433 tools: [":missing"],
434 out: ["out"],
435 cmd: "$(location :missing) > $(out)",
436 `,
437
438 allowMissingDependencies: true,
439
Jihoon Kangc170af42022-08-20 05:26:38 +0000440 expect: "'***missing tool :missing***' > __SBOX_SANDBOX_DIR__/out/out",
Colin Crossba71a3f2019-03-18 12:12:48 -0700441 },
Colin Cross2a076922018-10-04 23:28:25 -0700442 }
443
444 for _, test := range testcases {
445 t.Run(test.name, func(t *testing.T) {
Yu Liu6a7940c2023-05-09 17:12:22 -0700446 moduleName := "gen"
447 if test.moduleName != "" {
448 moduleName = test.moduleName
449 }
450 bp := fmt.Sprintf(`
451 genrule {
452 name: "%s",
453 %s
454 }`, moduleName, test.prop)
Paul Duffin672cb9f2021-03-03 02:30:37 +0000455 var expectedErrors []string
456 if test.err != "" {
457 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross2a076922018-10-04 23:28:25 -0700458 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000459
Paul Duffin89648f92021-03-20 00:36:55 +0000460 result := android.GroupFixturePreparers(
461 prepareForGenRuleTest,
Paul Duffin672cb9f2021-03-03 02:30:37 +0000462 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
463 variables.Allow_missing_dependencies = proptools.BoolPtr(test.allowMissingDependencies)
464 }),
Yu Liu6a7940c2023-05-09 17:12:22 -0700465 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
466 variables.GenruleSandboxing = proptools.BoolPtr(true)
467 }),
Paul Duffin672cb9f2021-03-03 02:30:37 +0000468 android.FixtureModifyContext(func(ctx *android.TestContext) {
469 ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
470 }),
471 ).
472 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
473 RunTestWithBp(t, testGenruleBp()+bp)
474
475 if expectedErrors != nil {
Colin Cross2a076922018-10-04 23:28:25 -0700476 return
477 }
478
Yu Liu6a7940c2023-05-09 17:12:22 -0700479 gen := result.Module(moduleName, "").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +0000480 android.AssertStringEquals(t, "raw commands", test.expect, gen.rawCommands[0])
Colin Cross2a076922018-10-04 23:28:25 -0700481 })
482 }
Colin Cross1a527682019-09-23 15:55:30 -0700483}
484
Bill Peckhamc087be12020-02-13 15:55:10 -0800485func TestGenruleHashInputs(t *testing.T) {
486
487 // The basic idea here is to verify that the sbox command (which is
488 // in the Command field of the generate rule) contains a hash of the
489 // inputs, but only if $(in) is not referenced in the genrule cmd
490 // property.
491
492 // By including a hash of the inputs, we cause the rule to re-run if
493 // the list of inputs changes (because the sbox command changes).
494
495 // However, if the genrule cmd property already contains $(in), then
496 // the dependency is already expressed, so we don't need to include the
497 // hash in that case.
498
499 bp := `
500 genrule {
501 name: "hash0",
502 srcs: ["in1.txt", "in2.txt"],
503 out: ["out"],
504 cmd: "echo foo > $(out)",
505 }
506 genrule {
507 name: "hash1",
508 srcs: ["*.txt"],
509 out: ["out"],
510 cmd: "echo bar > $(out)",
511 }
512 genrule {
513 name: "hash2",
514 srcs: ["*.txt"],
515 out: ["out"],
516 cmd: "echo $(in) > $(out)",
517 }
518 `
519 testcases := []struct {
520 name string
521 expectedHash string
522 }{
523 {
524 name: "hash0",
Colin Cross3d680512020-11-13 16:23:53 -0800525 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt' | sha256sum
526 expectedHash: "18da75b9b1cc74b09e365b4ca2e321b5d618f438cc632b387ad9dc2ab4b20e9d",
Bill Peckhamc087be12020-02-13 15:55:10 -0800527 },
528 {
529 name: "hash1",
Colin Cross3d680512020-11-13 16:23:53 -0800530 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
531 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800532 },
533 {
534 name: "hash2",
Colin Cross3d680512020-11-13 16:23:53 -0800535 // sha256 value obtained from: echo -en 'in1.txt\nin2.txt\nin3.txt' | sha256sum
536 expectedHash: "a38d432a4b19df93140e1f1fe26c97ff0387dae01fe506412b47208f0595fb45",
Bill Peckhamc087be12020-02-13 15:55:10 -0800537 },
538 }
539
Paul Duffin89648f92021-03-20 00:36:55 +0000540 result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp)
Bill Peckhamc087be12020-02-13 15:55:10 -0800541
542 for _, test := range testcases {
543 t.Run(test.name, func(t *testing.T) {
Paul Duffine84b1332021-03-12 11:59:43 +0000544 gen := result.ModuleForTests(test.name, "")
Colin Crosse16ce362020-11-12 08:29:30 -0800545 manifest := android.RuleBuilderSboxProtoForTests(t, gen.Output("genrule.sbox.textproto"))
546 hash := manifest.Commands[0].GetInputHash()
Bill Peckhamc087be12020-02-13 15:55:10 -0800547
Paul Duffine84b1332021-03-12 11:59:43 +0000548 android.AssertStringEquals(t, "hash", test.expectedHash, hash)
Bill Peckhamc087be12020-02-13 15:55:10 -0800549 })
550 }
551}
552
Colin Cross1a527682019-09-23 15:55:30 -0700553func TestGenSrcs(t *testing.T) {
554 testcases := []struct {
555 name string
556 prop string
557
558 allowMissingDependencies bool
559
560 err string
561 cmds []string
562 deps []string
563 files []string
564 }{
565 {
566 name: "gensrcs",
567 prop: `
568 tools: ["tool"],
569 srcs: ["in1.txt", "in2.txt"],
570 cmd: "$(location) $(in) > $(out)",
571 `,
572 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800573 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in1.txt > __SBOX_SANDBOX_DIR__/out/in1.h' && bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in2.txt > __SBOX_SANDBOX_DIR__/out/in2.h'",
Colin Cross1a527682019-09-23 15:55:30 -0700574 },
Paul Duffine66946b2021-03-16 12:38:33 +0000575 deps: []string{
576 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
577 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
578 },
579 files: []string{
580 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
581 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
582 },
Colin Cross1a527682019-09-23 15:55:30 -0700583 },
584 {
585 name: "shards",
586 prop: `
587 tools: ["tool"],
588 srcs: ["in1.txt", "in2.txt", "in3.txt"],
589 cmd: "$(location) $(in) > $(out)",
590 shard_size: 2,
591 `,
592 cmds: []string{
Colin Crossba9e4032020-11-24 16:32:22 -0800593 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in1.txt > __SBOX_SANDBOX_DIR__/out/in1.h' && bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in2.txt > __SBOX_SANDBOX_DIR__/out/in2.h'",
594 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in3.txt > __SBOX_SANDBOX_DIR__/out/in3.h'",
Colin Cross1a527682019-09-23 15:55:30 -0700595 },
Paul Duffine66946b2021-03-16 12:38:33 +0000596 deps: []string{
597 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
598 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
599 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
600 },
601 files: []string{
602 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
603 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
604 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
605 },
Colin Cross1a527682019-09-23 15:55:30 -0700606 },
Liz Kammer81fec182023-06-09 13:33:45 -0400607 {
608 name: "data",
609 prop: `
610 tools: ["tool"],
611 srcs: ["in1.txt", "in2.txt", "in3.txt"],
612 cmd: "$(location) $(in) --extra_input=$(location baz.txt) > $(out)",
613 data: ["baz.txt"],
614 shard_size: 2,
615 `,
616 cmds: []string{
617 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in1.txt --extra_input=baz.txt > __SBOX_SANDBOX_DIR__/out/in1.h' && bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in2.txt --extra_input=baz.txt > __SBOX_SANDBOX_DIR__/out/in2.h'",
618 "bash -c '__SBOX_SANDBOX_DIR__/tools/out/bin/tool in3.txt --extra_input=baz.txt > __SBOX_SANDBOX_DIR__/out/in3.h'",
619 },
620 deps: []string{
621 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
622 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
623 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
624 },
625 files: []string{
626 "out/soong/.intermediates/gen/gen/gensrcs/in1.h",
627 "out/soong/.intermediates/gen/gen/gensrcs/in2.h",
628 "out/soong/.intermediates/gen/gen/gensrcs/in3.h",
629 },
630 },
Colin Cross1a527682019-09-23 15:55:30 -0700631 }
632
633 for _, test := range testcases {
634 t.Run(test.name, func(t *testing.T) {
Colin Cross1a527682019-09-23 15:55:30 -0700635 bp := "gensrcs {\n"
636 bp += `name: "gen",` + "\n"
637 bp += `output_extension: "h",` + "\n"
638 bp += test.prop
639 bp += "}\n"
640
Paul Duffin672cb9f2021-03-03 02:30:37 +0000641 var expectedErrors []string
642 if test.err != "" {
643 expectedErrors = append(expectedErrors, regexp.QuoteMeta(test.err))
Colin Cross1a527682019-09-23 15:55:30 -0700644 }
Paul Duffin672cb9f2021-03-03 02:30:37 +0000645
Paul Duffin89648f92021-03-20 00:36:55 +0000646 result := prepareForGenRuleTest.
Paul Duffin672cb9f2021-03-03 02:30:37 +0000647 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
648 RunTestWithBp(t, testGenruleBp()+bp)
649
650 if expectedErrors != nil {
Colin Cross1a527682019-09-23 15:55:30 -0700651 return
652 }
653
Paul Duffin672cb9f2021-03-03 02:30:37 +0000654 gen := result.Module("gen", "").(*Module)
Paul Duffine84b1332021-03-12 11:59:43 +0000655 android.AssertDeepEquals(t, "cmd", test.cmds, gen.rawCommands)
Colin Cross1a527682019-09-23 15:55:30 -0700656
Paul Duffine66946b2021-03-16 12:38:33 +0000657 android.AssertPathsRelativeToTopEquals(t, "deps", test.deps, gen.outputDeps)
Colin Cross1a527682019-09-23 15:55:30 -0700658
Paul Duffine66946b2021-03-16 12:38:33 +0000659 android.AssertPathsRelativeToTopEquals(t, "files", test.files, gen.outputFiles)
Colin Cross1a527682019-09-23 15:55:30 -0700660 })
661 }
Colin Cross2a076922018-10-04 23:28:25 -0700662}
663
Yu Liu6a7940c2023-05-09 17:12:22 -0700664func TestGenruleAllowlistingDepfile(t *testing.T) {
Vinh Tran140d5882022-06-10 14:23:27 -0400665 tests := []struct {
Yu Liu6a7940c2023-05-09 17:12:22 -0700666 name string
667 prop string
668 err string
669 moduleName string
Vinh Tran140d5882022-06-10 14:23:27 -0400670 }{
671 {
Yu Liu6a7940c2023-05-09 17:12:22 -0700672 name: `error when module is not allowlisted`,
Vinh Tran140d5882022-06-10 14:23:27 -0400673 prop: `
674 depfile: true,
675 cmd: "cat $(in) > $(out) && cat $(depfile)",
676 `,
Yu Liu6a7940c2023-05-09 17:12:22 -0700677 err: "depfile: Deprecated to ensure the module type is convertible to Bazel",
Vinh Tran140d5882022-06-10 14:23:27 -0400678 },
679 {
Yu Liu6a7940c2023-05-09 17:12:22 -0700680 name: `no error when module is allowlisted`,
Vinh Tran140d5882022-06-10 14:23:27 -0400681 prop: `
682 depfile: true,
683 cmd: "cat $(in) > $(out) && cat $(depfile)",
684 `,
Yu Liu6a7940c2023-05-09 17:12:22 -0700685 moduleName: `depfile_allowed_for_test`,
Vinh Tran140d5882022-06-10 14:23:27 -0400686 },
687 }
688 for _, test := range tests {
689 t.Run(test.name, func(t *testing.T) {
Yu Liu6a7940c2023-05-09 17:12:22 -0700690 moduleName := "foo"
691 if test.moduleName != "" {
692 moduleName = test.moduleName
693 }
Vinh Tran140d5882022-06-10 14:23:27 -0400694 bp := fmt.Sprintf(`
695 gensrcs {
Yu Liu6a7940c2023-05-09 17:12:22 -0700696 name: "%s",
Vinh Tran140d5882022-06-10 14:23:27 -0400697 srcs: ["data.txt"],
698 %s
Yu Liu6a7940c2023-05-09 17:12:22 -0700699 }`, moduleName, test.prop)
Vinh Tran140d5882022-06-10 14:23:27 -0400700
701 var expectedErrors []string
702 if test.err != "" {
703 expectedErrors = append(expectedErrors, test.err)
704 }
705 android.GroupFixturePreparers(
706 prepareForGenRuleTest,
707 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
Yu Liu6a7940c2023-05-09 17:12:22 -0700708 variables.GenruleSandboxing = proptools.BoolPtr(true)
Vinh Tran140d5882022-06-10 14:23:27 -0400709 }),
710 ).
711 ExtendWithErrorHandler(android.FixtureExpectsAllErrorsToMatchAPattern(expectedErrors)).
712 RunTestWithBp(t, bp)
713 })
714
715 }
716}
717
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800718func TestGenruleDefaults(t *testing.T) {
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800719 bp := `
720 genrule_defaults {
721 name: "gen_defaults1",
722 cmd: "cp $(in) $(out)",
723 }
724
725 genrule_defaults {
726 name: "gen_defaults2",
727 srcs: ["in1"],
728 }
729
730 genrule {
731 name: "gen",
732 out: ["out"],
733 defaults: ["gen_defaults1", "gen_defaults2"],
734 }
735 `
Paul Duffin672cb9f2021-03-03 02:30:37 +0000736
Paul Duffin89648f92021-03-20 00:36:55 +0000737 result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp)
Paul Duffin672cb9f2021-03-03 02:30:37 +0000738
739 gen := result.Module("gen", "").(*Module)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800740
Colin Crosse16ce362020-11-12 08:29:30 -0800741 expectedCmd := "cp in1 __SBOX_SANDBOX_DIR__/out/out"
Paul Duffine84b1332021-03-12 11:59:43 +0000742 android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800743
744 expectedSrcs := []string{"in1"}
Paul Duffine84b1332021-03-12 11:59:43 +0000745 android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.Srcs)
Jaewoong Jung98716bd2018-12-10 08:13:18 -0800746}
747
Colin Crossfa65cee2021-03-22 17:05:59 -0700748func TestGenruleAllowMissingDependencies(t *testing.T) {
749 bp := `
750 output {
751 name: "disabled",
752 enabled: false,
753 }
754
755 genrule {
756 name: "gen",
757 srcs: [
758 ":disabled",
759 ],
760 out: ["out"],
761 cmd: "cat $(in) > $(out)",
762 }
763 `
Paul Duffin79abe572021-03-29 02:16:14 +0100764 result := android.GroupFixturePreparers(
765 prepareForGenRuleTest,
Colin Crossfa65cee2021-03-22 17:05:59 -0700766 android.FixtureModifyConfigAndContext(
767 func(config android.Config, ctx *android.TestContext) {
768 config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
769 ctx.SetAllowMissingDependencies(true)
770 })).RunTestWithBp(t, bp)
771
772 gen := result.ModuleForTests("gen", "").Output("out")
773 if gen.Rule != android.ErrorRule {
774 t.Errorf("Expected missing dependency error rule for gen, got %q", gen.Rule.String())
775 }
776}
777
Jooyung Han8c7e3ed2021-06-28 17:35:58 +0900778func TestGenruleOutputFiles(t *testing.T) {
779 bp := `
780 genrule {
781 name: "gen",
782 out: ["foo", "sub/bar"],
783 cmd: "echo foo > $(location foo) && echo bar > $(location sub/bar)",
784 }
785 use_source {
786 name: "gen_foo",
787 srcs: [":gen{foo}"],
788 }
789 use_source {
790 name: "gen_bar",
791 srcs: [":gen{sub/bar}"],
792 }
793 use_source {
794 name: "gen_all",
795 srcs: [":gen"],
796 }
797 `
798
799 result := prepareForGenRuleTest.RunTestWithBp(t, testGenruleBp()+bp)
800 android.AssertPathsRelativeToTopEquals(t,
801 "genrule.tag with output",
802 []string{"out/soong/.intermediates/gen/gen/foo"},
803 result.ModuleForTests("gen_foo", "").Module().(*useSource).srcs)
804 android.AssertPathsRelativeToTopEquals(t,
805 "genrule.tag with output in subdir",
806 []string{"out/soong/.intermediates/gen/gen/sub/bar"},
807 result.ModuleForTests("gen_bar", "").Module().(*useSource).srcs)
808 android.AssertPathsRelativeToTopEquals(t,
809 "genrule.tag with all",
810 []string{"out/soong/.intermediates/gen/gen/foo", "out/soong/.intermediates/gen/gen/sub/bar"},
811 result.ModuleForTests("gen_all", "").Module().(*useSource).srcs)
812}
813
Vinh Tran370e08c2022-09-23 18:09:01 -0400814func TestGenSrcsWithNonRootAndroidBpOutputFiles(t *testing.T) {
815 result := android.GroupFixturePreparers(
816 prepareForGenRuleTest,
817 android.FixtureMergeMockFs(android.MockFS{
818 "external-protos/path/Android.bp": []byte(`
819 filegroup {
820 name: "external-protos",
821 srcs: ["baz/baz.proto", "bar.proto"],
822 }
823 `),
824 "package-dir/Android.bp": []byte(`
825 gensrcs {
826 name: "module-name",
827 cmd: "mkdir -p $(genDir) && cat $(in) >> $(genDir)/$(out)",
828 srcs: [
829 "src/foo.proto",
830 ":external-protos",
831 ],
832 output_extension: "proto.h",
833 }
834 `),
835 }),
836 ).RunTest(t)
837
838 exportedIncludeDir := "out/soong/.intermediates/package-dir/module-name/gen/gensrcs"
839 gen := result.Module("module-name", "").(*Module)
840
841 android.AssertPathsRelativeToTopEquals(
842 t,
843 "include path",
844 []string{exportedIncludeDir},
845 gen.exportedIncludeDirs,
846 )
847 android.AssertPathsRelativeToTopEquals(
848 t,
849 "files",
850 []string{
851 exportedIncludeDir + "/package-dir/src/foo.proto.h",
852 exportedIncludeDir + "/external-protos/path/baz/baz.proto.h",
853 exportedIncludeDir + "/external-protos/path/bar.proto.h",
854 },
855 gen.outputFiles,
856 )
857}
858
859func TestGenSrcsWithSrcsFromExternalPackage(t *testing.T) {
860 bp := `
861 gensrcs {
862 name: "module-name",
863 cmd: "mkdir -p $(genDir) && cat $(in) >> $(genDir)/$(out)",
864 srcs: [
865 ":external-protos",
866 ],
867 output_extension: "proto.h",
868 }
869 `
870 result := android.GroupFixturePreparers(
871 prepareForGenRuleTest,
872 android.FixtureMergeMockFs(android.MockFS{
873 "external-protos/path/Android.bp": []byte(`
874 filegroup {
875 name: "external-protos",
876 srcs: ["foo/foo.proto", "bar.proto"],
877 }
878 `),
879 }),
880 ).RunTestWithBp(t, bp)
881
882 exportedIncludeDir := "out/soong/.intermediates/module-name/gen/gensrcs"
883 gen := result.Module("module-name", "").(*Module)
884
885 android.AssertPathsRelativeToTopEquals(
886 t,
887 "include path",
888 []string{exportedIncludeDir},
889 gen.exportedIncludeDirs,
890 )
891 android.AssertPathsRelativeToTopEquals(
892 t,
893 "files",
894 []string{
895 exportedIncludeDir + "/external-protos/path/foo/foo.proto.h",
896 exportedIncludeDir + "/external-protos/path/bar.proto.h",
897 },
898 gen.outputFiles,
899 )
900}
901
Martin Stjernholmdbd814d2022-01-12 23:18:30 +0000902func TestPrebuiltTool(t *testing.T) {
903 testcases := []struct {
904 name string
905 bp string
906 expectedToolName string
907 }{
908 {
909 name: "source only",
910 bp: `
911 tool { name: "tool" }
912 `,
913 expectedToolName: "bin/tool",
914 },
915 {
916 name: "prebuilt only",
917 bp: `
918 prebuilt_tool { name: "tool" }
919 `,
920 expectedToolName: "prebuilt_bin/tool",
921 },
922 {
923 name: "source preferred",
924 bp: `
925 tool { name: "tool" }
926 prebuilt_tool { name: "tool" }
927 `,
928 expectedToolName: "bin/tool",
929 },
930 {
931 name: "prebuilt preferred",
932 bp: `
933 tool { name: "tool" }
934 prebuilt_tool { name: "tool", prefer: true }
935 `,
936 expectedToolName: "prebuilt_bin/prebuilt_tool",
937 },
938 {
939 name: "source disabled",
940 bp: `
941 tool { name: "tool", enabled: false }
942 prebuilt_tool { name: "tool" }
943 `,
944 expectedToolName: "prebuilt_bin/prebuilt_tool",
945 },
946 }
947
948 for _, test := range testcases {
949 t.Run(test.name, func(t *testing.T) {
950 result := prepareForGenRuleTest.RunTestWithBp(t, test.bp+`
951 genrule {
952 name: "gen",
953 tools: ["tool"],
954 out: ["foo"],
955 cmd: "$(location tool)",
956 }
957 `)
958 gen := result.Module("gen", "").(*Module)
959 expectedCmd := "__SBOX_SANDBOX_DIR__/tools/out/" + test.expectedToolName
960 android.AssertStringEquals(t, "command", expectedCmd, gen.rawCommands[0])
961 })
962 }
963}
964
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400965func TestGenruleWithBazel(t *testing.T) {
966 bp := `
967 genrule {
968 name: "foo",
969 out: ["one.txt", "two.txt"],
Chris Parsonsaa8be052020-10-14 16:22:37 -0400970 bazel_module: { label: "//foo/bar:bar" },
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400971 }
972 `
973
Paul Duffin89648f92021-03-20 00:36:55 +0000974 result := android.GroupFixturePreparers(
975 prepareForGenRuleTest, android.FixtureModifyConfig(func(config android.Config) {
976 config.BazelContext = android.MockBazelContext{
Liz Kammera92e8442021-04-07 20:25:21 -0400977 OutputBaseDir: "outputbase",
978 LabelToOutputFiles: map[string][]string{
Paul Duffin89648f92021-03-20 00:36:55 +0000979 "//foo/bar:bar": []string{"bazelone.txt", "bazeltwo.txt"}}}
980 })).RunTestWithBp(t, testGenruleBp()+bp)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400981
Paul Duffin672cb9f2021-03-03 02:30:37 +0000982 gen := result.Module("foo", "").(*Module)
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400983
Chris Parsonsdbcb1ff2020-12-10 17:19:18 -0500984 expectedOutputFiles := []string{"outputbase/execroot/__main__/bazelone.txt",
985 "outputbase/execroot/__main__/bazeltwo.txt"}
Paul Duffine84b1332021-03-12 11:59:43 +0000986 android.AssertDeepEquals(t, "output files", expectedOutputFiles, gen.outputFiles.Strings())
987 android.AssertDeepEquals(t, "output deps", expectedOutputFiles, gen.outputDeps.Strings())
Chris Parsonsf3c96ef2020-09-29 02:23:17 -0400988}
989
Jihoon Kangc170af42022-08-20 05:26:38 +0000990func TestGenruleWithGlobPaths(t *testing.T) {
991 testcases := []struct {
992 name string
993 bp string
994 additionalFiles android.MockFS
995 expectedCmd string
996 }{
997 {
998 name: "single file in directory with $ sign",
999 bp: `
1000 genrule {
1001 name: "gen",
1002 srcs: ["inn*.txt"],
1003 out: ["out.txt"],
1004 cmd: "cp $(in) $(out)",
1005 }
1006 `,
1007 additionalFiles: android.MockFS{"inn$1.txt": nil},
1008 expectedCmd: "cp 'inn$1.txt' __SBOX_SANDBOX_DIR__/out/out.txt",
1009 },
1010 {
1011 name: "multiple file in directory with $ sign",
1012 bp: `
1013 genrule {
1014 name: "gen",
1015 srcs: ["inn*.txt"],
1016 out: ["."],
1017 cmd: "cp $(in) $(out)",
1018 }
1019 `,
1020 additionalFiles: android.MockFS{"inn$1.txt": nil, "inn$2.txt": nil},
1021 expectedCmd: "cp 'inn$1.txt' 'inn$2.txt' __SBOX_SANDBOX_DIR__/out",
1022 },
1023 {
1024 name: "file in directory with other shell unsafe character",
1025 bp: `
1026 genrule {
1027 name: "gen",
1028 srcs: ["inn*.txt"],
1029 out: ["out.txt"],
1030 cmd: "cp $(in) $(out)",
1031 }
1032 `,
1033 additionalFiles: android.MockFS{"inn@1.txt": nil},
1034 expectedCmd: "cp 'inn@1.txt' __SBOX_SANDBOX_DIR__/out/out.txt",
1035 },
1036 {
1037 name: "glob location param with filepath containing $",
1038 bp: `
1039 genrule {
1040 name: "gen",
1041 srcs: ["**/inn*"],
1042 out: ["."],
1043 cmd: "cp $(in) $(location **/inn*)",
1044 }
1045 `,
1046 additionalFiles: android.MockFS{"a/inn$1.txt": nil},
1047 expectedCmd: "cp 'a/inn$1.txt' 'a/inn$1.txt'",
1048 },
1049 {
1050 name: "glob locations param with filepath containing $",
1051 bp: `
1052 genrule {
1053 name: "gen",
1054 tool_files: ["**/inn*"],
1055 out: ["out.txt"],
1056 cmd: "cp $(locations **/inn*) $(out)",
1057 }
1058 `,
1059 additionalFiles: android.MockFS{"a/inn$1.txt": nil},
1060 expectedCmd: "cp '__SBOX_SANDBOX_DIR__/tools/src/a/inn$1.txt' __SBOX_SANDBOX_DIR__/out/out.txt",
1061 },
1062 }
1063
1064 for _, test := range testcases {
1065 t.Run(test.name, func(t *testing.T) {
1066 result := android.GroupFixturePreparers(
1067 prepareForGenRuleTest,
1068 android.FixtureMergeMockFs(test.additionalFiles),
1069 ).RunTestWithBp(t, test.bp)
1070 gen := result.Module("gen", "").(*Module)
1071 android.AssertStringEquals(t, "command", test.expectedCmd, gen.rawCommands[0])
1072 })
1073 }
1074}
1075
Colin Cross2a076922018-10-04 23:28:25 -07001076type testTool struct {
1077 android.ModuleBase
1078 outputFile android.Path
1079}
1080
1081func toolFactory() android.Module {
1082 module := &testTool{}
1083 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
1084 return module
1085}
1086
Colin Cross2a076922018-10-04 23:28:25 -07001087func (t *testTool) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Crossba9e4032020-11-24 16:32:22 -08001088 t.outputFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), android.PathForOutput(ctx, ctx.ModuleName()))
Colin Cross2a076922018-10-04 23:28:25 -07001089}
1090
1091func (t *testTool) HostToolPath() android.OptionalPath {
1092 return android.OptionalPathForPath(t.outputFile)
1093}
1094
Martin Stjernholmdbd814d2022-01-12 23:18:30 +00001095type prebuiltTestTool struct {
1096 android.ModuleBase
1097 prebuilt android.Prebuilt
1098 testTool
1099}
1100
1101func (p *prebuiltTestTool) Name() string {
1102 return p.prebuilt.Name(p.ModuleBase.Name())
1103}
1104
1105func (p *prebuiltTestTool) Prebuilt() *android.Prebuilt {
1106 return &p.prebuilt
1107}
1108
1109func (t *prebuiltTestTool) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1110 t.outputFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "prebuilt_bin"), ctx.ModuleName(), android.PathForOutput(ctx, ctx.ModuleName()))
1111}
1112
1113func prebuiltToolFactory() android.Module {
1114 module := &prebuiltTestTool{}
1115 android.InitPrebuiltModuleWithoutSrcs(module)
1116 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
1117 return module
1118}
1119
Colin Crossfe17f6f2019-03-28 19:30:56 -07001120var _ android.HostToolProvider = (*testTool)(nil)
Martin Stjernholmdbd814d2022-01-12 23:18:30 +00001121var _ android.HostToolProvider = (*prebuiltTestTool)(nil)
Colin Crossfa65cee2021-03-22 17:05:59 -07001122
1123type testOutputProducer struct {
1124 android.ModuleBase
1125 outputFile android.Path
1126}
1127
1128func outputProducerFactory() android.Module {
1129 module := &testOutputProducer{}
1130 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
1131 return module
1132}
1133
1134func (t *testOutputProducer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1135 t.outputFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), android.PathForOutput(ctx, ctx.ModuleName()))
1136}
1137
1138func (t *testOutputProducer) OutputFiles(tag string) (android.Paths, error) {
1139 return android.Paths{t.outputFile}, nil
1140}
1141
1142var _ android.OutputFileProducer = (*testOutputProducer)(nil)
Jooyung Han8c7e3ed2021-06-28 17:35:58 +09001143
1144type useSource struct {
1145 android.ModuleBase
1146 props struct {
1147 Srcs []string `android:"path"`
1148 }
1149 srcs android.Paths
1150}
1151
1152func (s *useSource) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1153 s.srcs = android.PathsForModuleSrc(ctx, s.props.Srcs)
1154}
1155
1156func useSourceFactory() android.Module {
1157 module := &useSource{}
1158 module.AddProperties(&module.props)
1159 android.InitAndroidModule(module)
1160 return module
1161}