blob: 840bf42991f36c8abf031a36ee73353b8eee214b [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: [
Jingwen Chendb120242021-02-23 00:46:47 -050055 "a/b/*.c"
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050056 ],
Jingwen Chendb120242021-02-23 00:46:47 -050057 exclude_srcs: ["a/b/exclude.c"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050058
59 bazel_module: { bp2build_available: true },
60}
61`,
62 expectedBazelTargets: []string{`cc_object(
63 name = "foo",
64 copts = [
65 "-fno-addrsig",
66 "-Wno-gcc-compat",
67 "-Wall",
68 "-Werror",
69 ],
Jingwen Chen63930982021-03-24 10:04:33 -040070 hdrs = [
71 "a/b/bar.h",
72 "a/b/foo.h",
73 ],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050074 local_include_dirs = [
75 "include",
Liz Kammera4aa4302021-03-18 16:56:36 -040076 ".",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050077 ],
78 srcs = [
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050079 "a/b/c.c",
80 ],
81)`,
82 },
83 },
84 {
85 description: "simple cc_object with defaults",
86 moduleTypeUnderTest: "cc_object",
87 moduleTypeUnderTestFactory: cc.ObjectFactory,
88 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
89 blueprint: `cc_object {
90 name: "foo",
91 local_include_dirs: ["include"],
92 srcs: [
93 "a/b/*.h",
94 "a/b/c.c"
95 ],
96
97 defaults: ["foo_defaults"],
98 bazel_module: { bp2build_available: true },
99}
100
101cc_defaults {
102 name: "foo_defaults",
103 defaults: ["foo_bar_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500104}
105
106cc_defaults {
107 name: "foo_bar_defaults",
108 cflags: [
109 "-Wno-gcc-compat",
110 "-Wall",
111 "-Werror",
112 ],
113}
114`,
115 expectedBazelTargets: []string{`cc_object(
116 name = "foo",
117 copts = [
118 "-Wno-gcc-compat",
119 "-Wall",
120 "-Werror",
121 "-fno-addrsig",
122 ],
123 local_include_dirs = [
124 "include",
Liz Kammera4aa4302021-03-18 16:56:36 -0400125 ".",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500126 ],
127 srcs = [
128 "a/b/c.c",
129 ],
130)`,
131 },
132 },
Jingwen Chendb120242021-02-23 00:46:47 -0500133 {
134 description: "cc_object with cc_object deps in objs props",
135 moduleTypeUnderTest: "cc_object",
136 moduleTypeUnderTestFactory: cc.ObjectFactory,
137 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
138 filesystem: map[string]string{
139 "a/b/c.c": "",
140 "x/y/z.c": "",
141 },
142 blueprint: `cc_object {
143 name: "foo",
144 srcs: ["a/b/c.c"],
145 objs: ["bar"],
146
147 bazel_module: { bp2build_available: true },
148}
149
150cc_object {
151 name: "bar",
152 srcs: ["x/y/z.c"],
153
154 bazel_module: { bp2build_available: true },
155}
156`,
157 expectedBazelTargets: []string{`cc_object(
158 name = "bar",
159 copts = [
160 "-fno-addrsig",
161 ],
Liz Kammera4aa4302021-03-18 16:56:36 -0400162 local_include_dirs = [
163 ".",
164 ],
Jingwen Chendb120242021-02-23 00:46:47 -0500165 srcs = [
166 "x/y/z.c",
167 ],
168)`, `cc_object(
169 name = "foo",
170 copts = [
171 "-fno-addrsig",
172 ],
173 deps = [
174 ":bar",
175 ],
Liz Kammera4aa4302021-03-18 16:56:36 -0400176 local_include_dirs = [
177 ".",
178 ],
179 srcs = [
180 "a/b/c.c",
181 ],
182)`,
183 },
184 },
185 {
186 description: "cc_object with include_build_dir: false",
187 moduleTypeUnderTest: "cc_object",
188 moduleTypeUnderTestFactory: cc.ObjectFactory,
189 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
190 filesystem: map[string]string{
191 "a/b/c.c": "",
192 "x/y/z.c": "",
193 },
194 blueprint: `cc_object {
195 name: "foo",
196 srcs: ["a/b/c.c"],
197 include_build_directory: false,
198
199 bazel_module: { bp2build_available: true },
200}
201`,
202 expectedBazelTargets: []string{`cc_object(
203 name = "foo",
204 copts = [
205 "-fno-addrsig",
206 ],
Jingwen Chendb120242021-02-23 00:46:47 -0500207 srcs = [
208 "a/b/c.c",
209 ],
210)`,
211 },
212 },
Liz Kammera060c452021-03-24 10:14:47 -0400213 {
214 description: "cc_object with product variable",
215 moduleTypeUnderTest: "cc_object",
216 moduleTypeUnderTestFactory: cc.ObjectFactory,
217 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
218 blueprint: `cc_object {
219 name: "foo",
220 include_build_directory: false,
221 product_variables: {
222 platform_sdk_version: {
223 asflags: ["-DPLATFORM_SDK_VERSION=%d"],
224 },
225 },
226
227 bazel_module: { bp2build_available: true },
228}
229`,
230 expectedBazelTargets: []string{`cc_object(
231 name = "foo",
232 asflags = [
233 "-DPLATFORM_SDK_VERSION={Platform_sdk_version}",
234 ],
235 copts = [
236 "-fno-addrsig",
237 ],
238)`,
239 },
240 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500241 }
242
243 dir := "."
244 for _, testCase := range testCases {
245 filesystem := make(map[string][]byte)
246 toParse := []string{
247 "Android.bp",
248 }
249 for f, content := range testCase.filesystem {
250 if strings.HasSuffix(f, "Android.bp") {
251 toParse = append(toParse, f)
252 }
253 filesystem[f] = []byte(content)
254 }
255 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
256 ctx := android.NewTestContext(config)
257 // Always register cc_defaults module factory
258 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
259
260 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
261 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
262 ctx.RegisterForBazelConversion()
263
264 _, errs := ctx.ParseFileList(dir, toParse)
265 if Errored(t, testCase.description, errs) {
266 continue
267 }
268 _, errs = ctx.ResolveDependencies(config)
269 if Errored(t, testCase.description, errs) {
270 continue
271 }
272
Jingwen Chen164e0862021-02-19 00:48:40 -0500273 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500274 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500275 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
276 fmt.Println(bazelTargets)
277 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
278 } else {
279 for i, target := range bazelTargets {
280 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
281 t.Errorf(
282 "%s: Expected generated Bazel target to be '%s', got '%s'",
283 testCase.description,
284 w,
285 g,
286 )
287 }
288 }
289 }
290 }
291}
Jingwen Chen5d864492021-02-24 07:20:12 -0500292
293func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
294 testCases := []struct {
295 description string
296 moduleTypeUnderTest string
297 moduleTypeUnderTestFactory android.ModuleFactory
298 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
299 blueprint string
300 expectedBazelTargets []string
301 filesystem map[string]string
302 }{
303 {
304 description: "cc_object setting cflags for one arch",
305 moduleTypeUnderTest: "cc_object",
306 moduleTypeUnderTestFactory: cc.ObjectFactory,
307 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
308 blueprint: `cc_object {
309 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400310 srcs: ["a.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500311 arch: {
312 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400313 cflags: ["-fPIC"], // string list
314 },
315 arm: {
316 srcs: ["arch/arm/file.S"], // label list
Jingwen Chen5d864492021-02-24 07:20:12 -0500317 },
318 },
319 bazel_module: { bp2build_available: true },
320}
321`,
322 expectedBazelTargets: []string{
323 `cc_object(
324 name = "foo",
325 copts = [
326 "-fno-addrsig",
327 ] + select({
Jingwen Chen91220d72021-03-24 02:18:33 -0400328 "//build/bazel/platforms/arch:x86": [
Jingwen Chen5d864492021-02-24 07:20:12 -0500329 "-fPIC",
330 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400331 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500332 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400333 local_include_dirs = [
334 ".",
335 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400336 srcs = [
337 "a.cpp",
338 ] + select({
Jingwen Chen91220d72021-03-24 02:18:33 -0400339 "//build/bazel/platforms/arch:arm": [
Jingwen Chen07027912021-03-15 06:02:43 -0400340 "arch/arm/file.S",
341 ],
342 "//conditions:default": [],
343 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500344)`,
345 },
346 },
347 {
348 description: "cc_object setting cflags for 4 architectures",
349 moduleTypeUnderTest: "cc_object",
350 moduleTypeUnderTestFactory: cc.ObjectFactory,
351 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
352 blueprint: `cc_object {
353 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400354 srcs: ["base.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500355 arch: {
356 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400357 srcs: ["x86.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500358 cflags: ["-fPIC"],
359 },
360 x86_64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400361 srcs: ["x86_64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500362 cflags: ["-fPIC"],
363 },
364 arm: {
Jingwen Chen07027912021-03-15 06:02:43 -0400365 srcs: ["arm.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500366 cflags: ["-Wall"],
367 },
368 arm64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400369 srcs: ["arm64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500370 cflags: ["-Wall"],
371 },
372 },
373 bazel_module: { bp2build_available: true },
374}
375`,
376 expectedBazelTargets: []string{
377 `cc_object(
378 name = "foo",
379 copts = [
380 "-fno-addrsig",
381 ] + select({
Jingwen Chen91220d72021-03-24 02:18:33 -0400382 "//build/bazel/platforms/arch:arm": [
Jingwen Chen5d864492021-02-24 07:20:12 -0500383 "-Wall",
384 ],
Jingwen Chen91220d72021-03-24 02:18:33 -0400385 "//build/bazel/platforms/arch:arm64": [
Jingwen Chen5d864492021-02-24 07:20:12 -0500386 "-Wall",
387 ],
Jingwen Chen91220d72021-03-24 02:18:33 -0400388 "//build/bazel/platforms/arch:x86": [
Jingwen Chen5d864492021-02-24 07:20:12 -0500389 "-fPIC",
390 ],
Jingwen Chen91220d72021-03-24 02:18:33 -0400391 "//build/bazel/platforms/arch:x86_64": [
Jingwen Chen5d864492021-02-24 07:20:12 -0500392 "-fPIC",
393 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400394 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500395 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400396 local_include_dirs = [
397 ".",
398 ],
Jingwen Chen07027912021-03-15 06:02:43 -0400399 srcs = [
400 "base.cpp",
401 ] + select({
Jingwen Chen91220d72021-03-24 02:18:33 -0400402 "//build/bazel/platforms/arch:arm": [
Jingwen Chen07027912021-03-15 06:02:43 -0400403 "arm.cpp",
404 ],
Jingwen Chen91220d72021-03-24 02:18:33 -0400405 "//build/bazel/platforms/arch:arm64": [
Jingwen Chen07027912021-03-15 06:02:43 -0400406 "arm64.cpp",
407 ],
Jingwen Chen91220d72021-03-24 02:18:33 -0400408 "//build/bazel/platforms/arch:x86": [
Jingwen Chen07027912021-03-15 06:02:43 -0400409 "x86.cpp",
410 ],
Jingwen Chen91220d72021-03-24 02:18:33 -0400411 "//build/bazel/platforms/arch:x86_64": [
Jingwen Chen07027912021-03-15 06:02:43 -0400412 "x86_64.cpp",
413 ],
414 "//conditions:default": [],
415 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500416)`,
417 },
418 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000419 {
420 description: "cc_object setting cflags for multiple OSes",
421 moduleTypeUnderTest: "cc_object",
422 moduleTypeUnderTestFactory: cc.ObjectFactory,
423 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
424 blueprint: `cc_object {
425 name: "foo",
426 srcs: ["base.cpp"],
427 target: {
428 android: {
429 cflags: ["-fPIC"],
430 },
431 windows: {
432 cflags: ["-fPIC"],
433 },
434 darwin: {
435 cflags: ["-Wall"],
436 },
437 },
438 bazel_module: { bp2build_available: true },
439}
440`,
441 expectedBazelTargets: []string{
442 `cc_object(
443 name = "foo",
444 copts = [
445 "-fno-addrsig",
446 ] + select({
447 "//build/bazel/platforms/os:android": [
448 "-fPIC",
449 ],
450 "//build/bazel/platforms/os:darwin": [
451 "-Wall",
452 ],
453 "//build/bazel/platforms/os:windows": [
454 "-fPIC",
455 ],
456 "//conditions:default": [],
457 }),
458 local_include_dirs = [
459 ".",
460 ],
461 srcs = [
462 "base.cpp",
463 ],
464)`,
465 },
466 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500467 }
468
469 dir := "."
470 for _, testCase := range testCases {
471 filesystem := make(map[string][]byte)
472 toParse := []string{
473 "Android.bp",
474 }
475 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
476 ctx := android.NewTestContext(config)
477 // Always register cc_defaults module factory
478 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
479
480 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
481 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
482 ctx.RegisterForBazelConversion()
483
484 _, errs := ctx.ParseFileList(dir, toParse)
485 if Errored(t, testCase.description, errs) {
486 continue
487 }
488 _, errs = ctx.ResolveDependencies(config)
489 if Errored(t, testCase.description, errs) {
490 continue
491 }
492
493 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
494 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
495 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
496 fmt.Println(bazelTargets)
497 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
498 } else {
499 for i, target := range bazelTargets {
500 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
501 t.Errorf(
502 "%s: Expected generated Bazel target to be '%s', got '%s'",
503 testCase.description,
504 w,
505 g,
506 )
507 }
508 }
509 }
510 }
511}