blob: 9461739276e77ed7b8ae29d47fb249fde9f9e0a0 [file] [log] [blame]
Jingwen Chen8c1b97e2021-02-18 03:21:34 -05001// 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
15package bp2build
16
17import (
18 "android/soong/android"
19 "android/soong/cc"
20 "fmt"
21 "strings"
22 "testing"
23)
24
25func TestCcObjectBp2Build(t *testing.T) {
26 testCases := []struct {
27 description string
28 moduleTypeUnderTest string
29 moduleTypeUnderTestFactory android.ModuleFactory
30 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
31 blueprint string
32 expectedBazelTargets []string
33 filesystem map[string]string
34 }{
35 {
36 description: "simple cc_object generates cc_object with include header dep",
37 moduleTypeUnderTest: "cc_object",
38 moduleTypeUnderTestFactory: cc.ObjectFactory,
39 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
40 filesystem: map[string]string{
Jingwen Chendb120242021-02-23 00:46:47 -050041 "a/b/foo.h": "",
42 "a/b/bar.h": "",
43 "a/b/exclude.c": "",
44 "a/b/c.c": "",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050045 },
46 blueprint: `cc_object {
47 name: "foo",
48 local_include_dirs: ["include"],
49 cflags: [
50 "-Wno-gcc-compat",
51 "-Wall",
52 "-Werror",
53 ],
54 srcs: [
55 "a/b/*.h",
Jingwen Chendb120242021-02-23 00:46:47 -050056 "a/b/*.c"
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050057 ],
Jingwen Chendb120242021-02-23 00:46:47 -050058 exclude_srcs: ["a/b/exclude.c"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050059
60 bazel_module: { bp2build_available: true },
61}
62`,
63 expectedBazelTargets: []string{`cc_object(
64 name = "foo",
65 copts = [
66 "-fno-addrsig",
67 "-Wno-gcc-compat",
68 "-Wall",
69 "-Werror",
70 ],
71 local_include_dirs = [
72 "include",
Liz Kammera4aa4302021-03-18 16:56:36 -040073 ".",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050074 ],
75 srcs = [
76 "a/b/bar.h",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050077 "a/b/c.c",
Jingwen Chen07027912021-03-15 06:02:43 -040078 "a/b/foo.h",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050079 ],
80)`,
81 },
82 },
83 {
84 description: "simple cc_object with defaults",
85 moduleTypeUnderTest: "cc_object",
86 moduleTypeUnderTestFactory: cc.ObjectFactory,
87 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
88 blueprint: `cc_object {
89 name: "foo",
90 local_include_dirs: ["include"],
91 srcs: [
92 "a/b/*.h",
93 "a/b/c.c"
94 ],
95
96 defaults: ["foo_defaults"],
97 bazel_module: { bp2build_available: true },
98}
99
100cc_defaults {
101 name: "foo_defaults",
102 defaults: ["foo_bar_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500103}
104
105cc_defaults {
106 name: "foo_bar_defaults",
107 cflags: [
108 "-Wno-gcc-compat",
109 "-Wall",
110 "-Werror",
111 ],
112}
113`,
114 expectedBazelTargets: []string{`cc_object(
115 name = "foo",
116 copts = [
117 "-Wno-gcc-compat",
118 "-Wall",
119 "-Werror",
120 "-fno-addrsig",
121 ],
122 local_include_dirs = [
123 "include",
Liz Kammera4aa4302021-03-18 16:56:36 -0400124 ".",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500125 ],
126 srcs = [
127 "a/b/c.c",
128 ],
129)`,
130 },
131 },
Jingwen Chendb120242021-02-23 00:46:47 -0500132 {
133 description: "cc_object with cc_object deps in objs props",
134 moduleTypeUnderTest: "cc_object",
135 moduleTypeUnderTestFactory: cc.ObjectFactory,
136 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
137 filesystem: map[string]string{
138 "a/b/c.c": "",
139 "x/y/z.c": "",
140 },
141 blueprint: `cc_object {
142 name: "foo",
143 srcs: ["a/b/c.c"],
144 objs: ["bar"],
145
146 bazel_module: { bp2build_available: true },
147}
148
149cc_object {
150 name: "bar",
151 srcs: ["x/y/z.c"],
152
153 bazel_module: { bp2build_available: true },
154}
155`,
156 expectedBazelTargets: []string{`cc_object(
157 name = "bar",
158 copts = [
159 "-fno-addrsig",
160 ],
Liz Kammera4aa4302021-03-18 16:56:36 -0400161 local_include_dirs = [
162 ".",
163 ],
Jingwen Chendb120242021-02-23 00:46:47 -0500164 srcs = [
165 "x/y/z.c",
166 ],
167)`, `cc_object(
168 name = "foo",
169 copts = [
170 "-fno-addrsig",
171 ],
172 deps = [
173 ":bar",
174 ],
Liz Kammera4aa4302021-03-18 16:56:36 -0400175 local_include_dirs = [
176 ".",
177 ],
178 srcs = [
179 "a/b/c.c",
180 ],
181)`,
182 },
183 },
184 {
185 description: "cc_object with include_build_dir: false",
186 moduleTypeUnderTest: "cc_object",
187 moduleTypeUnderTestFactory: cc.ObjectFactory,
188 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
189 filesystem: map[string]string{
190 "a/b/c.c": "",
191 "x/y/z.c": "",
192 },
193 blueprint: `cc_object {
194 name: "foo",
195 srcs: ["a/b/c.c"],
196 include_build_directory: false,
197
198 bazel_module: { bp2build_available: true },
199}
200`,
201 expectedBazelTargets: []string{`cc_object(
202 name = "foo",
203 copts = [
204 "-fno-addrsig",
205 ],
Jingwen Chendb120242021-02-23 00:46:47 -0500206 srcs = [
207 "a/b/c.c",
208 ],
209)`,
210 },
211 },
Liz Kammera060c452021-03-24 10:14:47 -0400212 {
213 description: "cc_object with product variable",
214 moduleTypeUnderTest: "cc_object",
215 moduleTypeUnderTestFactory: cc.ObjectFactory,
216 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
217 blueprint: `cc_object {
218 name: "foo",
219 include_build_directory: false,
220 product_variables: {
221 platform_sdk_version: {
222 asflags: ["-DPLATFORM_SDK_VERSION=%d"],
223 },
224 },
225
226 bazel_module: { bp2build_available: true },
227}
228`,
229 expectedBazelTargets: []string{`cc_object(
230 name = "foo",
231 asflags = [
232 "-DPLATFORM_SDK_VERSION={Platform_sdk_version}",
233 ],
234 copts = [
235 "-fno-addrsig",
236 ],
237)`,
238 },
239 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500240 }
241
242 dir := "."
243 for _, testCase := range testCases {
244 filesystem := make(map[string][]byte)
245 toParse := []string{
246 "Android.bp",
247 }
248 for f, content := range testCase.filesystem {
249 if strings.HasSuffix(f, "Android.bp") {
250 toParse = append(toParse, f)
251 }
252 filesystem[f] = []byte(content)
253 }
254 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
255 ctx := android.NewTestContext(config)
256 // Always register cc_defaults module factory
257 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
258
259 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
260 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
261 ctx.RegisterForBazelConversion()
262
263 _, errs := ctx.ParseFileList(dir, toParse)
264 if Errored(t, testCase.description, errs) {
265 continue
266 }
267 _, errs = ctx.ResolveDependencies(config)
268 if Errored(t, testCase.description, errs) {
269 continue
270 }
271
Jingwen Chen164e0862021-02-19 00:48:40 -0500272 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500273 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500274 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
275 fmt.Println(bazelTargets)
276 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
277 } else {
278 for i, target := range bazelTargets {
279 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
280 t.Errorf(
281 "%s: Expected generated Bazel target to be '%s', got '%s'",
282 testCase.description,
283 w,
284 g,
285 )
286 }
287 }
288 }
289 }
290}
Jingwen Chen5d864492021-02-24 07:20:12 -0500291
292func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
293 testCases := []struct {
294 description string
295 moduleTypeUnderTest string
296 moduleTypeUnderTestFactory android.ModuleFactory
297 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
298 blueprint string
299 expectedBazelTargets []string
300 filesystem map[string]string
301 }{
302 {
303 description: "cc_object setting cflags for one arch",
304 moduleTypeUnderTest: "cc_object",
305 moduleTypeUnderTestFactory: cc.ObjectFactory,
306 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
307 blueprint: `cc_object {
308 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400309 srcs: ["a.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500310 arch: {
311 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400312 cflags: ["-fPIC"], // string list
313 },
314 arm: {
315 srcs: ["arch/arm/file.S"], // label list
Jingwen Chen5d864492021-02-24 07:20:12 -0500316 },
317 },
318 bazel_module: { bp2build_available: true },
319}
320`,
321 expectedBazelTargets: []string{
322 `cc_object(
323 name = "foo",
324 copts = [
325 "-fno-addrsig",
326 ] + select({
327 "@bazel_tools//platforms:x86_32": [
328 "-fPIC",
329 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400330 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500331 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400332 local_include_dirs = [
333 ".",
334 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400335 srcs = [
336 "a.cpp",
337 ] + select({
338 "@bazel_tools//platforms:arm": [
339 "arch/arm/file.S",
340 ],
341 "//conditions:default": [],
342 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500343)`,
344 },
345 },
346 {
347 description: "cc_object setting cflags for 4 architectures",
348 moduleTypeUnderTest: "cc_object",
349 moduleTypeUnderTestFactory: cc.ObjectFactory,
350 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
351 blueprint: `cc_object {
352 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400353 srcs: ["base.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500354 arch: {
355 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400356 srcs: ["x86.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500357 cflags: ["-fPIC"],
358 },
359 x86_64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400360 srcs: ["x86_64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500361 cflags: ["-fPIC"],
362 },
363 arm: {
Jingwen Chen07027912021-03-15 06:02:43 -0400364 srcs: ["arm.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500365 cflags: ["-Wall"],
366 },
367 arm64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400368 srcs: ["arm64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500369 cflags: ["-Wall"],
370 },
371 },
372 bazel_module: { bp2build_available: true },
373}
374`,
375 expectedBazelTargets: []string{
376 `cc_object(
377 name = "foo",
378 copts = [
379 "-fno-addrsig",
380 ] + select({
381 "@bazel_tools//platforms:arm": [
382 "-Wall",
383 ],
384 "@bazel_tools//platforms:aarch64": [
385 "-Wall",
386 ],
387 "@bazel_tools//platforms:x86_32": [
388 "-fPIC",
389 ],
390 "@bazel_tools//platforms:x86_64": [
391 "-fPIC",
392 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400393 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500394 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400395 local_include_dirs = [
396 ".",
397 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400398 srcs = [
399 "base.cpp",
400 ] + select({
401 "@bazel_tools//platforms:arm": [
402 "arm.cpp",
403 ],
404 "@bazel_tools//platforms:aarch64": [
405 "arm64.cpp",
406 ],
407 "@bazel_tools//platforms:x86_32": [
408 "x86.cpp",
409 ],
410 "@bazel_tools//platforms:x86_64": [
411 "x86_64.cpp",
412 ],
413 "//conditions:default": [],
414 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500415)`,
416 },
417 },
418 }
419
420 dir := "."
421 for _, testCase := range testCases {
422 filesystem := make(map[string][]byte)
423 toParse := []string{
424 "Android.bp",
425 }
426 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
427 ctx := android.NewTestContext(config)
428 // Always register cc_defaults module factory
429 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
430
431 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
432 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
433 ctx.RegisterForBazelConversion()
434
435 _, errs := ctx.ParseFileList(dir, toParse)
436 if Errored(t, testCase.description, errs) {
437 continue
438 }
439 _, errs = ctx.ResolveDependencies(config)
440 if Errored(t, testCase.description, errs) {
441 continue
442 }
443
444 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
445 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
446 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
447 fmt.Println(bazelTargets)
448 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
449 } else {
450 for i, target := range bazelTargets {
451 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
452 t.Errorf(
453 "%s: Expected generated Bazel target to be '%s', got '%s'",
454 testCase.description,
455 w,
456 g,
457 )
458 }
459 }
460 }
461 }
462}