blob: edc5c4a9955ce0ae19b682e86bb5873d572f0210 [file] [log] [blame]
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxf5a3eac2021-08-23 17:05:17 +00001// Copyright 2021 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
Liz Kammer2dd9ca42020-11-25 16:06:39 -080015package bp2build
16
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux0da7ce62021-08-23 17:04:20 +000017/*
18For shareable/common bp2build testing functionality and dumping ground for
19specific-but-shared functionality among tests in package
20*/
21
Liz Kammer2dd9ca42020-11-25 16:06:39 -080022import (
Liz Kammer7a210ac2021-09-22 15:52:58 -040023 "fmt"
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000024 "strings"
Rupert Shuttleworth06559d02021-05-19 09:14:26 -040025 "testing"
26
Liz Kammer2dd9ca42020-11-25 16:06:39 -080027 "android/soong/android"
Sam Delmerico24c56032022-03-28 19:53:03 +000028 "android/soong/android/allowlists"
Jingwen Chen73850672020-12-14 08:25:34 -050029 "android/soong/bazel"
Liz Kammer2dd9ca42020-11-25 16:06:39 -080030)
31
Jingwen Chen91220d72021-03-24 02:18:33 -040032var (
33 // A default configuration for tests to not have to specify bp2build_available on top level targets.
Sam Delmerico24c56032022-03-28 19:53:03 +000034 bp2buildConfig = android.NewBp2BuildAllowlist().SetDefaultConfig(
35 allowlists.Bp2BuildConfig{
36 android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
37 },
38 )
Rupert Shuttleworth06559d02021-05-19 09:14:26 -040039
40 buildDir string
Jingwen Chen91220d72021-03-24 02:18:33 -040041)
42
Jingwen Chen5146ac02021-09-02 11:44:42 +000043func checkError(t *testing.T, errs []error, expectedErr error) bool {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000044 t.Helper()
Jingwen Chen5146ac02021-09-02 11:44:42 +000045
Jingwen Chen5146ac02021-09-02 11:44:42 +000046 if len(errs) != 1 {
Liz Kammer6eff3232021-08-26 08:37:59 -040047 return false
Jingwen Chen5146ac02021-09-02 11:44:42 +000048 }
Liz Kammer54309532021-12-14 12:21:22 -050049 if strings.Contains(errs[0].Error(), expectedErr.Error()) {
Jingwen Chen5146ac02021-09-02 11:44:42 +000050 return true
51 }
52
53 return false
54}
55
Sam Delmerico3177a6e2022-06-21 19:28:33 +000056func errored(t *testing.T, tc Bp2buildTestCase, errs []error) bool {
Jingwen Chen5146ac02021-09-02 11:44:42 +000057 t.Helper()
Sam Delmerico3177a6e2022-06-21 19:28:33 +000058 if tc.ExpectedErr != nil {
Jingwen Chen5146ac02021-09-02 11:44:42 +000059 // Rely on checkErrors, as this test case is expected to have an error.
60 return false
61 }
62
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000063 if len(errs) > 0 {
64 for _, err := range errs {
Sam Delmerico3177a6e2022-06-21 19:28:33 +000065 t.Errorf("%s: %s", tc.Description, err)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000066 }
67 return true
68 }
Jingwen Chen5146ac02021-09-02 11:44:42 +000069
70 // All good, continue execution.
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000071 return false
72}
73
Trevor Radcliffe1b4b2d92022-09-01 18:57:01 +000074func RunBp2BuildTestCaseSimple(t *testing.T, tc Bp2buildTestCase) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000075 t.Helper()
Sam Delmerico3177a6e2022-06-21 19:28:33 +000076 RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000077}
78
Sam Delmerico3177a6e2022-06-21 19:28:33 +000079type Bp2buildTestCase struct {
80 Description string
81 ModuleTypeUnderTest string
82 ModuleTypeUnderTestFactory android.ModuleFactory
83 Blueprint string
84 ExpectedBazelTargets []string
85 Filesystem map[string]string
86 Dir string
Trevor Radcliffe58ea4512022-04-07 20:36:39 +000087 // An error with a string contained within the string of the expected error
Sam Delmerico3177a6e2022-06-21 19:28:33 +000088 ExpectedErr error
89 UnconvertedDepsMode unconvertedDepsMode
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000090}
91
Sam Delmerico3177a6e2022-06-21 19:28:33 +000092func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +000093 t.Helper()
94 dir := "."
95 filesystem := make(map[string][]byte)
96 toParse := []string{
97 "Android.bp",
98 }
Sam Delmerico3177a6e2022-06-21 19:28:33 +000099 for f, content := range tc.Filesystem {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000100 if strings.HasSuffix(f, "Android.bp") {
101 toParse = append(toParse, f)
102 }
103 filesystem[f] = []byte(content)
104 }
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000105 config := android.TestConfig(buildDir, nil, tc.Blueprint, filesystem)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000106 ctx := android.NewTestContext(config)
107
108 registerModuleTypes(ctx)
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000109 ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000110 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000111 ctx.RegisterForBazelConversion()
112
Jingwen Chen5146ac02021-09-02 11:44:42 +0000113 _, parseErrs := ctx.ParseFileList(dir, toParse)
114 if errored(t, tc, parseErrs) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000115 return
116 }
Jingwen Chen5146ac02021-09-02 11:44:42 +0000117 _, resolveDepsErrs := ctx.ResolveDependencies(config)
118 if errored(t, tc, resolveDepsErrs) {
119 return
120 }
121
Cole Faustb09da7e2022-05-18 10:57:33 -0700122 parseAndResolveErrs := append(parseErrs, resolveDepsErrs...)
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000123 if tc.ExpectedErr != nil && checkError(t, parseAndResolveErrs, tc.ExpectedErr) {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000124 return
125 }
126
127 checkDir := dir
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000128 if tc.Dir != "" {
129 checkDir = tc.Dir
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000130 }
131 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000132 codegenCtx.unconvertedDepMode = tc.UnconvertedDepsMode
Liz Kammer6eff3232021-08-26 08:37:59 -0400133 bazelTargets, errs := generateBazelTargetsForDir(codegenCtx, checkDir)
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000134 if tc.ExpectedErr != nil {
135 if checkError(t, errs, tc.ExpectedErr) {
Liz Kammer54309532021-12-14 12:21:22 -0500136 return
137 } else {
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000138 t.Errorf("Expected error: %q, got: %q and %q", tc.ExpectedErr, errs, parseAndResolveErrs)
Liz Kammer54309532021-12-14 12:21:22 -0500139 }
Liz Kammer6eff3232021-08-26 08:37:59 -0400140 } else {
141 android.FailIfErrored(t, errs)
142 }
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000143 if actualCount, expectedCount := len(bazelTargets), len(tc.ExpectedBazelTargets); actualCount != expectedCount {
Sasha Smundak9d2f1742022-08-04 13:28:38 -0700144 t.Errorf("%s: Expected %d bazel target (%s), got %d (%s)",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000145 tc.Description, expectedCount, tc.ExpectedBazelTargets, actualCount, bazelTargets)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000146 } else {
147 for i, target := range bazelTargets {
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000148 if w, g := tc.ExpectedBazelTargets[i], target.content; w != g {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000149 t.Errorf(
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux447f6c92021-08-31 20:30:36 +0000150 "%s: Expected generated Bazel target to be `%s`, got `%s`",
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000151 tc.Description, w, g)
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux1c92aef2021-08-23 16:10:00 +0000152 }
153 }
154 }
155}
156
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800157type nestedProps struct {
Liz Kammer46fb7ab2021-12-01 10:09:34 -0500158 Nested_prop *string
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800159}
160
Liz Kammer32a03392021-09-14 11:17:21 -0400161type EmbeddedProps struct {
Liz Kammer46fb7ab2021-12-01 10:09:34 -0500162 Embedded_prop *string
Liz Kammer32a03392021-09-14 11:17:21 -0400163}
164
165type OtherEmbeddedProps struct {
Liz Kammer46fb7ab2021-12-01 10:09:34 -0500166 Other_embedded_prop *string
Liz Kammer32a03392021-09-14 11:17:21 -0400167}
168
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800169type customProps struct {
Liz Kammer32a03392021-09-14 11:17:21 -0400170 EmbeddedProps
171 *OtherEmbeddedProps
172
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800173 Bool_prop bool
174 Bool_ptr_prop *bool
175 // Ensure that properties tagged `blueprint:mutated` are omitted
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux3a019a62022-06-23 16:02:44 +0000176 Int_prop int `blueprint:"mutated"`
177 Int64_ptr_prop *int64
178 String_prop string
179 String_literal_prop *string `android:"arch_variant"`
180 String_ptr_prop *string
181 String_list_prop []string
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800182
183 Nested_props nestedProps
184 Nested_props_ptr *nestedProps
Liz Kammer4562a3b2021-04-21 18:15:34 -0400185
Liz Kammer32b77cf2021-08-04 15:17:02 -0400186 Arch_paths []string `android:"path,arch_variant"`
187 Arch_paths_exclude []string `android:"path,arch_variant"`
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400188
189 // Prop used to indicate this conversion should be 1 module -> multiple targets
190 One_to_many_prop *bool
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800191}
192
193type customModule struct {
194 android.ModuleBase
Liz Kammerea6666f2021-02-17 10:17:28 -0500195 android.BazelModuleBase
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800196
197 props customProps
198}
199
200// OutputFiles is needed because some instances of this module use dist with a
201// tag property which requires the module implements OutputFileProducer.
202func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
203 return android.PathsForTesting("path" + tag), nil
204}
205
206func (m *customModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
207 // nothing for now.
208}
209
210func customModuleFactoryBase() android.Module {
211 module := &customModule{}
212 module.AddProperties(&module.props)
Liz Kammerea6666f2021-02-17 10:17:28 -0500213 android.InitBazelModule(module)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800214 return module
215}
216
Liz Kammerdfeb1202022-05-13 17:20:20 -0400217func customModuleFactoryHostAndDevice() android.Module {
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800218 m := customModuleFactoryBase()
Liz Kammer4562a3b2021-04-21 18:15:34 -0400219 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibBoth)
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800220 return m
221}
222
Liz Kammerdfeb1202022-05-13 17:20:20 -0400223func customModuleFactoryDeviceSupported() android.Module {
224 m := customModuleFactoryBase()
225 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibBoth)
226 return m
227}
228
229func customModuleFactoryHostSupported() android.Module {
230 m := customModuleFactoryBase()
231 android.InitAndroidArchModule(m, android.HostSupported, android.MultilibBoth)
232 return m
233}
234
235func customModuleFactoryHostAndDeviceDefault() android.Module {
236 m := customModuleFactoryBase()
237 android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibBoth)
238 return m
239}
240
241func customModuleFactoryNeitherHostNorDeviceSupported() android.Module {
242 m := customModuleFactoryBase()
243 android.InitAndroidArchModule(m, android.NeitherHostNorDeviceSupported, android.MultilibBoth)
244 return m
245}
246
Liz Kammer2dd9ca42020-11-25 16:06:39 -0800247type testProps struct {
248 Test_prop struct {
249 Test_string_prop string
250 }
251}
252
253type customTestModule struct {
254 android.ModuleBase
255
256 props customProps
257 test_props testProps
258}
259
260func (m *customTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
261 // nothing for now.
262}
263
264func customTestModuleFactoryBase() android.Module {
265 m := &customTestModule{}
266 m.AddProperties(&m.props)
267 m.AddProperties(&m.test_props)
268 return m
269}
270
271func customTestModuleFactory() android.Module {
272 m := customTestModuleFactoryBase()
273 android.InitAndroidModule(m)
274 return m
275}
276
277type customDefaultsModule struct {
278 android.ModuleBase
279 android.DefaultsModuleBase
280}
281
282func customDefaultsModuleFactoryBase() android.DefaultsModule {
283 module := &customDefaultsModule{}
284 module.AddProperties(&customProps{})
285 return module
286}
287
288func customDefaultsModuleFactoryBasic() android.Module {
289 return customDefaultsModuleFactoryBase()
290}
291
292func customDefaultsModuleFactory() android.Module {
293 m := customDefaultsModuleFactoryBase()
294 android.InitDefaultsModule(m)
295 return m
296}
Jingwen Chen73850672020-12-14 08:25:34 -0500297
Liz Kammer32a03392021-09-14 11:17:21 -0400298type EmbeddedAttr struct {
Liz Kammer46fb7ab2021-12-01 10:09:34 -0500299 Embedded_attr *string
Liz Kammer32a03392021-09-14 11:17:21 -0400300}
301
302type OtherEmbeddedAttr struct {
Liz Kammer46fb7ab2021-12-01 10:09:34 -0500303 Other_embedded_attr *string
Liz Kammer32a03392021-09-14 11:17:21 -0400304}
305
Jingwen Chen73850672020-12-14 08:25:34 -0500306type customBazelModuleAttributes struct {
Liz Kammer32a03392021-09-14 11:17:21 -0400307 EmbeddedAttr
308 *OtherEmbeddedAttr
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux3a019a62022-06-23 16:02:44 +0000309 String_literal_prop bazel.StringAttribute
310 String_ptr_prop *string
311 String_list_prop []string
312 Arch_paths bazel.LabelListAttribute
Jingwen Chen73850672020-12-14 08:25:34 -0500313}
314
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400315func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400316 if p := m.props.One_to_many_prop; p != nil && *p {
317 customBp2buildOneToMany(ctx, m)
318 return
319 }
Liz Kammer4562a3b2021-04-21 18:15:34 -0400320
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux3a019a62022-06-23 16:02:44 +0000321 paths := bazel.LabelListAttribute{}
322 strAttr := bazel.StringAttribute{}
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400323 for axis, configToProps := range m.GetArchVariantProperties(ctx, &customProps{}) {
324 for config, props := range configToProps {
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux3a019a62022-06-23 16:02:44 +0000325 if custProps, ok := props.(*customProps); ok {
326 if custProps.Arch_paths != nil {
327 paths.SetSelectValue(axis, config, android.BazelLabelForModuleSrcExcludes(ctx, custProps.Arch_paths, custProps.Arch_paths_exclude))
328 }
329 if custProps.String_literal_prop != nil {
330 strAttr.SetSelectValue(axis, config, custProps.String_literal_prop)
331 }
Liz Kammer4562a3b2021-04-21 18:15:34 -0400332 }
333 }
Jingwen Chen73850672020-12-14 08:25:34 -0500334 }
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400335
336 paths.ResolveExcludes()
337
338 attrs := &customBazelModuleAttributes{
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux3a019a62022-06-23 16:02:44 +0000339 String_literal_prop: strAttr,
340 String_ptr_prop: m.props.String_ptr_prop,
341 String_list_prop: m.props.String_list_prop,
342 Arch_paths: paths,
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400343 }
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux3a019a62022-06-23 16:02:44 +0000344
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400345 attrs.Embedded_attr = m.props.Embedded_prop
346 if m.props.OtherEmbeddedProps != nil {
347 attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
348 }
349
350 props := bazel.BazelTargetModuleProperties{
351 Rule_class: "custom",
352 }
353
354 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
Jingwen Chen73850672020-12-14 08:25:34 -0500355}
Jingwen Chen40067de2021-01-26 21:58:43 -0500356
357// A bp2build mutator that uses load statements and creates a 1:M mapping from
358// module to target.
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400359func customBp2buildOneToMany(ctx android.TopDownMutatorContext, m *customModule) {
Jingwen Chen77e8b7b2021-02-05 03:03:24 -0500360
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400361 baseName := m.Name()
362 attrs := &customBazelModuleAttributes{}
Jingwen Chen1fd14692021-02-05 03:01:50 -0500363
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400364 myLibraryProps := bazel.BazelTargetModuleProperties{
365 Rule_class: "my_library",
366 Bzl_load_location: "//build/bazel/rules:rules.bzl",
Jingwen Chen40067de2021-01-26 21:58:43 -0500367 }
Liz Kammerbe46fcc2021-11-01 15:32:43 -0400368 ctx.CreateBazelTargetModule(myLibraryProps, android.CommonAttributes{Name: baseName}, attrs)
369
370 protoLibraryProps := bazel.BazelTargetModuleProperties{
371 Rule_class: "proto_library",
372 Bzl_load_location: "//build/bazel/rules:proto.bzl",
373 }
374 ctx.CreateBazelTargetModule(protoLibraryProps, android.CommonAttributes{Name: baseName + "_proto_library_deps"}, attrs)
375
376 myProtoLibraryProps := bazel.BazelTargetModuleProperties{
377 Rule_class: "my_proto_library",
378 Bzl_load_location: "//build/bazel/rules:proto.bzl",
379 }
380 ctx.CreateBazelTargetModule(myProtoLibraryProps, android.CommonAttributes{Name: baseName + "_my_proto_library_deps"}, attrs)
Jingwen Chen40067de2021-01-26 21:58:43 -0500381}
Jingwen Chenba369ad2021-02-22 10:19:34 -0500382
383// Helper method for tests to easily access the targets in a dir.
Liz Kammer6eff3232021-08-26 08:37:59 -0400384func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) {
Rupert Shuttleworth2a4fc3e2021-04-21 07:10:09 -0400385 // TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
Liz Kammer6eff3232021-08-26 08:37:59 -0400386 res, err := GenerateBazelTargets(codegenCtx, false)
Alix94e26032022-08-16 20:37:33 +0000387 if err != nil {
388 return BazelTargets{}, err
389 }
Liz Kammer6eff3232021-08-26 08:37:59 -0400390 return res.buildFileToTargets[dir], err
Jingwen Chenba369ad2021-02-22 10:19:34 -0500391}
Liz Kammer32b77cf2021-08-04 15:17:02 -0400392
393func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
Liz Kammerdfeb1202022-05-13 17:20:20 -0400394 ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
Liz Kammer32b77cf2021-08-04 15:17:02 -0400395 ctx.RegisterForBazelConversion()
396}
Liz Kammer7a210ac2021-09-22 15:52:58 -0400397
398func simpleModuleDoNotConvertBp2build(typ, name string) string {
399 return fmt.Sprintf(`
400%s {
401 name: "%s",
402 bazel_module: { bp2build_available: false },
403}`, typ, name)
404}
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500405
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000406type AttrNameToString map[string]string
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500407
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000408func (a AttrNameToString) clone() AttrNameToString {
409 newAttrs := make(AttrNameToString, len(a))
Liz Kammerdfeb1202022-05-13 17:20:20 -0400410 for k, v := range a {
411 newAttrs[k] = v
412 }
413 return newAttrs
414}
415
416// makeBazelTargetNoRestrictions returns bazel target build file definition that can be host or
417// device specific, or independent of host/device.
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000418func makeBazelTargetHostOrDevice(typ, name string, attrs AttrNameToString, hod android.HostOrDeviceSupported) string {
Liz Kammerdfeb1202022-05-13 17:20:20 -0400419 if _, ok := attrs["target_compatible_with"]; !ok {
420 switch hod {
421 case android.HostSupported:
422 attrs["target_compatible_with"] = `select({
423 "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
424 "//conditions:default": [],
425 })`
426 case android.DeviceSupported:
427 attrs["target_compatible_with"] = `["//build/bazel/platforms/os:android"]`
428 }
429 }
430
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500431 attrStrings := make([]string, 0, len(attrs)+1)
Sasha Smundakfb589492022-08-04 11:13:27 -0700432 if name != "" {
433 attrStrings = append(attrStrings, fmt.Sprintf(` name = "%s",`, name))
434 }
Liz Kammer78cfdaa2021-11-08 12:56:31 -0500435 for _, k := range android.SortedStringKeys(attrs) {
436 attrStrings = append(attrStrings, fmt.Sprintf(" %s = %s,", k, attrs[k]))
437 }
438 return fmt.Sprintf(`%s(
439%s
440)`, typ, strings.Join(attrStrings, "\n"))
441}
Liz Kammerdfeb1202022-05-13 17:20:20 -0400442
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000443// MakeBazelTargetNoRestrictions returns bazel target build file definition that does not add a
Liz Kammerdfeb1202022-05-13 17:20:20 -0400444// target_compatible_with. This is useful for module types like filegroup and genrule that arch not
445// arch variant
Sam Delmerico3177a6e2022-06-21 19:28:33 +0000446func MakeBazelTargetNoRestrictions(typ, name string, attrs AttrNameToString) string {
Liz Kammerdfeb1202022-05-13 17:20:20 -0400447 return makeBazelTargetHostOrDevice(typ, name, attrs, android.HostAndDeviceDefault)
448}
449
450// makeBazelTargetNoRestrictions returns bazel target build file definition that is device specific
451// as this is the most common default in Soong.
Alixe06d75b2022-08-31 18:28:19 +0000452func MakeBazelTarget(typ, name string, attrs AttrNameToString) string {
Liz Kammerdfeb1202022-05-13 17:20:20 -0400453 return makeBazelTargetHostOrDevice(typ, name, attrs, android.DeviceSupported)
454}
Sasha Smundak9d2f1742022-08-04 13:28:38 -0700455
456type ExpectedRuleTarget struct {
457 Rule string
458 Name string
459 Attrs AttrNameToString
460 Hod android.HostOrDeviceSupported
461}
462
463func (ebr ExpectedRuleTarget) String() string {
464 return makeBazelTargetHostOrDevice(ebr.Rule, ebr.Name, ebr.Attrs, ebr.Hod)
465}