blob: 1d4e32221237682ca3911be569dc9aefe093dfd5 [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",
73 ],
74 srcs = [
75 "a/b/bar.h",
76 "a/b/foo.h",
77 "a/b/c.c",
78 ],
79)`,
80 },
81 },
82 {
83 description: "simple cc_object with defaults",
84 moduleTypeUnderTest: "cc_object",
85 moduleTypeUnderTestFactory: cc.ObjectFactory,
86 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
87 blueprint: `cc_object {
88 name: "foo",
89 local_include_dirs: ["include"],
90 srcs: [
91 "a/b/*.h",
92 "a/b/c.c"
93 ],
94
95 defaults: ["foo_defaults"],
96 bazel_module: { bp2build_available: true },
97}
98
99cc_defaults {
100 name: "foo_defaults",
101 defaults: ["foo_bar_defaults"],
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500102}
103
104cc_defaults {
105 name: "foo_bar_defaults",
106 cflags: [
107 "-Wno-gcc-compat",
108 "-Wall",
109 "-Werror",
110 ],
111}
112`,
113 expectedBazelTargets: []string{`cc_object(
114 name = "foo",
115 copts = [
116 "-Wno-gcc-compat",
117 "-Wall",
118 "-Werror",
119 "-fno-addrsig",
120 ],
121 local_include_dirs = [
122 "include",
123 ],
124 srcs = [
125 "a/b/c.c",
126 ],
127)`,
128 },
129 },
Jingwen Chendb120242021-02-23 00:46:47 -0500130 {
131 description: "cc_object with cc_object deps in objs props",
132 moduleTypeUnderTest: "cc_object",
133 moduleTypeUnderTestFactory: cc.ObjectFactory,
134 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
135 filesystem: map[string]string{
136 "a/b/c.c": "",
137 "x/y/z.c": "",
138 },
139 blueprint: `cc_object {
140 name: "foo",
141 srcs: ["a/b/c.c"],
142 objs: ["bar"],
143
144 bazel_module: { bp2build_available: true },
145}
146
147cc_object {
148 name: "bar",
149 srcs: ["x/y/z.c"],
150
151 bazel_module: { bp2build_available: true },
152}
153`,
154 expectedBazelTargets: []string{`cc_object(
155 name = "bar",
156 copts = [
157 "-fno-addrsig",
158 ],
159 srcs = [
160 "x/y/z.c",
161 ],
162)`, `cc_object(
163 name = "foo",
164 copts = [
165 "-fno-addrsig",
166 ],
167 deps = [
168 ":bar",
169 ],
170 srcs = [
171 "a/b/c.c",
172 ],
173)`,
174 },
175 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500176 }
177
178 dir := "."
179 for _, testCase := range testCases {
180 filesystem := make(map[string][]byte)
181 toParse := []string{
182 "Android.bp",
183 }
184 for f, content := range testCase.filesystem {
185 if strings.HasSuffix(f, "Android.bp") {
186 toParse = append(toParse, f)
187 }
188 filesystem[f] = []byte(content)
189 }
190 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
191 ctx := android.NewTestContext(config)
192 // Always register cc_defaults module factory
193 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
194
195 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
196 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
197 ctx.RegisterForBazelConversion()
198
199 _, errs := ctx.ParseFileList(dir, toParse)
200 if Errored(t, testCase.description, errs) {
201 continue
202 }
203 _, errs = ctx.ResolveDependencies(config)
204 if Errored(t, testCase.description, errs) {
205 continue
206 }
207
Jingwen Chen164e0862021-02-19 00:48:40 -0500208 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500209 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500210 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
211 fmt.Println(bazelTargets)
212 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
213 } else {
214 for i, target := range bazelTargets {
215 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
216 t.Errorf(
217 "%s: Expected generated Bazel target to be '%s', got '%s'",
218 testCase.description,
219 w,
220 g,
221 )
222 }
223 }
224 }
225 }
226}
Jingwen Chen5d864492021-02-24 07:20:12 -0500227
228func TestCcObjectConfigurableAttributesBp2Build(t *testing.T) {
229 testCases := []struct {
230 description string
231 moduleTypeUnderTest string
232 moduleTypeUnderTestFactory android.ModuleFactory
233 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
234 blueprint string
235 expectedBazelTargets []string
236 filesystem map[string]string
237 }{
238 {
239 description: "cc_object setting cflags for one arch",
240 moduleTypeUnderTest: "cc_object",
241 moduleTypeUnderTestFactory: cc.ObjectFactory,
242 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
243 blueprint: `cc_object {
244 name: "foo",
245 arch: {
246 x86: {
247 cflags: ["-fPIC"],
248 },
249 },
250 bazel_module: { bp2build_available: true },
251}
252`,
253 expectedBazelTargets: []string{
254 `cc_object(
255 name = "foo",
256 copts = [
257 "-fno-addrsig",
258 ] + select({
259 "@bazel_tools//platforms:x86_32": [
260 "-fPIC",
261 ],
262 "//conditions:default": [
263 ],
264 }),
265)`,
266 },
267 },
268 {
269 description: "cc_object setting cflags for 4 architectures",
270 moduleTypeUnderTest: "cc_object",
271 moduleTypeUnderTestFactory: cc.ObjectFactory,
272 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
273 blueprint: `cc_object {
274 name: "foo",
275 arch: {
276 x86: {
277 cflags: ["-fPIC"],
278 },
279 x86_64: {
280 cflags: ["-fPIC"],
281 },
282 arm: {
283 cflags: ["-Wall"],
284 },
285 arm64: {
286 cflags: ["-Wall"],
287 },
288 },
289 bazel_module: { bp2build_available: true },
290}
291`,
292 expectedBazelTargets: []string{
293 `cc_object(
294 name = "foo",
295 copts = [
296 "-fno-addrsig",
297 ] + select({
298 "@bazel_tools//platforms:arm": [
299 "-Wall",
300 ],
301 "@bazel_tools//platforms:aarch64": [
302 "-Wall",
303 ],
304 "@bazel_tools//platforms:x86_32": [
305 "-fPIC",
306 ],
307 "@bazel_tools//platforms:x86_64": [
308 "-fPIC",
309 ],
310 "//conditions:default": [
311 ],
312 }),
313)`,
314 },
315 },
316 }
317
318 dir := "."
319 for _, testCase := range testCases {
320 filesystem := make(map[string][]byte)
321 toParse := []string{
322 "Android.bp",
323 }
324 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
325 ctx := android.NewTestContext(config)
326 // Always register cc_defaults module factory
327 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
328
329 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
330 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
331 ctx.RegisterForBazelConversion()
332
333 _, errs := ctx.ParseFileList(dir, toParse)
334 if Errored(t, testCase.description, errs) {
335 continue
336 }
337 _, errs = ctx.ResolveDependencies(config)
338 if Errored(t, testCase.description, errs) {
339 continue
340 }
341
342 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
343 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
344 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
345 fmt.Println(bazelTargets)
346 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
347 } else {
348 for i, target := range bazelTargets {
349 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
350 t.Errorf(
351 "%s: Expected generated Bazel target to be '%s', got '%s'",
352 testCase.description,
353 w,
354 g,
355 )
356 }
357 }
358 }
359 }
360}