blob: 9d91ffa1cac601b4b35fb9c073c9266b0124d680 [file] [log] [blame]
Rupert Shuttleworth54e78412021-02-15 11:04:32 +00001// 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 "strings"
21 "testing"
22)
23
24const (
25 // See cc/testing.go for more context
26 soongCcLibraryPreamble = `
27cc_defaults {
28 name: "linux_bionic_supported",
29}
30
31toolchain_library {
32 name: "libclang_rt.builtins-x86_64-android",
33 defaults: ["linux_bionic_supported"],
34 vendor_available: true,
35 vendor_ramdisk_available: true,
36 product_available: true,
37 recovery_available: true,
38 native_bridge_supported: true,
39 src: "",
40}
41
42toolchain_library {
43 name: "libatomic",
44 defaults: ["linux_bionic_supported"],
45 vendor_available: true,
46 vendor_ramdisk_available: true,
47 product_available: true,
48 recovery_available: true,
49 native_bridge_supported: true,
50 src: "",
51}`
52)
53
54func TestCcLibraryHeadersLoadStatement(t *testing.T) {
55 testCases := []struct {
56 bazelTargets BazelTargets
57 expectedLoadStatements string
58 }{
59 {
60 bazelTargets: BazelTargets{
61 BazelTarget{
62 name: "cc_library_headers_target",
63 ruleClass: "cc_library_headers",
64 // Note: no bzlLoadLocation for native rules
65 },
66 },
67 expectedLoadStatements: ``,
68 },
69 }
70
71 for _, testCase := range testCases {
72 actual := testCase.bazelTargets.LoadStatements()
73 expected := testCase.expectedLoadStatements
74 if actual != expected {
75 t.Fatalf("Expected load statements to be %s, got %s", expected, actual)
76 }
77 }
78
79}
80
81func TestCcLibraryHeadersBp2Build(t *testing.T) {
82 testCases := []struct {
83 description string
84 moduleTypeUnderTest string
85 moduleTypeUnderTestFactory android.ModuleFactory
86 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
87 preArchMutators []android.RegisterMutatorFunc
88 depsMutators []android.RegisterMutatorFunc
89 bp string
90 expectedBazelTargets []string
91 filesystem map[string]string
92 dir string
93 }{
94 {
95 description: "cc_library_headers test",
96 moduleTypeUnderTest: "cc_library_headers",
97 moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
98 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
99 filesystem: map[string]string{
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000100 "lib-1/lib1a.h": "",
101 "lib-1/lib1b.h": "",
102 "lib-2/lib2a.h": "",
103 "lib-2/lib2b.h": "",
104 "dir-1/dir1a.h": "",
105 "dir-1/dir1b.h": "",
106 "dir-2/dir2a.h": "",
107 "dir-2/dir2b.h": "",
108 "arch_arm64_exported_include_dir/a.h": "",
109 "arch_x86_exported_include_dir/b.h": "",
110 "arch_x86_64_exported_include_dir/c.h": "",
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000111 },
112 bp: soongCcLibraryPreamble + `
113cc_library_headers {
114 name: "lib-1",
115 export_include_dirs: ["lib-1"],
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000116}
117
118cc_library_headers {
119 name: "lib-2",
120 export_include_dirs: ["lib-2"],
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000121}
122
123cc_library_headers {
124 name: "foo_headers",
125 export_include_dirs: ["dir-1", "dir-2"],
126 header_libs: ["lib-1", "lib-2"],
Rupert Shuttleworth095081c2021-03-25 09:06:03 +0000127
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000128 arch: {
129 arm64: {
130 // We expect dir-1 headers to be dropped, because dir-1 is already in export_include_dirs
131 export_include_dirs: ["arch_arm64_exported_include_dir", "dir-1"],
132 },
133 x86: {
134 export_include_dirs: ["arch_x86_exported_include_dir"],
135 },
136 x86_64: {
137 export_include_dirs: ["arch_x86_64_exported_include_dir"],
138 },
139 },
140
Rupert Shuttleworth095081c2021-03-25 09:06:03 +0000141 // TODO: Also support export_header_lib_headers
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000142}`,
143 expectedBazelTargets: []string{`cc_library_headers(
144 name = "foo_headers",
145 deps = [
146 ":lib-1",
147 ":lib-2",
148 ],
149 hdrs = [
150 "dir-1/dir1a.h",
151 "dir-1/dir1b.h",
152 "dir-2/dir2a.h",
153 "dir-2/dir2b.h",
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000154 ] + select({
155 "//build/bazel/platforms/arch:arm64": [
156 "arch_arm64_exported_include_dir/a.h",
157 ],
158 "//build/bazel/platforms/arch:x86": [
159 "arch_x86_exported_include_dir/b.h",
160 ],
161 "//build/bazel/platforms/arch:x86_64": [
162 "arch_x86_64_exported_include_dir/c.h",
163 ],
164 "//conditions:default": [],
165 }),
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000166 includes = [
167 "dir-1",
168 "dir-2",
Rupert Shuttleworthb8151682021-04-06 20:06:21 +0000169 ] + select({
170 "//build/bazel/platforms/arch:arm64": [
171 "arch_arm64_exported_include_dir",
172 ],
173 "//build/bazel/platforms/arch:x86": [
174 "arch_x86_exported_include_dir",
175 ],
176 "//build/bazel/platforms/arch:x86_64": [
177 "arch_x86_64_exported_include_dir",
178 ],
179 "//conditions:default": [],
180 }),
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000181)`, `cc_library_headers(
182 name = "lib-1",
183 hdrs = [
184 "lib-1/lib1a.h",
185 "lib-1/lib1b.h",
186 ],
187 includes = [
188 "lib-1",
189 ],
190)`, `cc_library_headers(
191 name = "lib-2",
192 hdrs = [
193 "lib-2/lib2a.h",
194 "lib-2/lib2b.h",
195 ],
196 includes = [
197 "lib-2",
198 ],
199)`},
200 },
Jingwen Chen91220d72021-03-24 02:18:33 -0400201 {
202 description: "cc_library_headers test with os-specific header_libs props",
203 moduleTypeUnderTest: "cc_library_headers",
204 moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
205 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
206 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
207 filesystem: map[string]string{},
208 bp: soongCcLibraryPreamble + `
209cc_library_headers { name: "android-lib" }
210cc_library_headers { name: "base-lib" }
211cc_library_headers { name: "darwin-lib" }
212cc_library_headers { name: "fuchsia-lib" }
213cc_library_headers { name: "linux-lib" }
214cc_library_headers { name: "linux_bionic-lib" }
215cc_library_headers { name: "windows-lib" }
216cc_library_headers {
217 name: "foo_headers",
218 header_libs: ["base-lib"],
219 target: {
220 android: { header_libs: ["android-lib"] },
221 darwin: { header_libs: ["darwin-lib"] },
222 fuchsia: { header_libs: ["fuchsia-lib"] },
223 linux_bionic: { header_libs: ["linux_bionic-lib"] },
224 linux_glibc: { header_libs: ["linux-lib"] },
225 windows: { header_libs: ["windows-lib"] },
226 },
227 bazel_module: { bp2build_available: true },
228}`,
229 expectedBazelTargets: []string{`cc_library_headers(
230 name = "android-lib",
231)`, `cc_library_headers(
232 name = "base-lib",
233)`, `cc_library_headers(
234 name = "darwin-lib",
235)`, `cc_library_headers(
236 name = "foo_headers",
237 deps = [
238 ":base-lib",
239 ] + select({
240 "//build/bazel/platforms/os:android": [
241 ":android-lib",
242 ],
243 "//build/bazel/platforms/os:darwin": [
244 ":darwin-lib",
245 ],
246 "//build/bazel/platforms/os:fuchsia": [
247 ":fuchsia-lib",
248 ],
249 "//build/bazel/platforms/os:linux": [
250 ":linux-lib",
251 ],
252 "//build/bazel/platforms/os:linux_bionic": [
253 ":linux_bionic-lib",
254 ],
255 "//build/bazel/platforms/os:windows": [
256 ":windows-lib",
257 ],
258 "//conditions:default": [],
259 }),
260)`, `cc_library_headers(
261 name = "fuchsia-lib",
262)`, `cc_library_headers(
263 name = "linux-lib",
264)`, `cc_library_headers(
265 name = "linux_bionic-lib",
266)`, `cc_library_headers(
267 name = "windows-lib",
268)`},
269 },
270 {
271 description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
272 moduleTypeUnderTest: "cc_library_headers",
273 moduleTypeUnderTestFactory: cc.LibraryHeaderFactory,
274 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
275 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
276 filesystem: map[string]string{},
277 bp: soongCcLibraryPreamble + `
278cc_library_headers { name: "android-lib" }
279cc_library_headers { name: "exported-lib" }
280cc_library_headers {
281 name: "foo_headers",
282 target: {
283 android: { header_libs: ["android-lib"], export_header_lib_headers: ["exported-lib"] },
284 },
285}`,
286 expectedBazelTargets: []string{`cc_library_headers(
287 name = "android-lib",
288)`, `cc_library_headers(
289 name = "exported-lib",
290)`, `cc_library_headers(
291 name = "foo_headers",
292 deps = [] + select({
293 "//build/bazel/platforms/os:android": [
294 ":android-lib",
295 ":exported-lib",
296 ],
297 "//conditions:default": [],
298 }),
299)`},
300 },
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000301 }
302
303 dir := "."
304 for _, testCase := range testCases {
305 filesystem := make(map[string][]byte)
306 toParse := []string{
307 "Android.bp",
308 }
309 for f, content := range testCase.filesystem {
310 if strings.HasSuffix(f, "Android.bp") {
311 toParse = append(toParse, f)
312 }
313 filesystem[f] = []byte(content)
314 }
315 config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
316 ctx := android.NewTestContext(config)
317
Jingwen Chen91220d72021-03-24 02:18:33 -0400318 // TODO(jingwen): make this default for all bp2build tests
319 ctx.RegisterBp2BuildConfig(bp2buildConfig)
320
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000321 cc.RegisterCCBuildComponents(ctx)
322 ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
323
324 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
325 for _, m := range testCase.depsMutators {
326 ctx.DepsBp2BuildMutators(m)
327 }
328 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
329 ctx.RegisterForBazelConversion()
330
331 _, errs := ctx.ParseFileList(dir, toParse)
332 if Errored(t, testCase.description, errs) {
333 continue
334 }
335 _, errs = ctx.ResolveDependencies(config)
336 if Errored(t, testCase.description, errs) {
337 continue
338 }
339
340 checkDir := dir
341 if testCase.dir != "" {
342 checkDir = testCase.dir
343 }
Jingwen Chen164e0862021-02-19 00:48:40 -0500344 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500345 bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
Rupert Shuttleworth54e78412021-02-15 11:04:32 +0000346 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
347 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
348 } else {
349 for i, target := range bazelTargets {
350 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
351 t.Errorf(
352 "%s: Expected generated Bazel target to be '%s', got '%s'",
353 testCase.description,
354 w,
355 g,
356 )
357 }
358 }
359 }
360 }
361}