blob: f6558422fd7341acd7aab8668ae0dbc7b45dd344 [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"],
102 // TODO(b/178130668): handle configurable attributes that depend on the platform
103 arch: {
104 x86: {
105 cflags: ["-fPIC"],
106 },
107 x86_64: {
108 cflags: ["-fPIC"],
109 },
110 },
111}
112
113cc_defaults {
114 name: "foo_bar_defaults",
115 cflags: [
116 "-Wno-gcc-compat",
117 "-Wall",
118 "-Werror",
119 ],
120}
121`,
122 expectedBazelTargets: []string{`cc_object(
123 name = "foo",
124 copts = [
125 "-Wno-gcc-compat",
126 "-Wall",
127 "-Werror",
128 "-fno-addrsig",
129 ],
130 local_include_dirs = [
131 "include",
132 ],
133 srcs = [
134 "a/b/c.c",
135 ],
136)`,
137 },
138 },
Jingwen Chendb120242021-02-23 00:46:47 -0500139 {
140 description: "cc_object with cc_object deps in objs props",
141 moduleTypeUnderTest: "cc_object",
142 moduleTypeUnderTestFactory: cc.ObjectFactory,
143 moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
144 filesystem: map[string]string{
145 "a/b/c.c": "",
146 "x/y/z.c": "",
147 },
148 blueprint: `cc_object {
149 name: "foo",
150 srcs: ["a/b/c.c"],
151 objs: ["bar"],
152
153 bazel_module: { bp2build_available: true },
154}
155
156cc_object {
157 name: "bar",
158 srcs: ["x/y/z.c"],
159
160 bazel_module: { bp2build_available: true },
161}
162`,
163 expectedBazelTargets: []string{`cc_object(
164 name = "bar",
165 copts = [
166 "-fno-addrsig",
167 ],
168 srcs = [
169 "x/y/z.c",
170 ],
171)`, `cc_object(
172 name = "foo",
173 copts = [
174 "-fno-addrsig",
175 ],
176 deps = [
177 ":bar",
178 ],
179 srcs = [
180 "a/b/c.c",
181 ],
182)`,
183 },
184 },
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500185 }
186
187 dir := "."
188 for _, testCase := range testCases {
189 filesystem := make(map[string][]byte)
190 toParse := []string{
191 "Android.bp",
192 }
193 for f, content := range testCase.filesystem {
194 if strings.HasSuffix(f, "Android.bp") {
195 toParse = append(toParse, f)
196 }
197 filesystem[f] = []byte(content)
198 }
199 config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
200 ctx := android.NewTestContext(config)
201 // Always register cc_defaults module factory
202 ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
203
204 ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
205 ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
206 ctx.RegisterForBazelConversion()
207
208 _, errs := ctx.ParseFileList(dir, toParse)
209 if Errored(t, testCase.description, errs) {
210 continue
211 }
212 _, errs = ctx.ResolveDependencies(config)
213 if Errored(t, testCase.description, errs) {
214 continue
215 }
216
Jingwen Chen164e0862021-02-19 00:48:40 -0500217 codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
Jingwen Chenba369ad2021-02-22 10:19:34 -0500218 bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
Jingwen Chen8c1b97e2021-02-18 03:21:34 -0500219 if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
220 fmt.Println(bazelTargets)
221 t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
222 } else {
223 for i, target := range bazelTargets {
224 if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
225 t.Errorf(
226 "%s: Expected generated Bazel target to be '%s', got '%s'",
227 testCase.description,
228 w,
229 g,
230 )
231 }
232 }
233 }
234 }
235}