blob: 7bf5fd3e4cde56b0bdc56c204b2312f71d5e5e71 [file] [log] [blame]
Rupert Shuttleworth095081c2021-03-25 09:06:03 +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 soongCcLibraryStaticPreamble = `
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 TestCcLibraryStaticLoadStatement(t *testing.T) {
55 testCases := []struct {
56 bazelTargets BazelTargets
57 expectedLoadStatements string
58 }{
59 {
60 bazelTargets: BazelTargets{
61 BazelTarget{
62 name: "cc_library_static_target",
63 ruleClass: "cc_library_static",
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 TestCcLibraryStaticBp2Build(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_static test",
96 moduleTypeUnderTest: "cc_library_static",
97 moduleTypeUnderTestFactory: cc.LibraryStaticFactory,
98 moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build,
99 filesystem: map[string]string{
100 // NOTE: include_dir headers *should not* appear in Bazel hdrs later (?)
101 "include_dir_1/include_dir_1_a.h": "",
102 "include_dir_1/include_dir_1_b.h": "",
103 "include_dir_2/include_dir_2_a.h": "",
104 "include_dir_2/include_dir_2_b.h": "",
105 // NOTE: local_include_dir headers *should not* appear in Bazel hdrs later (?)
106 "local_include_dir_1/local_include_dir_1_a.h": "",
107 "local_include_dir_1/local_include_dir_1_b.h": "",
108 "local_include_dir_2/local_include_dir_2_a.h": "",
109 "local_include_dir_2/local_include_dir_2_b.h": "",
110 // NOTE: export_include_dir headers *should* appear in Bazel hdrs later
111 "export_include_dir_1/export_include_dir_1_a.h": "",
112 "export_include_dir_1/export_include_dir_1_b.h": "",
113 "export_include_dir_2/export_include_dir_2_a.h": "",
114 "export_include_dir_2/export_include_dir_2_b.h": "",
115 },
116 bp: soongCcLibraryStaticPreamble + `
117cc_library_headers {
118 name: "header_lib_1",
119 export_include_dirs: ["header_lib_1"],
120}
121
122cc_library_headers {
123 name: "header_lib_2",
124 export_include_dirs: ["header_lib_2"],
125}
126
127cc_library_static {
128 name: "static_lib_1",
129 srcs: ["static_lib_1.cc"],
130 bazel_module: { bp2build_available: true },
131}
132
133cc_library_static {
134 name: "static_lib_2",
135 srcs: ["static_lib_2.cc"],
136 bazel_module: { bp2build_available: true },
137}
138
139cc_library_static {
140 name: "whole_static_lib_1",
141 srcs: ["whole_static_lib_1.cc"],
142 bazel_module: { bp2build_available: true },
143}
144
145cc_library_static {
146 name: "whole_static_lib_2",
147 srcs: ["whole_static_lib_2.cc"],
148 bazel_module: { bp2build_available: true },
149}
150
151cc_library_static {
152 name: "foo_static",
153 srcs: [
154 "foo_static1.cc",
155 "foo_static2.cc",
156 ],
157 cflags: [
158 "-Dflag1",
159 "-Dflag2"
160 ],
161 static_libs: [
162 "static_lib_1",
163 "static_lib_2"
164 ],
165 whole_static_libs: [
166 "whole_static_lib_1",
167 "whole_static_lib_2"
168 ],
169 include_dirs: [
170 "include_dir_1",
171 "include_dir_2",
172 ],
173 local_include_dirs: [
174 "local_include_dir_1",
175 "local_include_dir_2",
176 ],
177 export_include_dirs: [
178 "export_include_dir_1",
179 "export_include_dir_2"
180 ],
181 header_libs: [
182 "header_lib_1",
183 "header_lib_2"
184 ],
185
186 // TODO: Also support export_header_lib_headers
187
188 bazel_module: { bp2build_available: true },
189}`,
190 expectedBazelTargets: []string{`cc_library_static(
191 name = "foo_static",
192 copts = [
193 "-Dflag1",
194 "-Dflag2",
195 ],
196 deps = [
197 ":header_lib_1",
198 ":header_lib_2",
199 ":static_lib_1",
200 ":static_lib_2",
201 ":whole_static_lib_1",
202 ":whole_static_lib_2",
203 ],
204 hdrs = [
205 "export_include_dir_1/export_include_dir_1_a.h",
206 "export_include_dir_1/export_include_dir_1_b.h",
207 "export_include_dir_2/export_include_dir_2_a.h",
208 "export_include_dir_2/export_include_dir_2_b.h",
209 ],
210 includes = [
211 "export_include_dir_1",
212 "export_include_dir_2",
213 "include_dir_1",
214 "include_dir_2",
215 "local_include_dir_1",
216 "local_include_dir_2",
217 ],
218 linkstatic = True,
219 srcs = [
220 "foo_static1.cc",
221 "foo_static2.cc",
222 ],
223)`, `cc_library_static(
224 name = "static_lib_1",
225 linkstatic = True,
226 srcs = [
227 "static_lib_1.cc",
228 ],
229)`, `cc_library_static(
230 name = "static_lib_2",
231 linkstatic = True,
232 srcs = [
233 "static_lib_2.cc",
234 ],
235)`, `cc_library_static(
236 name = "whole_static_lib_1",
237 linkstatic = True,
238 srcs = [
239 "whole_static_lib_1.cc",
240 ],
241)`, `cc_library_static(
242 name = "whole_static_lib_2",
243 linkstatic = True,
244 srcs = [
245 "whole_static_lib_2.cc",
246 ],
247)`},
248 },
249 }
250
251 dir := "."
252 for _, testCase := range testCases {
253 filesystem := make(map[string][]byte)
254 toParse := []string{
255 "Android.bp",
256 }
257 for f, content := range testCase.filesystem {
258 if strings.HasSuffix(f, "Android.bp") {
259 toParse = append(toParse, f)
260 }
261 filesystem[f] = []byte(content)
262 }
263 config := android.TestConfig(buildDir, nil, testCase.bp, filesystem)
264 ctx := android.NewTestContext(config)
265
266 cc.RegisterCCBuildComponents(ctx)
267 ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
268 ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
269
270 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
271 for _, m := range testCase.depsMutators {
272 ctx.DepsBp2BuildMutators(m)
273 }
274 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
275 ctx.RegisterForBazelConversion()
276
277 _, errs := ctx.ParseFileList(dir, toParse)
278 if Errored(t, testCase.description, errs) {
279 continue
280 }
281 _, errs = ctx.ResolveDependencies(config)
282 if Errored(t, testCase.description, errs) {
283 continue
284 }
285
286 checkDir := dir
287 if testCase.dir != "" {
288 checkDir = testCase.dir
289 }
290 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
291 bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
292 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
293 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
294 } else {
295 for i, target := range bazelTargets {
296 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
297 t.Errorf(
298 "%s: Expected generated Bazel target to be '%s', got '%s'",
299 testCase.description,
300 w,
301 g,
302 )
303 }
304 }
305 }
306 }
307}