blob: ea8b9f158c66fc79b6acb07fd2e61c25390b2a31 [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`,
60 expectedBazelTargets: []string{`cc_object(
61 name = "foo",
62 copts = [
63 "-fno-addrsig",
64 "-Wno-gcc-compat",
65 "-Wall",
66 "-Werror",
Jingwen Chened9c17d2021-04-13 07:14:55 +000067 "-Iinclude",
Chris Parsons484e50a2021-05-13 15:13:04 -040068 "-I$(BINDIR)/include",
Jingwen Chened9c17d2021-04-13 07:14:55 +000069 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -040070 "-I$(BINDIR)/.",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050071 ],
Jingwen Chen882bcc12021-04-27 05:54:20 +000072 srcs = ["a/b/c.c"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050073)`,
74 },
75 },
76 {
77 description: "simple cc_object with defaults",
78 moduleTypeUnderTest: "cc_object",
79 moduleTypeUnderTestFactory: cc.ObjectFactory,
80 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
81 blueprint: `cc_object {
82 name: "foo",
83 local_include_dirs: ["include"],
84 srcs: [
85 "a/b/*.h",
86 "a/b/c.c"
87 ],
88
89 defaults: ["foo_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050090}
91
92cc_defaults {
93 name: "foo_defaults",
94 defaults: ["foo_bar_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050095}
96
97cc_defaults {
98 name: "foo_bar_defaults",
99 cflags: [
100 "-Wno-gcc-compat",
101 "-Wall",
102 "-Werror",
103 ],
104}
105`,
106 expectedBazelTargets: []string{`cc_object(
107 name = "foo",
108 copts = [
109 "-Wno-gcc-compat",
110 "-Wall",
111 "-Werror",
112 "-fno-addrsig",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000113 "-Iinclude",
Chris Parsons484e50a2021-05-13 15:13:04 -0400114 "-I$(BINDIR)/include",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000115 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -0400116 "-I$(BINDIR)/.",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500117 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000118 srcs = ["a/b/c.c"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500119)`,
120 },
121 },
Jingwen Chendb120242021-02-23 00:46:47 -0500122 {
123 description: "cc_object with cc_object deps in objs props",
124 moduleTypeUnderTest: "cc_object",
125 moduleTypeUnderTestFactory: cc.ObjectFactory,
126 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
127 filesystem: map[string]string{
128 "a/b/c.c": "",
129 "x/y/z.c": "",
130 },
131 blueprint: `cc_object {
132 name: "foo",
133 srcs: ["a/b/c.c"],
134 objs: ["bar"],
Jingwen Chendb120242021-02-23 00:46:47 -0500135}
136
137cc_object {
138 name: "bar",
139 srcs: ["x/y/z.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500140}
141`,
142 expectedBazelTargets: []string{`cc_object(
143 name = "bar",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000144 copts = [
145 "-fno-addrsig",
146 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -0400147 "-I$(BINDIR)/.",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000148 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000149 srcs = ["x/y/z.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500150)`, `cc_object(
151 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000152 copts = [
153 "-fno-addrsig",
154 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -0400155 "-I$(BINDIR)/.",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000156 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000157 deps = [":bar"],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000158 srcs = ["a/b/c.c"],
Liz Kammera4aa4302021-03-18 16:56:36 -0400159)`,
160 },
161 },
162 {
163 description: "cc_object with include_build_dir: false",
164 moduleTypeUnderTest: "cc_object",
165 moduleTypeUnderTestFactory: cc.ObjectFactory,
166 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
167 filesystem: map[string]string{
168 "a/b/c.c": "",
169 "x/y/z.c": "",
170 },
171 blueprint: `cc_object {
172 name: "foo",
173 srcs: ["a/b/c.c"],
174 include_build_directory: false,
Liz Kammera4aa4302021-03-18 16:56:36 -0400175}
176`,
177 expectedBazelTargets: []string{`cc_object(
178 name = "foo",
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000179 copts = ["-fno-addrsig"],
180 srcs = ["a/b/c.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500181)`,
182 },
183 },
Liz Kammera060c452021-03-24 10:14:47 -0400184 {
185 description: "cc_object with product variable",
186 moduleTypeUnderTest: "cc_object",
187 moduleTypeUnderTestFactory: cc.ObjectFactory,
188 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
189 blueprint: `cc_object {
190 name: "foo",
191 include_build_directory: false,
192 product_variables: {
193 platform_sdk_version: {
194 asflags: ["-DPLATFORM_SDK_VERSION=%d"],
195 },
196 },
Liz Kammera060c452021-03-24 10:14:47 -0400197}
198`,
199 expectedBazelTargets: []string{`cc_object(
200 name = "foo",
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000201 asflags = ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
202 copts = ["-fno-addrsig"],
Liz Kammera060c452021-03-24 10:14:47 -0400203)`,
204 },
205 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500206 }
207
208 dir := "."
209 for _, testCase := range testCases {
210 filesystem := make(map[string][]byte)
211 toParse := []string{
212 "Android.bp",
213 }
214 for f, content := range testCase.filesystem {
215 if strings.HasSuffix(f, "Android.bp") {
216 toParse = append(toParse, f)
217 }
218 filesystem[f] = []byte(content)
219 }
220 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
221 ctx := android.NewTestContext(config)
222 // Always register cc_defaults module factory
223 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
224
225 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
226 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000227 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500228 ctx.RegisterForBazelConversion()
229
230 _, errs := ctx.ParseFileList(dir, toParse)
231 if Errored(t, testCase.description, errs) {
232 continue
233 }
234 _, errs = ctx.ResolveDependencies(config)
235 if Errored(t, testCase.description, errs) {
236 continue
237 }
238
Jingwen Chen164e0862021-02-19 00:48:40 -0500239 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500240 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500241 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
242 fmt.Println(bazelTargets)
243 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
244 } else {
245 for i, target := range bazelTargets {
246 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
247 t.Errorf(
248 "%s: Expected generated Bazel target to be '%s', got '%s'",
249 testCase.description,
250 w,
251 g,
252 )
253 }
254 }
255 }
256 }
257}
Jingwen Chen5d864492021-02-24 07:20:12 -0500258
259func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
260 testCases := []struct {
261 description string
262 moduleTypeUnderTest string
263 moduleTypeUnderTestFactory android.ModuleFactory
264 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
265 blueprint string
266 expectedBazelTargets []string
267 filesystem map[string]string
268 }{
269 {
270 description: "cc_object setting cflags for one arch",
271 moduleTypeUnderTest: "cc_object",
272 moduleTypeUnderTestFactory: cc.ObjectFactory,
273 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
274 blueprint: `cc_object {
275 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400276 srcs: ["a.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500277 arch: {
278 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400279 cflags: ["-fPIC"], // string list
280 },
281 arm: {
282 srcs: ["arch/arm/file.S"], // label list
Jingwen Chen5d864492021-02-24 07:20:12 -0500283 },
284 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500285}
286`,
287 expectedBazelTargets: []string{
288 `cc_object(
289 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000290 copts = [
291 "-fno-addrsig",
292 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -0400293 "-I$(BINDIR)/.",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000294 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000295 "//build/bazel/platforms/arch:x86": ["-fPIC"],
Jingwen Chen07027912021-03-15 06:02:43 -0400296 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500297 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000298 srcs = ["a.cpp"] + select({
299 "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"],
Jingwen Chen07027912021-03-15 06:02:43 -0400300 "//conditions:default": [],
301 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500302)`,
303 },
304 },
305 {
306 description: "cc_object setting cflags for 4 architectures",
307 moduleTypeUnderTest: "cc_object",
308 moduleTypeUnderTestFactory: cc.ObjectFactory,
309 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
310 blueprint: `cc_object {
311 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400312 srcs: ["base.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500313 arch: {
314 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400315 srcs: ["x86.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500316 cflags: ["-fPIC"],
317 },
318 x86_64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400319 srcs: ["x86_64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500320 cflags: ["-fPIC"],
321 },
322 arm: {
Jingwen Chen07027912021-03-15 06:02:43 -0400323 srcs: ["arm.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500324 cflags: ["-Wall"],
325 },
326 arm64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400327 srcs: ["arm64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500328 cflags: ["-Wall"],
329 },
330 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500331}
332`,
333 expectedBazelTargets: []string{
334 `cc_object(
335 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000336 copts = [
337 "-fno-addrsig",
338 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -0400339 "-I$(BINDIR)/.",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000340 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000341 "//build/bazel/platforms/arch:arm": ["-Wall"],
342 "//build/bazel/platforms/arch:arm64": ["-Wall"],
343 "//build/bazel/platforms/arch:x86": ["-fPIC"],
344 "//build/bazel/platforms/arch:x86_64": ["-fPIC"],
Jingwen Chen07027912021-03-15 06:02:43 -0400345 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500346 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000347 srcs = ["base.cpp"] + select({
348 "//build/bazel/platforms/arch:arm": ["arm.cpp"],
349 "//build/bazel/platforms/arch:arm64": ["arm64.cpp"],
350 "//build/bazel/platforms/arch:x86": ["x86.cpp"],
351 "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
Jingwen Chen07027912021-03-15 06:02:43 -0400352 "//conditions:default": [],
353 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500354)`,
355 },
356 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000357 {
358 description: "cc_object setting cflags for multiple OSes",
359 moduleTypeUnderTest: "cc_object",
360 moduleTypeUnderTestFactory: cc.ObjectFactory,
361 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
362 blueprint: `cc_object {
363 name: "foo",
364 srcs: ["base.cpp"],
365 target: {
366 android: {
367 cflags: ["-fPIC"],
368 },
369 windows: {
370 cflags: ["-fPIC"],
371 },
372 darwin: {
373 cflags: ["-Wall"],
374 },
375 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000376}
377`,
378 expectedBazelTargets: []string{
379 `cc_object(
380 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000381 copts = [
382 "-fno-addrsig",
383 "-I.",
Chris Parsons484e50a2021-05-13 15:13:04 -0400384 "-I$(BINDIR)/.",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000385 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000386 "//build/bazel/platforms/os:android": ["-fPIC"],
387 "//build/bazel/platforms/os:darwin": ["-Wall"],
388 "//build/bazel/platforms/os:windows": ["-fPIC"],
Jingwen Chenc1c26502021-04-05 10:35:13 +0000389 "//conditions:default": [],
390 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000391 srcs = ["base.cpp"],
Jingwen Chenc1c26502021-04-05 10:35:13 +0000392)`,
393 },
394 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500395 }
396
397 dir := "."
398 for _, testCase := range testCases {
399 filesystem := make(map[string][]byte)
400 toParse := []string{
401 "Android.bp",
402 }
403 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
404 ctx := android.NewTestContext(config)
405 // Always register cc_defaults module factory
406 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
407
408 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
409 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000410 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Jingwen Chen5d864492021-02-24 07:20:12 -0500411 ctx.RegisterForBazelConversion()
412
413 _, errs := ctx.ParseFileList(dir, toParse)
414 if Errored(t, testCase.description, errs) {
415 continue
416 }
417 _, errs = ctx.ResolveDependencies(config)
418 if Errored(t, testCase.description, errs) {
419 continue
420 }
421
422 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
423 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
424 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
425 fmt.Println(bazelTargets)
426 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
427 } else {
428 for i, target := range bazelTargets {
429 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
430 t.Errorf(
431 "%s: Expected generated Bazel target to be '%s', got '%s'",
432 testCase.description,
433 w,
434 g,
435 )
436 }
437 }
438 }
439 }
440}