blob: 7ddfaa7fd61391ff927195eb9d57470f91065753 [file] [log] [blame]
Colin Crossad59e752017-11-16 14:29:11 -08001// Copyright 2017 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 cc
16
17import (
18 "reflect"
19 "testing"
Jooyung Hanaed150d2020-04-02 01:41:41 +090020
21 "android/soong/android"
Chris Parsons94a0bba2021-06-04 15:03:47 -040022 "android/soong/bazel/cquery"
Colin Crossad59e752017-11-16 14:29:11 -080023)
24
25func TestLibraryReuse(t *testing.T) {
26 t.Run("simple", func(t *testing.T) {
27 ctx := testCc(t, `
28 cc_library {
29 name: "libfoo",
Pete Bentleyfcf55bf2019-08-16 20:14:32 +010030 srcs: ["foo.c", "baz.o"],
Colin Crossad59e752017-11-16 14:29:11 -080031 }`)
32
Colin Cross7113d202019-11-20 16:39:12 -080033 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
34 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
Colin Crossad59e752017-11-16 14:29:11 -080035
Pete Bentleyfcf55bf2019-08-16 20:14:32 +010036 if len(libfooShared.Inputs) != 2 {
Colin Crossad59e752017-11-16 14:29:11 -080037 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
38 }
39
Pete Bentleyfcf55bf2019-08-16 20:14:32 +010040 if len(libfooStatic.Inputs) != 2 {
Colin Crossad59e752017-11-16 14:29:11 -080041 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
42 }
43
44 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
45 t.Errorf("static object not reused for shared library")
46 }
Pete Bentleyfcf55bf2019-08-16 20:14:32 +010047 if libfooShared.Inputs[1] != libfooStatic.Inputs[1] {
48 t.Errorf("static object not reused for shared library")
49 }
Colin Crossad59e752017-11-16 14:29:11 -080050 })
51
52 t.Run("extra static source", func(t *testing.T) {
53 ctx := testCc(t, `
54 cc_library {
55 name: "libfoo",
56 srcs: ["foo.c"],
57 static: {
58 srcs: ["bar.c"]
59 },
60 }`)
61
Colin Cross7113d202019-11-20 16:39:12 -080062 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
63 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
Colin Crossad59e752017-11-16 14:29:11 -080064
65 if len(libfooShared.Inputs) != 1 {
66 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
67 }
68
69 if len(libfooStatic.Inputs) != 2 {
70 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
71 }
72
73 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
74 t.Errorf("static object not reused for shared library")
75 }
76 })
77
78 t.Run("extra shared source", func(t *testing.T) {
79 ctx := testCc(t, `
80 cc_library {
81 name: "libfoo",
82 srcs: ["foo.c"],
83 shared: {
84 srcs: ["bar.c"]
85 },
86 }`)
87
Colin Cross7113d202019-11-20 16:39:12 -080088 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
89 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
Colin Crossad59e752017-11-16 14:29:11 -080090
91 if len(libfooShared.Inputs) != 2 {
92 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
93 }
94
95 if len(libfooStatic.Inputs) != 1 {
96 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
97 }
98
99 if libfooShared.Inputs[0] != libfooStatic.Inputs[0] {
100 t.Errorf("static object not reused for shared library")
101 }
102 })
103
104 t.Run("extra static cflags", func(t *testing.T) {
105 ctx := testCc(t, `
106 cc_library {
107 name: "libfoo",
108 srcs: ["foo.c"],
109 static: {
110 cflags: ["-DFOO"],
111 },
112 }`)
113
Colin Cross7113d202019-11-20 16:39:12 -0800114 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
115 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
Colin Crossad59e752017-11-16 14:29:11 -0800116
117 if len(libfooShared.Inputs) != 1 {
118 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
119 }
120
121 if len(libfooStatic.Inputs) != 1 {
122 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
123 }
124
125 if libfooShared.Inputs[0] == libfooStatic.Inputs[0] {
126 t.Errorf("static object reused for shared library when it shouldn't be")
127 }
128 })
129
130 t.Run("extra shared cflags", func(t *testing.T) {
131 ctx := testCc(t, `
132 cc_library {
133 name: "libfoo",
134 srcs: ["foo.c"],
135 shared: {
136 cflags: ["-DFOO"],
137 },
138 }`)
139
Colin Cross7113d202019-11-20 16:39:12 -0800140 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
141 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
Colin Crossad59e752017-11-16 14:29:11 -0800142
143 if len(libfooShared.Inputs) != 1 {
144 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
145 }
146
147 if len(libfooStatic.Inputs) != 1 {
148 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
149 }
150
151 if libfooShared.Inputs[0] == libfooStatic.Inputs[0] {
152 t.Errorf("static object reused for shared library when it shouldn't be")
153 }
154 })
155
156 t.Run("global cflags for reused generated sources", func(t *testing.T) {
157 ctx := testCc(t, `
158 cc_library {
159 name: "libfoo",
160 srcs: [
161 "foo.c",
162 "a.proto",
163 ],
164 shared: {
165 srcs: [
166 "bar.c",
167 ],
168 },
169 }`)
170
Colin Cross7113d202019-11-20 16:39:12 -0800171 libfooShared := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Rule("ld")
172 libfooStatic := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_static").Output("libfoo.a")
Colin Crossad59e752017-11-16 14:29:11 -0800173
174 if len(libfooShared.Inputs) != 3 {
175 t.Fatalf("unexpected inputs to libfoo shared: %#v", libfooShared.Inputs.Strings())
176 }
177
178 if len(libfooStatic.Inputs) != 2 {
179 t.Fatalf("unexpected inputs to libfoo static: %#v", libfooStatic.Inputs.Strings())
180 }
181
182 if !reflect.DeepEqual(libfooShared.Inputs[0:2].Strings(), libfooStatic.Inputs.Strings()) {
183 t.Errorf("static objects not reused for shared library")
184 }
185
Colin Cross7113d202019-11-20 16:39:12 -0800186 libfoo := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_shared").Module().(*Module)
Colin Cross4af21ed2019-11-04 09:37:55 -0800187 if !inList("-DGOOGLE_PROTOBUF_NO_RTTI", libfoo.flags.Local.CFlags) {
Colin Crossad59e752017-11-16 14:29:11 -0800188 t.Errorf("missing protobuf cflags")
189 }
190 })
191}
Jooyung Hanaed150d2020-04-02 01:41:41 +0900192
193func TestStubsVersions(t *testing.T) {
194 bp := `
195 cc_library {
196 name: "libfoo",
197 srcs: ["foo.c"],
198 stubs: {
Dan Albertc8060532020-07-22 22:32:17 -0700199 versions: ["29", "R", "current"],
Jooyung Hanaed150d2020-04-02 01:41:41 +0900200 },
201 }
202 `
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000203 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Hanaed150d2020-04-02 01:41:41 +0900204 config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
205 ctx := testCcWithConfig(t, config)
206
207 variants := ctx.ModuleVariantsForTests("libfoo")
Dan Albertc8060532020-07-22 22:32:17 -0700208 for _, expectedVer := range []string{"29", "R", "current"} {
Jooyung Hanaed150d2020-04-02 01:41:41 +0900209 expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer
210 if !inList(expectedVariant, variants) {
211 t.Errorf("missing expected variant: %q", expectedVariant)
212 }
213 }
214}
215
216func TestStubsVersions_NotSorted(t *testing.T) {
217 bp := `
218 cc_library {
219 name: "libfoo",
220 srcs: ["foo.c"],
221 stubs: {
Dan Albertc8060532020-07-22 22:32:17 -0700222 versions: ["29", "current", "R"],
Jooyung Hanaed150d2020-04-02 01:41:41 +0900223 },
224 }
225 `
Paul Duffinc3e6ce02021-03-22 23:21:32 +0000226 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
Jooyung Hanaed150d2020-04-02 01:41:41 +0900227 config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
228 testCcErrorWithConfig(t, `"libfoo" .*: versions: not sorted`, config)
229}
230
231func TestStubsVersions_ParseError(t *testing.T) {
232 bp := `
233 cc_library {
234 name: "libfoo",
235 srcs: ["foo.c"],
236 stubs: {
Dan Albertc8060532020-07-22 22:32:17 -0700237 versions: ["29", "current", "X"],
Jooyung Hanaed150d2020-04-02 01:41:41 +0900238 },
239 }
240 `
241
Dan Albertc8060532020-07-22 22:32:17 -0700242 testCcError(t, `"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`, bp)
Jooyung Hanaed150d2020-04-02 01:41:41 +0900243}
Chris Parsons94a0bba2021-06-04 15:03:47 -0400244
245func TestCcLibraryWithBazel(t *testing.T) {
246 bp := `
247cc_library {
248 name: "foo",
249 srcs: ["foo.cc"],
250 bazel_module: { label: "//foo/bar:bar" },
251}`
252 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
253 config.BazelContext = android.MockBazelContext{
254 OutputBaseDir: "outputbase",
255 LabelToCcInfo: map[string]cquery.CcInfo{
256 "//foo/bar:bar": cquery.CcInfo{
257 CcObjectFiles: []string{"foo.o"},
258 Includes: []string{"include"},
259 SystemIncludes: []string{"system_include"},
260 RootStaticArchives: []string{"foo.a"},
261 RootDynamicLibraries: []string{"foo.so"},
262 },
263 },
264 }
265 ctx := testCcWithConfig(t, config)
266
267 staticFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
268 outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
269 if err != nil {
270 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
271 }
272
273 expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.a"}
274 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
275
276 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
277 outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("")
278 if err != nil {
279 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
280 }
281 expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"}
282 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
283
284 entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
285 expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
286 gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
287 android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
288}
Colin Cross59422382021-07-22 16:35:24 -0700289
290func TestLibraryVersionScript(t *testing.T) {
291 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
292 cc_library {
293 name: "libfoo",
294 srcs: ["foo.c"],
295 version_script: "foo.map.txt",
296 }`)
297
298 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
299
300 android.AssertStringListContains(t, "missing dependency on version_script",
301 libfoo.Implicits.Strings(), "foo.map.txt")
302 android.AssertStringDoesContain(t, "missing flag for version_script",
303 libfoo.Args["ldFlags"], "-Wl,--version-script,foo.map.txt")
304
305}
306
307func TestLibraryDynamicList(t *testing.T) {
308 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
309 cc_library {
310 name: "libfoo",
311 srcs: ["foo.c"],
312 dynamic_list: "foo.dynamic.txt",
313 }`)
314
315 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
316
317 android.AssertStringListContains(t, "missing dependency on dynamic_list",
318 libfoo.Implicits.Strings(), "foo.dynamic.txt")
319 android.AssertStringDoesContain(t, "missing flag for dynamic_list",
320 libfoo.Args["ldFlags"], "-Wl,--dynamic-list,foo.dynamic.txt")
321
322}
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000323
324func TestCcLibrarySharedWithBazel(t *testing.T) {
325 bp := `
326cc_library_shared {
327 name: "foo",
328 srcs: ["foo.cc"],
329 bazel_module: { label: "//foo/bar:bar" },
330}`
331 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
332 config.BazelContext = android.MockBazelContext{
333 OutputBaseDir: "outputbase",
334 LabelToCcInfo: map[string]cquery.CcInfo{
335 "//foo/bar:bar": cquery.CcInfo{
336 CcObjectFiles: []string{"foo.o"},
337 Includes: []string{"include"},
338 SystemIncludes: []string{"system_include"},
339 RootDynamicLibraries: []string{"foo.so"},
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux62585e82021-09-14 21:19:31 +0000340 TocFile: "foo.so.toc",
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000341 },
342 },
343 }
344 ctx := testCcWithConfig(t, config)
345
346 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux62585e82021-09-14 21:19:31 +0000347 producer := sharedFoo.(android.OutputFileProducer)
348 outputFiles, err := producer.OutputFiles("")
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000349 if err != nil {
350 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
351 }
352 expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"}
353 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
354
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux62585e82021-09-14 21:19:31 +0000355 tocFilePath := sharedFoo.(*Module).Toc()
356 if !tocFilePath.Valid() {
357 t.Errorf("Invalid tocFilePath: %s", tocFilePath)
358 }
359 tocFile := tocFilePath.Path()
360 expectedToc := "outputbase/execroot/__main__/foo.so.toc"
361 android.AssertStringEquals(t, "toc file", expectedToc, tocFile.String())
362
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000363 entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
364 expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
365 gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
366 android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
367}