blob: d00a1cb9cb9de91aeb33e0a55e6f2f9b23c177b7 [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",
68 "-I.",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050069 ],
Jingwen Chened9c17d2021-04-13 07:14:55 +000070 srcs = [
71 "a/b/c.c",
Jingwen Chen63930982021-03-24 10:04:33 -040072 "a/b/bar.h",
73 "a/b/foo.h",
74 ],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050075)`,
76 },
77 },
78 {
79 description: "simple cc_object with defaults",
80 moduleTypeUnderTest: "cc_object",
81 moduleTypeUnderTestFactory: cc.ObjectFactory,
82 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
83 blueprint: `cc_object {
84 name: "foo",
85 local_include_dirs: ["include"],
86 srcs: [
87 "a/b/*.h",
88 "a/b/c.c"
89 ],
90
91 defaults: ["foo_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050092}
93
94cc_defaults {
95 name: "foo_defaults",
96 defaults: ["foo_bar_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050097}
98
99cc_defaults {
100 name: "foo_bar_defaults",
101 cflags: [
102 "-Wno-gcc-compat",
103 "-Wall",
104 "-Werror",
105 ],
106}
107`,
108 expectedBazelTargets: []string{`cc_object(
109 name = "foo",
110 copts = [
111 "-Wno-gcc-compat",
112 "-Wall",
113 "-Werror",
114 "-fno-addrsig",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000115 "-Iinclude",
116 "-I.",
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.",
147 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000148 srcs = ["x/y/z.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500149)`, `cc_object(
150 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000151 copts = [
152 "-fno-addrsig",
153 "-I.",
154 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000155 deps = [":bar"],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000156 srcs = ["a/b/c.c"],
Liz Kammera4aa4302021-03-18 16:56:36 -0400157)`,
158 },
159 },
160 {
161 description: "cc_object with include_build_dir: false",
162 moduleTypeUnderTest: "cc_object",
163 moduleTypeUnderTestFactory: cc.ObjectFactory,
164 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
165 filesystem: map[string]string{
166 "a/b/c.c": "",
167 "x/y/z.c": "",
168 },
169 blueprint: `cc_object {
170 name: "foo",
171 srcs: ["a/b/c.c"],
172 include_build_directory: false,
Liz Kammera4aa4302021-03-18 16:56:36 -0400173}
174`,
175 expectedBazelTargets: []string{`cc_object(
176 name = "foo",
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000177 copts = ["-fno-addrsig"],
178 srcs = ["a/b/c.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500179)`,
180 },
181 },
Liz Kammera060c452021-03-24 10:14:47 -0400182 {
183 description: "cc_object with product variable",
184 moduleTypeUnderTest: "cc_object",
185 moduleTypeUnderTestFactory: cc.ObjectFactory,
186 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
187 blueprint: `cc_object {
188 name: "foo",
189 include_build_directory: false,
190 product_variables: {
191 platform_sdk_version: {
192 asflags: ["-DPLATFORM_SDK_VERSION=%d"],
193 },
194 },
Liz Kammera060c452021-03-24 10:14:47 -0400195}
196`,
197 expectedBazelTargets: []string{`cc_object(
198 name = "foo",
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000199 asflags = ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
200 copts = ["-fno-addrsig"],
Liz Kammera060c452021-03-24 10:14:47 -0400201)`,
202 },
203 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500204 }
205
206 dir := "."
207 for _, testCase := range testCases {
208 filesystem := make(map[string][]byte)
209 toParse := []string{
210 "Android.bp",
211 }
212 for f, content := range testCase.filesystem {
213 if strings.HasSuffix(f, "Android.bp") {
214 toParse = append(toParse, f)
215 }
216 filesystem[f] = []byte(content)
217 }
218 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
219 ctx := android.NewTestContext(config)
220 // Always register cc_defaults module factory
221 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
222
223 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
224 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000225 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500226 ctx.RegisterForBazelConversion()
227
228 _, errs := ctx.ParseFileList(dir, toParse)
229 if Errored(t, testCase.description, errs) {
230 continue
231 }
232 _, errs = ctx.ResolveDependencies(config)
233 if Errored(t, testCase.description, errs) {
234 continue
235 }
236
Jingwen Chen164e0862021-02-19 00:48:40 -0500237 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500238 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500239 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
240 fmt.Println(bazelTargets)
241 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
242 } else {
243 for i, target := range bazelTargets {
244 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
245 t.Errorf(
246 "%s: Expected generated Bazel target to be '%s', got '%s'",
247 testCase.description,
248 w,
249 g,
250 )
251 }
252 }
253 }
254 }
255}
Jingwen Chen5d864492021-02-24 07:20:12 -0500256
257func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
258 testCases := []struct {
259 description string
260 moduleTypeUnderTest string
261 moduleTypeUnderTestFactory android.ModuleFactory
262 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
263 blueprint string
264 expectedBazelTargets []string
265 filesystem map[string]string
266 }{
267 {
268 description: "cc_object setting cflags for one arch",
269 moduleTypeUnderTest: "cc_object",
270 moduleTypeUnderTestFactory: cc.ObjectFactory,
271 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
272 blueprint: `cc_object {
273 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400274 srcs: ["a.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500275 arch: {
276 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400277 cflags: ["-fPIC"], // string list
278 },
279 arm: {
280 srcs: ["arch/arm/file.S"], // label list
Jingwen Chen5d864492021-02-24 07:20:12 -0500281 },
282 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500283}
284`,
285 expectedBazelTargets: []string{
286 `cc_object(
287 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000288 copts = [
289 "-fno-addrsig",
290 "-I.",
291 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000292 "//build/bazel/platforms/arch:x86": ["-fPIC"],
Jingwen Chen07027912021-03-15 06:02:43 -0400293 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500294 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000295 srcs = ["a.cpp"] + select({
296 "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"],
Jingwen Chen07027912021-03-15 06:02:43 -0400297 "//conditions:default": [],
298 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500299)`,
300 },
301 },
302 {
303 description: "cc_object setting cflags for 4 architectures",
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: ["base.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500310 arch: {
311 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400312 srcs: ["x86.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500313 cflags: ["-fPIC"],
314 },
315 x86_64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400316 srcs: ["x86_64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500317 cflags: ["-fPIC"],
318 },
319 arm: {
Jingwen Chen07027912021-03-15 06:02:43 -0400320 srcs: ["arm.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500321 cflags: ["-Wall"],
322 },
323 arm64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400324 srcs: ["arm64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500325 cflags: ["-Wall"],
326 },
327 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500328}
329`,
330 expectedBazelTargets: []string{
331 `cc_object(
332 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000333 copts = [
334 "-fno-addrsig",
335 "-I.",
336 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000337 "//build/bazel/platforms/arch:arm": ["-Wall"],
338 "//build/bazel/platforms/arch:arm64": ["-Wall"],
339 "//build/bazel/platforms/arch:x86": ["-fPIC"],
340 "//build/bazel/platforms/arch:x86_64": ["-fPIC"],
Jingwen Chen07027912021-03-15 06:02:43 -0400341 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500342 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000343 srcs = ["base.cpp"] + select({
344 "//build/bazel/platforms/arch:arm": ["arm.cpp"],
345 "//build/bazel/platforms/arch:arm64": ["arm64.cpp"],
346 "//build/bazel/platforms/arch:x86": ["x86.cpp"],
347 "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
Jingwen Chen07027912021-03-15 06:02:43 -0400348 "//conditions:default": [],
349 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500350)`,
351 },
352 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000353 {
354 description: "cc_object setting cflags for multiple OSes",
355 moduleTypeUnderTest: "cc_object",
356 moduleTypeUnderTestFactory: cc.ObjectFactory,
357 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
358 blueprint: `cc_object {
359 name: "foo",
360 srcs: ["base.cpp"],
361 target: {
362 android: {
363 cflags: ["-fPIC"],
364 },
365 windows: {
366 cflags: ["-fPIC"],
367 },
368 darwin: {
369 cflags: ["-Wall"],
370 },
371 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000372}
373`,
374 expectedBazelTargets: []string{
375 `cc_object(
376 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000377 copts = [
378 "-fno-addrsig",
379 "-I.",
380 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000381 "//build/bazel/platforms/os:android": ["-fPIC"],
382 "//build/bazel/platforms/os:darwin": ["-Wall"],
383 "//build/bazel/platforms/os:windows": ["-fPIC"],
Jingwen Chenc1c26502021-04-05 10:35:13 +0000384 "//conditions:default": [],
385 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000386 srcs = ["base.cpp"],
Jingwen Chenc1c26502021-04-05 10:35:13 +0000387)`,
388 },
389 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500390 }
391
392 dir := "."
393 for _, testCase := range testCases {
394 filesystem := make(map[string][]byte)
395 toParse := []string{
396 "Android.bp",
397 }
398 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
399 ctx := android.NewTestContext(config)
400 // Always register cc_defaults module factory
401 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
402
403 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
404 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000405 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Jingwen Chen5d864492021-02-24 07:20:12 -0500406 ctx.RegisterForBazelConversion()
407
408 _, errs := ctx.ParseFileList(dir, toParse)
409 if Errored(t, testCase.description, errs) {
410 continue
411 }
412 _, errs = ctx.ResolveDependencies(config)
413 if Errored(t, testCase.description, errs) {
414 continue
415 }
416
417 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
418 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
419 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
420 fmt.Println(bazelTargets)
421 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
422 } else {
423 for i, target := range bazelTargets {
424 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
425 t.Errorf(
426 "%s: Expected generated Bazel target to be '%s', got '%s'",
427 testCase.description,
428 w,
429 g,
430 )
431 }
432 }
433 }
434 }
435}