blob: 4620d8da694e6f31fe81610290f61c5001c6e569 [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",
77 "a/b/foo.h",
78 "a/b/c.c",
79 ],
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",
309 arch: {
310 x86: {
311 cflags: ["-fPIC"],
312 },
313 },
314 bazel_module: { bp2build_available: true },
315}
316`,
317 expectedBazelTargets: []string{
318 `cc_object(
319 name = "foo",
320 copts = [
321 "-fno-addrsig",
322 ] + select({
323 "@bazel_tools//platforms:x86_32": [
324 "-fPIC",
325 ],
326 "//conditions:default": [
327 ],
328 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400329 local_include_dirs = [
330 ".",
331 ],
Jingwen Chen5d864492021-02-24 07:20:12 -0500332)`,
333 },
334 },
335 {
336 description: "cc_object setting cflags for 4 architectures",
337 moduleTypeUnderTest: "cc_object",
338 moduleTypeUnderTestFactory: cc.ObjectFactory,
339 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
340 blueprint: `cc_object {
341 name: "foo",
342 arch: {
343 x86: {
344 cflags: ["-fPIC"],
345 },
346 x86_64: {
347 cflags: ["-fPIC"],
348 },
349 arm: {
350 cflags: ["-Wall"],
351 },
352 arm64: {
353 cflags: ["-Wall"],
354 },
355 },
356 bazel_module: { bp2build_available: true },
357}
358`,
359 expectedBazelTargets: []string{
360 `cc_object(
361 name = "foo",
362 copts = [
363 "-fno-addrsig",
364 ] + select({
365 "@bazel_tools//platforms:arm": [
366 "-Wall",
367 ],
368 "@bazel_tools//platforms:aarch64": [
369 "-Wall",
370 ],
371 "@bazel_tools//platforms:x86_32": [
372 "-fPIC",
373 ],
374 "@bazel_tools//platforms:x86_64": [
375 "-fPIC",
376 ],
377 "//conditions:default": [
378 ],
379 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400380 local_include_dirs = [
381 ".",
382 ],
Jingwen Chen5d864492021-02-24 07:20:12 -0500383)`,
384 },
385 },
386 }
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)
401 ctx.RegisterForBazelConversion()
402
403 _, errs := ctx.ParseFileList(dir, toParse)
404 if Errored(t, testCase.description, errs) {
405 continue
406 }
407 _, errs = ctx.ResolveDependencies(config)
408 if Errored(t, testCase.description, errs) {
409 continue
410 }
411
412 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
413 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
414 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
415 fmt.Println(bazelTargets)
416 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
417 } else {
418 for i, target := range bazelTargets {
419 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
420 t.Errorf(
421 "%s: Expected generated Bazel target to be '%s', got '%s'",
422 testCase.description,
423 w,
424 g,
425 )
426 }
427 }
428 }
429 }
430}