blob: 7427b597409497f595b65c08b4775c49a33ff952 [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"},
Chris Parsons94a0bba2021-06-04 15:03:47 -0400260 RootDynamicLibraries: []string{"foo.so"},
261 },
Chris Parsons77acf2e2021-12-03 17:27:16 -0500262 "//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
263 CcObjectFiles: []string{"foo.o"},
264 Includes: []string{"include"},
265 SystemIncludes: []string{"system_include"},
266 RootStaticArchives: []string{"foo.a"},
267 },
Chris Parsons94a0bba2021-06-04 15:03:47 -0400268 },
269 }
270 ctx := testCcWithConfig(t, config)
271
272 staticFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
273 outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
274 if err != nil {
275 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
276 }
277
278 expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.a"}
279 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
280
281 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
282 outputFiles, err = sharedFoo.(android.OutputFileProducer).OutputFiles("")
283 if err != nil {
284 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
285 }
286 expectedOutputFiles = []string{"outputbase/execroot/__main__/foo.so"}
287 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
288
289 entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
290 expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
291 gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
292 android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
293}
Colin Cross59422382021-07-22 16:35:24 -0700294
295func TestLibraryVersionScript(t *testing.T) {
296 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
297 cc_library {
298 name: "libfoo",
299 srcs: ["foo.c"],
300 version_script: "foo.map.txt",
301 }`)
302
303 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
304
305 android.AssertStringListContains(t, "missing dependency on version_script",
306 libfoo.Implicits.Strings(), "foo.map.txt")
307 android.AssertStringDoesContain(t, "missing flag for version_script",
308 libfoo.Args["ldFlags"], "-Wl,--version-script,foo.map.txt")
309
310}
311
312func TestLibraryDynamicList(t *testing.T) {
313 result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
314 cc_library {
315 name: "libfoo",
316 srcs: ["foo.c"],
317 dynamic_list: "foo.dynamic.txt",
318 }`)
319
320 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("ld")
321
322 android.AssertStringListContains(t, "missing dependency on dynamic_list",
323 libfoo.Implicits.Strings(), "foo.dynamic.txt")
324 android.AssertStringDoesContain(t, "missing flag for dynamic_list",
325 libfoo.Args["ldFlags"], "-Wl,--dynamic-list,foo.dynamic.txt")
326
327}
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000328
329func TestCcLibrarySharedWithBazel(t *testing.T) {
330 bp := `
331cc_library_shared {
332 name: "foo",
333 srcs: ["foo.cc"],
334 bazel_module: { label: "//foo/bar:bar" },
335}`
336 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
337 config.BazelContext = android.MockBazelContext{
338 OutputBaseDir: "outputbase",
339 LabelToCcInfo: map[string]cquery.CcInfo{
340 "//foo/bar:bar": cquery.CcInfo{
341 CcObjectFiles: []string{"foo.o"},
342 Includes: []string{"include"},
343 SystemIncludes: []string{"system_include"},
344 RootDynamicLibraries: []string{"foo.so"},
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux62585e82021-09-14 21:19:31 +0000345 TocFile: "foo.so.toc",
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000346 },
347 },
348 }
349 ctx := testCcWithConfig(t, config)
350
351 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 +0000352 producer := sharedFoo.(android.OutputFileProducer)
353 outputFiles, err := producer.OutputFiles("")
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000354 if err != nil {
355 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
356 }
357 expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"}
358 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
359
Alex Márquez Pérez Muñíz Díaz Púras Thaureaux62585e82021-09-14 21:19:31 +0000360 tocFilePath := sharedFoo.(*Module).Toc()
361 if !tocFilePath.Valid() {
362 t.Errorf("Invalid tocFilePath: %s", tocFilePath)
363 }
364 tocFile := tocFilePath.Path()
365 expectedToc := "outputbase/execroot/__main__/foo.so.toc"
366 android.AssertStringEquals(t, "toc file", expectedToc, tocFile.String())
367
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxbc4e7342021-09-14 20:58:25 +0000368 entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
369 expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
370 gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
371 android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
372}