blob: 9efdb53de3aa07682b6f1c3d70e028c79f969002 [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 Chen882bcc12021-04-27 05:54:20 +000070 srcs = ["a/b/c.c"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050071)`,
72 },
73 },
74 {
75 description: "simple cc_object with defaults",
76 moduleTypeUnderTest: "cc_object",
77 moduleTypeUnderTestFactory: cc.ObjectFactory,
78 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
79 blueprint: `cc_object {
80 name: "foo",
81 local_include_dirs: ["include"],
82 srcs: [
83 "a/b/*.h",
84 "a/b/c.c"
85 ],
86
87 defaults: ["foo_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050088}
89
90cc_defaults {
91 name: "foo_defaults",
92 defaults: ["foo_bar_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -050093}
94
95cc_defaults {
96 name: "foo_bar_defaults",
97 cflags: [
98 "-Wno-gcc-compat",
99 "-Wall",
100 "-Werror",
101 ],
102}
103`,
104 expectedBazelTargets: []string{`cc_object(
105 name = "foo",
106 copts = [
107 "-Wno-gcc-compat",
108 "-Wall",
109 "-Werror",
110 "-fno-addrsig",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000111 "-Iinclude",
112 "-I.",
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500113 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000114 srcs = ["a/b/c.c"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500115)`,
116 },
117 },
Jingwen Chendb120242021-02-23 00:46:47 -0500118 {
119 description: "cc_object with cc_object deps in objs props",
120 moduleTypeUnderTest: "cc_object",
121 moduleTypeUnderTestFactory: cc.ObjectFactory,
122 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
123 filesystem: map[string]string{
124 "a/b/c.c": "",
125 "x/y/z.c": "",
126 },
127 blueprint: `cc_object {
128 name: "foo",
129 srcs: ["a/b/c.c"],
130 objs: ["bar"],
Jingwen Chendb120242021-02-23 00:46:47 -0500131}
132
133cc_object {
134 name: "bar",
135 srcs: ["x/y/z.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500136}
137`,
138 expectedBazelTargets: []string{`cc_object(
139 name = "bar",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000140 copts = [
141 "-fno-addrsig",
142 "-I.",
143 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000144 srcs = ["x/y/z.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500145)`, `cc_object(
146 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000147 copts = [
148 "-fno-addrsig",
149 "-I.",
150 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000151 deps = [":bar"],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000152 srcs = ["a/b/c.c"],
Liz Kammera4aa4302021-03-18 16:56:36 -0400153)`,
154 },
155 },
156 {
157 description: "cc_object with include_build_dir: false",
158 moduleTypeUnderTest: "cc_object",
159 moduleTypeUnderTestFactory: cc.ObjectFactory,
160 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
161 filesystem: map[string]string{
162 "a/b/c.c": "",
163 "x/y/z.c": "",
164 },
165 blueprint: `cc_object {
166 name: "foo",
167 srcs: ["a/b/c.c"],
168 include_build_directory: false,
Liz Kammera4aa4302021-03-18 16:56:36 -0400169}
170`,
171 expectedBazelTargets: []string{`cc_object(
172 name = "foo",
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000173 copts = ["-fno-addrsig"],
174 srcs = ["a/b/c.c"],
Jingwen Chendb120242021-02-23 00:46:47 -0500175)`,
176 },
177 },
Liz Kammera060c452021-03-24 10:14:47 -0400178 {
179 description: "cc_object with product variable",
180 moduleTypeUnderTest: "cc_object",
181 moduleTypeUnderTestFactory: cc.ObjectFactory,
182 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
183 blueprint: `cc_object {
184 name: "foo",
185 include_build_directory: false,
186 product_variables: {
187 platform_sdk_version: {
188 asflags: ["-DPLATFORM_SDK_VERSION=%d"],
189 },
190 },
Liz Kammera060c452021-03-24 10:14:47 -0400191}
192`,
193 expectedBazelTargets: []string{`cc_object(
194 name = "foo",
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000195 asflags = ["-DPLATFORM_SDK_VERSION={Platform_sdk_version}"],
196 copts = ["-fno-addrsig"],
Liz Kammera060c452021-03-24 10:14:47 -0400197)`,
198 },
199 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500200 }
201
202 dir := "."
203 for _, testCase := range testCases {
204 filesystem := make(map[string][]byte)
205 toParse := []string{
206 "Android.bp",
207 }
208 for f, content := range testCase.filesystem {
209 if strings.HasSuffix(f, "Android.bp") {
210 toParse = append(toParse, f)
211 }
212 filesystem[f] = []byte(content)
213 }
214 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
215 ctx := android.NewTestContext(config)
216 // Always register cc_defaults module factory
217 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
218
219 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
220 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000221 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500222 ctx.RegisterForBazelConversion()
223
224 _, errs := ctx.ParseFileList(dir, toParse)
225 if Errored(t, testCase.description, errs) {
226 continue
227 }
228 _, errs = ctx.ResolveDependencies(config)
229 if Errored(t, testCase.description, errs) {
230 continue
231 }
232
Jingwen Chen164e0862021-02-19 00:48:40 -0500233 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500234 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500235 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
236 fmt.Println(bazelTargets)
237 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
238 } else {
239 for i, target := range bazelTargets {
240 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
241 t.Errorf(
242 "%s: Expected generated Bazel target to be '%s', got '%s'",
243 testCase.description,
244 w,
245 g,
246 )
247 }
248 }
249 }
250 }
251}
Jingwen Chen5d864492021-02-24 07:20:12 -0500252
253func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
254 testCases := []struct {
255 description string
256 moduleTypeUnderTest string
257 moduleTypeUnderTestFactory android.ModuleFactory
258 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
259 blueprint string
260 expectedBazelTargets []string
261 filesystem map[string]string
262 }{
263 {
264 description: "cc_object setting cflags for one arch",
265 moduleTypeUnderTest: "cc_object",
266 moduleTypeUnderTestFactory: cc.ObjectFactory,
267 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
268 blueprint: `cc_object {
269 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400270 srcs: ["a.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500271 arch: {
272 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400273 cflags: ["-fPIC"], // string list
274 },
275 arm: {
276 srcs: ["arch/arm/file.S"], // label list
Jingwen Chen5d864492021-02-24 07:20:12 -0500277 },
278 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500279}
280`,
281 expectedBazelTargets: []string{
282 `cc_object(
283 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000284 copts = [
285 "-fno-addrsig",
286 "-I.",
287 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000288 "//build/bazel/platforms/arch:x86": ["-fPIC"],
Jingwen Chen07027912021-03-15 06:02:43 -0400289 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500290 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000291 srcs = ["a.cpp"] + select({
292 "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"],
Jingwen Chen07027912021-03-15 06:02:43 -0400293 "//conditions:default": [],
294 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500295)`,
296 },
297 },
298 {
299 description: "cc_object setting cflags for 4 architectures",
300 moduleTypeUnderTest: "cc_object",
301 moduleTypeUnderTestFactory: cc.ObjectFactory,
302 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
303 blueprint: `cc_object {
304 name: "foo",
Jingwen Chen07027912021-03-15 06:02:43 -0400305 srcs: ["base.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500306 arch: {
307 x86: {
Jingwen Chen07027912021-03-15 06:02:43 -0400308 srcs: ["x86.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500309 cflags: ["-fPIC"],
310 },
311 x86_64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400312 srcs: ["x86_64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500313 cflags: ["-fPIC"],
314 },
315 arm: {
Jingwen Chen07027912021-03-15 06:02:43 -0400316 srcs: ["arm.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500317 cflags: ["-Wall"],
318 },
319 arm64: {
Jingwen Chen07027912021-03-15 06:02:43 -0400320 srcs: ["arm64.cpp"],
Jingwen Chen5d864492021-02-24 07:20:12 -0500321 cflags: ["-Wall"],
322 },
323 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500324}
325`,
326 expectedBazelTargets: []string{
327 `cc_object(
328 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000329 copts = [
330 "-fno-addrsig",
331 "-I.",
332 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000333 "//build/bazel/platforms/arch:arm": ["-Wall"],
334 "//build/bazel/platforms/arch:arm64": ["-Wall"],
335 "//build/bazel/platforms/arch:x86": ["-fPIC"],
336 "//build/bazel/platforms/arch:x86_64": ["-fPIC"],
Jingwen Chen07027912021-03-15 06:02:43 -0400337 "//conditions:default": [],
Jingwen Chen5d864492021-02-24 07:20:12 -0500338 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000339 srcs = ["base.cpp"] + select({
340 "//build/bazel/platforms/arch:arm": ["arm.cpp"],
341 "//build/bazel/platforms/arch:arm64": ["arm64.cpp"],
342 "//build/bazel/platforms/arch:x86": ["x86.cpp"],
343 "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
Jingwen Chen07027912021-03-15 06:02:43 -0400344 "//conditions:default": [],
345 }),
Jingwen Chen5d864492021-02-24 07:20:12 -0500346)`,
347 },
348 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000349 {
350 description: "cc_object setting cflags for multiple OSes",
351 moduleTypeUnderTest: "cc_object",
352 moduleTypeUnderTestFactory: cc.ObjectFactory,
353 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
354 blueprint: `cc_object {
355 name: "foo",
356 srcs: ["base.cpp"],
357 target: {
358 android: {
359 cflags: ["-fPIC"],
360 },
361 windows: {
362 cflags: ["-fPIC"],
363 },
364 darwin: {
365 cflags: ["-Wall"],
366 },
367 },
Jingwen Chenc1c26502021-04-05 10:35:13 +0000368}
369`,
370 expectedBazelTargets: []string{
371 `cc_object(
372 name = "foo",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000373 copts = [
374 "-fno-addrsig",
375 "-I.",
376 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000377 "//build/bazel/platforms/os:android": ["-fPIC"],
378 "//build/bazel/platforms/os:darwin": ["-Wall"],
379 "//build/bazel/platforms/os:windows": ["-fPIC"],
Jingwen Chenc1c26502021-04-05 10:35:13 +0000380 "//conditions:default": [],
381 }),
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000382 srcs = ["base.cpp"],
Jingwen Chenc1c26502021-04-05 10:35:13 +0000383)`,
384 },
385 },
Jingwen Chen5d864492021-02-24 07:20:12 -0500386 }
387
388 dir := "."
389 for _, testCase := range testCases {
390 filesystem := make(map[string][]byte)
391 toParse := []string{
392 "Android.bp",
393 }
394 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
395 ctx := android.NewTestContext(config)
396 // Always register cc_defaults module factory
397 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
398
399 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
400 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
Jingwen Chened9c17d2021-04-13 07:14:55 +0000401 ctx.RegisterBp2BuildConfig(bp2buildConfig)
Jingwen Chen5d864492021-02-24 07:20:12 -0500402 ctx.RegisterForBazelConversion()
403
404 _, errs := ctx.ParseFileList(dir, toParse)
405 if Errored(t, testCase.description, errs) {
406 continue
407 }
408 _, errs = ctx.ResolveDependencies(config)
409 if Errored(t, testCase.description, errs) {
410 continue
411 }
412
413 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
414 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
415 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
416 fmt.Println(bazelTargets)
417 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
418 } else {
419 for i, target := range bazelTargets {
420 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
421 t.Errorf(
422 "%s: Expected generated Bazel target to be '%s', got '%s'",
423 testCase.description,
424 w,
425 g,
426 )
427 }
428 }
429 }
430 }
431}