blob: 74c65c00328e9b1c135b7ad861c1d59a73346a03 [file] [log] [blame]
Jingwen Chen63930982021-03-24 10:04:33 -04001// 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)
42
43func TestCcLibraryBp2Build(t *testing.T) {
44 testCases := []struct {
45 description string
46 moduleTypeUnderTest string
47 moduleTypeUnderTestFactory android.ModuleFactory
48 moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
49 bp string
50 expectedBazelTargets []string
51 filesystem map[string]string
52 dir string
Jingwen Chen53681ef2021-04-29 08:15:13 +000053 depsMutators []android.RegisterMutatorFunc
Jingwen Chen63930982021-03-24 10:04:33 -040054 }{
55 {
56 description: "cc_library - simple example",
57 moduleTypeUnderTest: "cc_library",
58 moduleTypeUnderTestFactory: cc.LibraryFactory,
59 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
60 filesystem: map[string]string{
61 "android.cpp": "",
62 "darwin.cpp": "",
63 // Refer to cc.headerExts for the supported header extensions in Soong.
64 "header.h": "",
65 "header.hh": "",
66 "header.hpp": "",
67 "header.hxx": "",
68 "header.h++": "",
69 "header.inl": "",
70 "header.inc": "",
71 "header.ipp": "",
72 "header.h.generic": "",
73 "impl.cpp": "",
74 "linux.cpp": "",
75 "x86.cpp": "",
76 "x86_64.cpp": "",
77 "foo-dir/a.h": "",
78 },
79 bp: soongCcLibraryPreamble + `
80cc_library_headers { name: "some-headers" }
81cc_library {
82 name: "foo-lib",
83 srcs: ["impl.cpp"],
84 cflags: ["-Wall"],
85 header_libs: ["some-headers"],
86 export_include_dirs: ["foo-dir"],
87 ldflags: ["-Wl,--exclude-libs=bar.a"],
88 arch: {
89 x86: {
90 ldflags: ["-Wl,--exclude-libs=baz.a"],
91 srcs: ["x86.cpp"],
92 },
93 x86_64: {
94 ldflags: ["-Wl,--exclude-libs=qux.a"],
95 srcs: ["x86_64.cpp"],
96 },
97 },
98 target: {
99 android: {
100 srcs: ["android.cpp"],
101 },
102 linux_glibc: {
103 srcs: ["linux.cpp"],
104 },
105 darwin: {
106 srcs: ["darwin.cpp"],
107 },
108 },
109}
110`,
111 expectedBazelTargets: []string{`cc_library(
112 name = "foo-lib",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000113 copts = [
114 "-Wall",
115 "-I.",
116 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000117 deps = [":some-headers"],
Jingwen Chened9c17d2021-04-13 07:14:55 +0000118 includes = ["foo-dir"],
119 linkopts = ["-Wl,--exclude-libs=bar.a"] + select({
120 "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
121 "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
122 "//conditions:default": [],
123 }),
Jingwen Chen882bcc12021-04-27 05:54:20 +0000124 srcs = ["impl.cpp"] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000125 "//build/bazel/platforms/arch:x86": ["x86.cpp"],
126 "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
Jingwen Chen63930982021-03-24 10:04:33 -0400127 "//conditions:default": [],
128 }) + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000129 "//build/bazel/platforms/os:android": ["android.cpp"],
130 "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
131 "//build/bazel/platforms/os:linux": ["linux.cpp"],
Jingwen Chen63930982021-03-24 10:04:33 -0400132 "//conditions:default": [],
133 }),
134)`},
135 },
136 {
137 description: "cc_library - trimmed example of //bionic/linker:ld-android",
138 moduleTypeUnderTest: "cc_library",
139 moduleTypeUnderTestFactory: cc.LibraryFactory,
140 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
141 filesystem: map[string]string{
142 "ld-android.cpp": "",
143 "linked_list.h": "",
144 "linker.h": "",
145 "linker_block_allocator.h": "",
146 "linker_cfi.h": "",
147 },
148 bp: soongCcLibraryPreamble + `
149cc_library_headers { name: "libc_headers" }
150cc_library {
151 name: "fake-ld-android",
152 srcs: ["ld_android.cpp"],
153 cflags: [
154 "-Wall",
155 "-Wextra",
156 "-Wunused",
157 "-Werror",
158 ],
159 header_libs: ["libc_headers"],
160 ldflags: [
161 "-Wl,--exclude-libs=libgcc.a",
162 "-Wl,--exclude-libs=libgcc_stripped.a",
163 "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
164 "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
165 "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
166 "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
167 ],
168 arch: {
169 x86: {
170 ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
171 },
172 x86_64: {
173 ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
174 },
175 },
176}
177`,
178 expectedBazelTargets: []string{`cc_library(
179 name = "fake-ld-android",
180 copts = [
181 "-Wall",
182 "-Wextra",
183 "-Wunused",
184 "-Werror",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000185 "-I.",
Jingwen Chen63930982021-03-24 10:04:33 -0400186 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000187 deps = [":libc_headers"],
Jingwen Chen63930982021-03-24 10:04:33 -0400188 linkopts = [
189 "-Wl,--exclude-libs=libgcc.a",
190 "-Wl,--exclude-libs=libgcc_stripped.a",
191 "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
192 "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
193 "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
194 "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
195 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000196 "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=libgcc_eh.a"],
197 "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=libgcc_eh.a"],
Jingwen Chen63930982021-03-24 10:04:33 -0400198 "//conditions:default": [],
199 }),
Jingwen Chen882bcc12021-04-27 05:54:20 +0000200 srcs = ["ld_android.cpp"],
Jingwen Chen63930982021-03-24 10:04:33 -0400201)`},
202 },
Jingwen Chen4ecc67d2021-04-27 09:47:02 +0000203 {
204 description: "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math",
205 moduleTypeUnderTest: "cc_library",
206 moduleTypeUnderTestFactory: cc.LibraryFactory,
207 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
208 dir: "external",
209 filesystem: map[string]string{
210 "external/math/cosf.c": "",
211 "external/math/erf.c": "",
212 "external/math/erf_data.c": "",
213 "external/math/erff.c": "",
214 "external/math/erff_data.c": "",
215 "external/Android.bp": `
216cc_library {
217 name: "fake-libarm-optimized-routines-math",
218 exclude_srcs: [
219 // Provided by:
220 // bionic/libm/upstream-freebsd/lib/msun/src/s_erf.c
221 // bionic/libm/upstream-freebsd/lib/msun/src/s_erff.c
222 "math/erf.c",
223 "math/erf_data.c",
224 "math/erff.c",
225 "math/erff_data.c",
226 ],
227 srcs: [
228 "math/*.c",
229 ],
230 // arch-specific settings
231 arch: {
232 arm64: {
233 cflags: [
234 "-DHAVE_FAST_FMA=1",
235 ],
236 },
237 },
238 bazel_module: { bp2build_available: true },
239}
240`,
241 },
242 bp: soongCcLibraryPreamble,
243 expectedBazelTargets: []string{`cc_library(
244 name = "fake-libarm-optimized-routines-math",
245 copts = ["-Iexternal"] + select({
246 "//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
247 "//conditions:default": [],
248 }),
249 srcs = ["math/cosf.c"],
250)`},
251 },
Jingwen Chen53681ef2021-04-29 08:15:13 +0000252 {
253 description: "cc_library shared/static props",
254 moduleTypeUnderTest: "cc_library",
255 moduleTypeUnderTestFactory: cc.LibraryFactory,
256 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
257 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
258 dir: "foo/bar",
259 filesystem: map[string]string{
Chris Parsons08648312021-05-06 16:23:19 -0400260 "foo/bar/both.cpp": "",
261 "foo/bar/sharedonly.cpp": "",
262 "foo/bar/staticonly.cpp": "",
Jingwen Chen53681ef2021-04-29 08:15:13 +0000263 "foo/bar/Android.bp": `
264cc_library {
265 name: "a",
Chris Parsons08648312021-05-06 16:23:19 -0400266 srcs: ["both.cpp"],
267 cflags: ["bothflag"],
268 shared_libs: ["shared_dep_for_both"],
269 static_libs: ["static_dep_for_both"],
270 whole_static_libs: ["whole_static_lib_for_both"],
271 static: {
272 srcs: ["staticonly.cpp"],
273 cflags: ["staticflag"],
274 shared_libs: ["shared_dep_for_static"],
275 static_libs: ["static_dep_for_static"],
276 whole_static_libs: ["whole_static_lib_for_static"],
277 },
278 shared: {
279 srcs: ["sharedonly.cpp"],
280 cflags: ["sharedflag"],
281 shared_libs: ["shared_dep_for_shared"],
282 static_libs: ["static_dep_for_shared"],
283 whole_static_libs: ["whole_static_lib_for_shared"],
284 },
Jingwen Chen53681ef2021-04-29 08:15:13 +0000285 bazel_module: { bp2build_available: true },
286}
287
Chris Parsons08648312021-05-06 16:23:19 -0400288cc_library_static { name: "static_dep_for_shared" }
289
290cc_library_static { name: "static_dep_for_static" }
291
292cc_library_static { name: "static_dep_for_both" }
293
294cc_library_static { name: "whole_static_lib_for_shared" }
295
296cc_library_static { name: "whole_static_lib_for_static" }
297
298cc_library_static { name: "whole_static_lib_for_both" }
299
300cc_library { name: "shared_dep_for_shared" }
301
302cc_library { name: "shared_dep_for_static" }
303
304cc_library { name: "shared_dep_for_both" }
Jingwen Chen53681ef2021-04-29 08:15:13 +0000305`,
306 },
307 bp: soongCcLibraryPreamble,
308 expectedBazelTargets: []string{`cc_library(
309 name = "a",
Chris Parsons08648312021-05-06 16:23:19 -0400310 copts = [
311 "bothflag",
312 "-Ifoo/bar",
313 ],
314 deps = [":static_dep_for_both"],
315 dynamic_deps = [":shared_dep_for_both"],
316 dynamic_deps_for_shared = [":shared_dep_for_shared"],
317 dynamic_deps_for_static = [":shared_dep_for_static"],
318 shared_copts = ["sharedflag"],
319 shared_srcs = ["sharedonly.cpp"],
320 srcs = ["both.cpp"],
321 static_copts = ["staticflag"],
322 static_deps_for_shared = [":static_dep_for_shared"],
323 static_deps_for_static = [":static_dep_for_static"],
324 static_srcs = ["staticonly.cpp"],
325 whole_archive_deps = [":whole_static_lib_for_both"],
326 whole_archive_deps_for_shared = [":whole_static_lib_for_shared"],
327 whole_archive_deps_for_static = [":whole_static_lib_for_static"],
Jingwen Chen53681ef2021-04-29 08:15:13 +0000328)`},
329 },
Lukacs T. Berki1353e592021-04-30 15:35:09 +0200330 {
331 description: "cc_library non-configured version script",
332 moduleTypeUnderTest: "cc_library",
333 moduleTypeUnderTestFactory: cc.LibraryFactory,
334 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
335 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
336 dir: "foo/bar",
337 filesystem: map[string]string{
338 "foo/bar/Android.bp": `
339cc_library {
340 name: "a",
341 srcs: ["a.cpp"],
342 version_script: "v.map",
343 bazel_module: { bp2build_available: true },
344}
345`,
346 },
347 bp: soongCcLibraryPreamble,
348 expectedBazelTargets: []string{`cc_library(
349 name = "a",
350 copts = ["-Ifoo/bar"],
351 srcs = ["a.cpp"],
352 version_script = "v.map",
353)`},
354 },
Rupert Shuttleworthc50fa8d2021-05-06 02:40:33 -0400355 {
356 description: "cc_library shared_libs",
357 moduleTypeUnderTest: "cc_library",
358 moduleTypeUnderTestFactory: cc.LibraryFactory,
359 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
360 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
361 dir: "foo/bar",
362 filesystem: map[string]string{
363 "foo/bar/Android.bp": `
364cc_library {
365 name: "mylib",
366 bazel_module: { bp2build_available: true },
367}
368
369cc_library {
370 name: "a",
371 shared_libs: ["mylib",],
372 bazel_module: { bp2build_available: true },
373}
374`,
375 },
376 bp: soongCcLibraryPreamble,
377 expectedBazelTargets: []string{`cc_library(
378 name = "a",
379 copts = ["-Ifoo/bar"],
380 dynamic_deps = [":mylib"],
381)`, `cc_library(
382 name = "mylib",
383 copts = ["-Ifoo/bar"],
384)`},
385 },
Rupert Shuttleworth143be942021-05-09 23:55:51 -0400386 {
387 description: "cc_library pack_relocations test",
388 moduleTypeUnderTest: "cc_library",
389 moduleTypeUnderTestFactory: cc.LibraryFactory,
390 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
391 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
392 dir: "foo/bar",
393 filesystem: map[string]string{
394 "foo/bar/Android.bp": `
395cc_library {
396 name: "a",
397 srcs: ["a.cpp"],
398 pack_relocations: false,
399 bazel_module: { bp2build_available: true },
400}
401
402cc_library {
403 name: "b",
404 srcs: ["b.cpp"],
405 arch: {
406 x86_64: {
407 pack_relocations: false,
408 },
409 },
410 bazel_module: { bp2build_available: true },
411}
412
413cc_library {
414 name: "c",
415 srcs: ["c.cpp"],
416 target: {
417 darwin: {
418 pack_relocations: false,
419 },
420 },
421 bazel_module: { bp2build_available: true },
422}`,
423 },
424 bp: soongCcLibraryPreamble,
425 expectedBazelTargets: []string{`cc_library(
426 name = "a",
427 copts = ["-Ifoo/bar"],
428 linkopts = ["-Wl,--pack-dyn-relocs=none"],
429 srcs = ["a.cpp"],
430)`, `cc_library(
431 name = "b",
432 copts = ["-Ifoo/bar"],
433 linkopts = select({
434 "//build/bazel/platforms/arch:x86_64": ["-Wl,--pack-dyn-relocs=none"],
435 "//conditions:default": [],
436 }),
437 srcs = ["b.cpp"],
438)`, `cc_library(
439 name = "c",
440 copts = ["-Ifoo/bar"],
441 linkopts = select({
442 "//build/bazel/platforms/os:darwin": ["-Wl,--pack-dyn-relocs=none"],
443 "//conditions:default": [],
444 }),
445 srcs = ["c.cpp"],
446)`},
447 },
Jingwen Chen3950cd62021-05-12 04:33:00 +0000448 {
449 description: "cc_library spaces in copts",
450 moduleTypeUnderTest: "cc_library",
451 moduleTypeUnderTestFactory: cc.LibraryFactory,
452 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
453 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
454 dir: "foo/bar",
455 filesystem: map[string]string{
456 "foo/bar/Android.bp": `
457cc_library {
458 name: "a",
459 cflags: ["-include header.h",],
460 bazel_module: { bp2build_available: true },
461}
462`,
463 },
464 bp: soongCcLibraryPreamble,
465 expectedBazelTargets: []string{`cc_library(
466 name = "a",
467 copts = [
468 "-include",
469 "header.h",
470 "-Ifoo/bar",
471 ],
472)`},
473 },
Jingwen Chen75be1ca2021-05-12 05:04:58 +0000474 {
475 description: "cc_library cppflags goes into copts",
476 moduleTypeUnderTest: "cc_library",
477 moduleTypeUnderTestFactory: cc.LibraryFactory,
478 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
479 depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
480 dir: "foo/bar",
481 filesystem: map[string]string{
482 "foo/bar/Android.bp": `cc_library {
483 name: "a",
484 srcs: ["a.cpp"],
485 cflags: [
486 "-Wall",
487 ],
488 cppflags: [
489 "-fsigned-char",
490 "-pedantic",
491 ],
492 arch: {
493 arm64: {
494 cppflags: ["-DARM64=1"],
495 },
496 },
497 target: {
498 android: {
499 cppflags: ["-DANDROID=1"],
500 },
501 },
502 bazel_module: { bp2build_available: true },
503}
504`,
505 },
506 bp: soongCcLibraryPreamble,
507 expectedBazelTargets: []string{`cc_library(
508 name = "a",
509 copts = [
510 "-Wall",
511 "-fsigned-char",
512 "-pedantic",
513 "-Ifoo/bar",
514 ] + select({
515 "//build/bazel/platforms/arch:arm64": ["-DARM64=1"],
516 "//conditions:default": [],
517 }) + select({
518 "//build/bazel/platforms/os:android": ["-DANDROID=1"],
519 "//conditions:default": [],
520 }),
521 srcs = ["a.cpp"],
522)`},
523 },
Jingwen Chen63930982021-03-24 10:04:33 -0400524 }
525
526 dir := "."
527 for _, testCase := range testCases {
528 filesystem := make(map[string][]byte)
529 toParse := []string{
530 "Android.bp",
531 }
532 for f, content := range testCase.filesystem {
533 if strings.HasSuffix(f, "Android.bp") {
534 toParse = append(toParse, f)
535 }
536 filesystem[f] = []byte(content)
537 }
538 config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
539 ctx := android.NewTestContext(config)
540
541 cc.RegisterCCBuildComponents(ctx)
Jingwen Chen53681ef2021-04-29 08:15:13 +0000542 ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
Jingwen Chen63930982021-03-24 10:04:33 -0400543 ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
544 ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
545 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
546 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
547 ctx.RegisterBp2BuildConfig(bp2buildConfig) // TODO(jingwen): make this the default for all tests
Jingwen Chen53681ef2021-04-29 08:15:13 +0000548 for _, m := range testCase.depsMutators {
549 ctx.DepsBp2BuildMutators(m)
550 }
Jingwen Chen63930982021-03-24 10:04:33 -0400551 ctx.RegisterForBazelConversion()
552
553 _, errs := ctx.ParseFileList(dir, toParse)
554 if Errored(t, testCase.description, errs) {
555 continue
556 }
557 _, errs = ctx.ResolveDependencies(config)
558 if Errored(t, testCase.description, errs) {
559 continue
560 }
561
562 checkDir := dir
563 if testCase.dir != "" {
564 checkDir = testCase.dir
565 }
566 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
567 bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
568 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
569 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
570 } else {
571 for i, target := range bazelTargets {
572 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
573 t.Errorf(
574 "%s: Expected generated Bazel target to be '%s', got '%s'",
575 testCase.description,
576 w,
577 g,
578 )
579 }
580 }
581 }
582 }
583}