blob: d9cd22dab1c10a350d78af2e9ae823d8da1d5d80 [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
53 }{
54 {
55 description: "cc_library - simple example",
56 moduleTypeUnderTest: "cc_library",
57 moduleTypeUnderTestFactory: cc.LibraryFactory,
58 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
59 filesystem: map[string]string{
60 "android.cpp": "",
61 "darwin.cpp": "",
62 // Refer to cc.headerExts for the supported header extensions in Soong.
63 "header.h": "",
64 "header.hh": "",
65 "header.hpp": "",
66 "header.hxx": "",
67 "header.h++": "",
68 "header.inl": "",
69 "header.inc": "",
70 "header.ipp": "",
71 "header.h.generic": "",
72 "impl.cpp": "",
73 "linux.cpp": "",
74 "x86.cpp": "",
75 "x86_64.cpp": "",
76 "foo-dir/a.h": "",
77 },
78 bp: soongCcLibraryPreamble + `
79cc_library_headers { name: "some-headers" }
80cc_library {
81 name: "foo-lib",
82 srcs: ["impl.cpp"],
83 cflags: ["-Wall"],
84 header_libs: ["some-headers"],
85 export_include_dirs: ["foo-dir"],
86 ldflags: ["-Wl,--exclude-libs=bar.a"],
87 arch: {
88 x86: {
89 ldflags: ["-Wl,--exclude-libs=baz.a"],
90 srcs: ["x86.cpp"],
91 },
92 x86_64: {
93 ldflags: ["-Wl,--exclude-libs=qux.a"],
94 srcs: ["x86_64.cpp"],
95 },
96 },
97 target: {
98 android: {
99 srcs: ["android.cpp"],
100 },
101 linux_glibc: {
102 srcs: ["linux.cpp"],
103 },
104 darwin: {
105 srcs: ["darwin.cpp"],
106 },
107 },
108}
109`,
110 expectedBazelTargets: []string{`cc_library(
111 name = "foo-lib",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000112 copts = [
113 "-Wall",
114 "-I.",
115 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000116 deps = [":some-headers"],
Jingwen Chened9c17d2021-04-13 07:14:55 +0000117 includes = ["foo-dir"],
118 linkopts = ["-Wl,--exclude-libs=bar.a"] + select({
119 "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=baz.a"],
120 "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=qux.a"],
121 "//conditions:default": [],
122 }),
Jingwen Chen882bcc12021-04-27 05:54:20 +0000123 srcs = ["impl.cpp"] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000124 "//build/bazel/platforms/arch:x86": ["x86.cpp"],
125 "//build/bazel/platforms/arch:x86_64": ["x86_64.cpp"],
Jingwen Chen63930982021-03-24 10:04:33 -0400126 "//conditions:default": [],
127 }) + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000128 "//build/bazel/platforms/os:android": ["android.cpp"],
129 "//build/bazel/platforms/os:darwin": ["darwin.cpp"],
130 "//build/bazel/platforms/os:linux": ["linux.cpp"],
Jingwen Chen63930982021-03-24 10:04:33 -0400131 "//conditions:default": [],
132 }),
133)`},
134 },
135 {
136 description: "cc_library - trimmed example of //bionic/linker:ld-android",
137 moduleTypeUnderTest: "cc_library",
138 moduleTypeUnderTestFactory: cc.LibraryFactory,
139 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
140 filesystem: map[string]string{
141 "ld-android.cpp": "",
142 "linked_list.h": "",
143 "linker.h": "",
144 "linker_block_allocator.h": "",
145 "linker_cfi.h": "",
146 },
147 bp: soongCcLibraryPreamble + `
148cc_library_headers { name: "libc_headers" }
149cc_library {
150 name: "fake-ld-android",
151 srcs: ["ld_android.cpp"],
152 cflags: [
153 "-Wall",
154 "-Wextra",
155 "-Wunused",
156 "-Werror",
157 ],
158 header_libs: ["libc_headers"],
159 ldflags: [
160 "-Wl,--exclude-libs=libgcc.a",
161 "-Wl,--exclude-libs=libgcc_stripped.a",
162 "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
163 "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
164 "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
165 "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
166 ],
167 arch: {
168 x86: {
169 ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
170 },
171 x86_64: {
172 ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
173 },
174 },
175}
176`,
177 expectedBazelTargets: []string{`cc_library(
178 name = "fake-ld-android",
179 copts = [
180 "-Wall",
181 "-Wextra",
182 "-Wunused",
183 "-Werror",
Jingwen Chened9c17d2021-04-13 07:14:55 +0000184 "-I.",
Jingwen Chen63930982021-03-24 10:04:33 -0400185 ],
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000186 deps = [":libc_headers"],
Jingwen Chen63930982021-03-24 10:04:33 -0400187 linkopts = [
188 "-Wl,--exclude-libs=libgcc.a",
189 "-Wl,--exclude-libs=libgcc_stripped.a",
190 "-Wl,--exclude-libs=libclang_rt.builtins-arm-android.a",
191 "-Wl,--exclude-libs=libclang_rt.builtins-aarch64-android.a",
192 "-Wl,--exclude-libs=libclang_rt.builtins-i686-android.a",
193 "-Wl,--exclude-libs=libclang_rt.builtins-x86_64-android.a",
194 ] + select({
Jingwen Chenb4628eb2021-04-08 14:40:57 +0000195 "//build/bazel/platforms/arch:x86": ["-Wl,--exclude-libs=libgcc_eh.a"],
196 "//build/bazel/platforms/arch:x86_64": ["-Wl,--exclude-libs=libgcc_eh.a"],
Jingwen Chen63930982021-03-24 10:04:33 -0400197 "//conditions:default": [],
198 }),
Jingwen Chen882bcc12021-04-27 05:54:20 +0000199 srcs = ["ld_android.cpp"],
Jingwen Chen63930982021-03-24 10:04:33 -0400200)`},
201 },
Jingwen Chen4ecc67d2021-04-27 09:47:02 +0000202 {
203 description: "cc_library exclude_srcs - trimmed example of //external/arm-optimized-routines:libarm-optimized-routines-math",
204 moduleTypeUnderTest: "cc_library",
205 moduleTypeUnderTestFactory: cc.LibraryFactory,
206 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
207 dir: "external",
208 filesystem: map[string]string{
209 "external/math/cosf.c": "",
210 "external/math/erf.c": "",
211 "external/math/erf_data.c": "",
212 "external/math/erff.c": "",
213 "external/math/erff_data.c": "",
214 "external/Android.bp": `
215cc_library {
216 name: "fake-libarm-optimized-routines-math",
217 exclude_srcs: [
218 // Provided by:
219 // bionic/libm/upstream-freebsd/lib/msun/src/s_erf.c
220 // bionic/libm/upstream-freebsd/lib/msun/src/s_erff.c
221 "math/erf.c",
222 "math/erf_data.c",
223 "math/erff.c",
224 "math/erff_data.c",
225 ],
226 srcs: [
227 "math/*.c",
228 ],
229 // arch-specific settings
230 arch: {
231 arm64: {
232 cflags: [
233 "-DHAVE_FAST_FMA=1",
234 ],
235 },
236 },
237 bazel_module: { bp2build_available: true },
238}
239`,
240 },
241 bp: soongCcLibraryPreamble,
242 expectedBazelTargets: []string{`cc_library(
243 name = "fake-libarm-optimized-routines-math",
244 copts = ["-Iexternal"] + select({
245 "//build/bazel/platforms/arch:arm64": ["-DHAVE_FAST_FMA=1"],
246 "//conditions:default": [],
247 }),
248 srcs = ["math/cosf.c"],
249)`},
250 },
Jingwen Chen63930982021-03-24 10:04:33 -0400251 }
252
253 dir := "."
254 for _, testCase := range testCases {
255 filesystem := make(map[string][]byte)
256 toParse := []string{
257 "Android.bp",
258 }
259 for f, content := range testCase.filesystem {
260 if strings.HasSuffix(f, "Android.bp") {
261 toParse = append(toParse, f)
262 }
263 filesystem[f] = []byte(content)
264 }
265 config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
266 ctx := android.NewTestContext(config)
267
268 cc.RegisterCCBuildComponents(ctx)
269 ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
270 ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
271 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
272 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
273 ctx.RegisterBp2BuildConfig(bp2buildConfig) // TODO(jingwen): make this the default for all tests
274 ctx.RegisterForBazelConversion()
275
276 _, errs := ctx.ParseFileList(dir, toParse)
277 if Errored(t, testCase.description, errs) {
278 continue
279 }
280 _, errs = ctx.ResolveDependencies(config)
281 if Errored(t, testCase.description, errs) {
282 continue
283 }
284
285 checkDir := dir
286 if testCase.dir != "" {
287 checkDir = testCase.dir
288 }
289 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
290 bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
291 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
292 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
293 } else {
294 for i, target := range bazelTargets {
295 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
296 t.Errorf(
297 "%s: Expected generated Bazel target to be '%s', got '%s'",
298 testCase.description,
299 w,
300 g,
301 )
302 }
303 }
304 }
305 }
306}