blob: 1c058ba3e749ae8fbcba406a6108c32db9f778d0 [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 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500212 }
213
214 dir := "."
215 for _, testCase := range testCases {
216 filesystem := make(map[string][]byte)
217 toParse := []string{
218 "Android.bp",
219 }
220 for f, content := range testCase.filesystem {
221 if strings.HasSuffix(f, "Android.bp") {
222 toParse = append(toParse, f)
223 }
224 filesystem[f] = []byte(content)
225 }
226 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
227 ctx := android.NewTestContext(config)
228 // Always register cc_defaults module factory
229 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
230
231 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
232 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
233 ctx.RegisterForBazelConversion()
234
235 _, errs := ctx.ParseFileList(dir, toParse)
236 if Errored(t, testCase.description, errs) {
237 continue
238 }
239 _, errs = ctx.ResolveDependencies(config)
240 if Errored(t, testCase.description, errs) {
241 continue
242 }
243
Jingwen Chen164e0862021-02-19 00:48:40 -0500244 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500245 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500246 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
247 fmt.Println(bazelTargets)
248 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
249 } else {
250 for i, target := range bazelTargets {
251 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
252 t.Errorf(
253 "%s: Expected generated Bazel target to be '%s', got '%s'",
254 testCase.description,
255 w,
256 g,
257 )
258 }
259 }
260 }
261 }
262}
Jingwen Chen5d864492021-02-24 07:20:12 -0500263
264func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
265 testCases := []struct {
266 description string
267 moduleTypeUnderTest string
268 moduleTypeUnderTestFactory android.ModuleFactory
269 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
270 blueprint string
271 expectedBazelTargets []string
272 filesystem map[string]string
273 }{
274 {
275 description: "cc_object setting cflags for one arch",
276 moduleTypeUnderTest: "cc_object",
277 moduleTypeUnderTestFactory: cc.ObjectFactory,
278 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
279 blueprint: `cc_object {
280 name: "foo",
281 arch: {
282 x86: {
283 cflags: ["-fPIC"],
284 },
285 },
286 bazel_module: { bp2build_available: true },
287}
288`,
289 expectedBazelTargets: []string{
290 `cc_object(
291 name = "foo",
292 copts = [
293 "-fno-addrsig",
294 ] + select({
295 "@bazel_tools//platforms:x86_32": [
296 "-fPIC",
297 ],
298 "//conditions:default": [
299 ],
300 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400301 local_include_dirs = [
302 ".",
303 ],
Jingwen Chen5d864492021-02-24 07:20:12 -0500304)`,
305 },
306 },
307 {
308 description: "cc_object setting cflags for 4 architectures",
309 moduleTypeUnderTest: "cc_object",
310 moduleTypeUnderTestFactory: cc.ObjectFactory,
311 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
312 blueprint: `cc_object {
313 name: "foo",
314 arch: {
315 x86: {
316 cflags: ["-fPIC"],
317 },
318 x86_64: {
319 cflags: ["-fPIC"],
320 },
321 arm: {
322 cflags: ["-Wall"],
323 },
324 arm64: {
325 cflags: ["-Wall"],
326 },
327 },
328 bazel_module: { bp2build_available: true },
329}
330`,
331 expectedBazelTargets: []string{
332 `cc_object(
333 name = "foo",
334 copts = [
335 "-fno-addrsig",
336 ] + select({
337 "@bazel_tools//platforms:arm": [
338 "-Wall",
339 ],
340 "@bazel_tools//platforms:aarch64": [
341 "-Wall",
342 ],
343 "@bazel_tools//platforms:x86_32": [
344 "-fPIC",
345 ],
346 "@bazel_tools//platforms:x86_64": [
347 "-fPIC",
348 ],
349 "//conditions:default": [
350 ],
351 }),
Liz Kammera4aa4302021-03-18 16:56:36 -0400352 local_include_dirs = [
353 ".",
354 ],
Jingwen Chen5d864492021-02-24 07:20:12 -0500355)`,
356 },
357 },
358 }
359
360 dir := "."
361 for _, testCase := range testCases {
362 filesystem := make(map[string][]byte)
363 toParse := []string{
364 "Android.bp",
365 }
366 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
367 ctx := android.NewTestContext(config)
368 // Always register cc_defaults module factory
369 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
370
371 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
372 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
373 ctx.RegisterForBazelConversion()
374
375 _, errs := ctx.ParseFileList(dir, toParse)
376 if Errored(t, testCase.description, errs) {
377 continue
378 }
379 _, errs = ctx.ResolveDependencies(config)
380 if Errored(t, testCase.description, errs) {
381 continue
382 }
383
384 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
385 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
386 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
387 fmt.Println(bazelTargets)
388 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
389 } else {
390 for i, target := range bazelTargets {
391 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
392 t.Errorf(
393 "%s: Expected generated Bazel target to be '%s', got '%s'",
394 testCase.description,
395 w,
396 g,
397 )
398 }
399 }
400 }
401 }
402}