blob: 901f458251f46ae3fc280dd931a2b33b7f6d635f [file] [log] [blame]
Colin Cross33b2fb72019-05-14 14:07:01 -07001// Copyright 2019 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 (
Colin Cross0c66bc62021-07-20 09:47:41 -070018 "runtime"
Colin Cross33b2fb72019-05-14 14:07:01 -070019 "testing"
20
21 "android/soong/android"
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxc3b97c32021-10-05 13:43:23 -040022 "android/soong/bazel/cquery"
Martin Stjernholm5bdf2d52022-02-06 22:07:45 +000023
Colin Cross33b2fb72019-05-14 14:07:01 -070024 "github.com/google/blueprint"
25)
26
Paul Duffin8567f222021-03-23 00:02:06 +000027var prepareForPrebuiltTest = android.GroupFixturePreparers(
28 prepareForCcTest,
Paul Duffin6a1160e2021-03-07 15:47:42 +000029 android.PrepareForTestWithAndroidMk,
30)
Martin Stjernholmadeb0882020-04-01 23:02:57 +010031
Paul Duffin6a1160e2021-03-07 15:47:42 +000032func testPrebuilt(t *testing.T, bp string, fs android.MockFS, handlers ...android.FixturePreparer) *android.TestContext {
Martin Stjernholm5bdf2d52022-02-06 22:07:45 +000033 t.Helper()
Paul Duffin8567f222021-03-23 00:02:06 +000034 result := android.GroupFixturePreparers(
35 prepareForPrebuiltTest,
Paul Duffin6a1160e2021-03-07 15:47:42 +000036 fs.AddToFixture(),
Paul Duffin8567f222021-03-23 00:02:06 +000037 android.GroupFixturePreparers(handlers...),
38 ).RunTestWithBp(t, bp)
Martin Stjernholmadeb0882020-04-01 23:02:57 +010039
Paul Duffin6a1160e2021-03-07 15:47:42 +000040 return result.TestContext
Martin Stjernholmadeb0882020-04-01 23:02:57 +010041}
42
Evgenii Stepanov2080bfe2020-07-24 15:35:40 -070043type configCustomizer func(config android.Config)
44
Colin Cross33b2fb72019-05-14 14:07:01 -070045func TestPrebuilt(t *testing.T) {
46 bp := `
47 cc_library {
48 name: "liba",
49 }
50
51 cc_prebuilt_library_shared {
52 name: "liba",
53 srcs: ["liba.so"],
54 }
55
56 cc_library {
57 name: "libb",
58 }
59
60 cc_prebuilt_library_static {
61 name: "libb",
62 srcs: ["libb.a"],
63 }
64
65 cc_library_shared {
66 name: "libd",
67 }
68
69 cc_prebuilt_library_shared {
70 name: "libd",
71 srcs: ["libd.so"],
72 }
73
74 cc_library_static {
75 name: "libe",
76 }
77
78 cc_prebuilt_library_static {
79 name: "libe",
80 srcs: ["libe.a"],
81 }
Paul Duffinbce90da2020-03-12 20:17:14 +000082
83 cc_library {
84 name: "libf",
85 }
86
87 cc_prebuilt_library {
88 name: "libf",
89 static: {
90 srcs: ["libf.a"],
91 },
92 shared: {
93 srcs: ["libf.so"],
94 },
95 }
Martin Stjernholm0b92ac82020-03-11 21:45:49 +000096
97 cc_object {
98 name: "crtx",
99 }
100
101 cc_prebuilt_object {
102 name: "crtx",
103 srcs: ["crtx.o"],
104 }
Colin Cross33b2fb72019-05-14 14:07:01 -0700105 `
106
Martin Stjernholmadeb0882020-04-01 23:02:57 +0100107 ctx := testPrebuilt(t, bp, map[string][]byte{
108 "liba.so": nil,
109 "libb.a": nil,
110 "libd.so": nil,
111 "libe.a": nil,
112 "libf.a": nil,
113 "libf.so": nil,
114 "crtx.o": nil,
115 })
Colin Cross33b2fb72019-05-14 14:07:01 -0700116
117 // Verify that all the modules exist and that their dependencies were connected correctly
Colin Cross7113d202019-11-20 16:39:12 -0800118 liba := ctx.ModuleForTests("liba", "android_arm64_armv8-a_shared").Module()
119 libb := ctx.ModuleForTests("libb", "android_arm64_armv8-a_static").Module()
120 libd := ctx.ModuleForTests("libd", "android_arm64_armv8-a_shared").Module()
121 libe := ctx.ModuleForTests("libe", "android_arm64_armv8-a_static").Module()
Paul Duffinbce90da2020-03-12 20:17:14 +0000122 libfStatic := ctx.ModuleForTests("libf", "android_arm64_armv8-a_static").Module()
123 libfShared := ctx.ModuleForTests("libf", "android_arm64_armv8-a_shared").Module()
Martin Stjernholm0b92ac82020-03-11 21:45:49 +0000124 crtx := ctx.ModuleForTests("crtx", "android_arm64_armv8-a").Module()
Colin Cross33b2fb72019-05-14 14:07:01 -0700125
Colin Cross7113d202019-11-20 16:39:12 -0800126 prebuiltLiba := ctx.ModuleForTests("prebuilt_liba", "android_arm64_armv8-a_shared").Module()
127 prebuiltLibb := ctx.ModuleForTests("prebuilt_libb", "android_arm64_armv8-a_static").Module()
128 prebuiltLibd := ctx.ModuleForTests("prebuilt_libd", "android_arm64_armv8-a_shared").Module()
129 prebuiltLibe := ctx.ModuleForTests("prebuilt_libe", "android_arm64_armv8-a_static").Module()
Paul Duffinbce90da2020-03-12 20:17:14 +0000130 prebuiltLibfStatic := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_static").Module()
131 prebuiltLibfShared := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_shared").Module()
Martin Stjernholm0b92ac82020-03-11 21:45:49 +0000132 prebuiltCrtx := ctx.ModuleForTests("prebuilt_crtx", "android_arm64_armv8-a").Module()
Colin Cross33b2fb72019-05-14 14:07:01 -0700133
134 hasDep := func(m android.Module, wantDep android.Module) bool {
135 t.Helper()
136 var found bool
137 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
138 if dep == wantDep {
139 found = true
140 }
141 })
142 return found
143 }
144
145 if !hasDep(liba, prebuiltLiba) {
146 t.Errorf("liba missing dependency on prebuilt_liba")
147 }
148
149 if !hasDep(libb, prebuiltLibb) {
150 t.Errorf("libb missing dependency on prebuilt_libb")
151 }
152
153 if !hasDep(libd, prebuiltLibd) {
154 t.Errorf("libd missing dependency on prebuilt_libd")
155 }
156
157 if !hasDep(libe, prebuiltLibe) {
158 t.Errorf("libe missing dependency on prebuilt_libe")
159 }
Paul Duffinbce90da2020-03-12 20:17:14 +0000160
161 if !hasDep(libfStatic, prebuiltLibfStatic) {
162 t.Errorf("libf static missing dependency on prebuilt_libf")
163 }
164
165 if !hasDep(libfShared, prebuiltLibfShared) {
166 t.Errorf("libf shared missing dependency on prebuilt_libf")
167 }
Martin Stjernholm0b92ac82020-03-11 21:45:49 +0000168
169 if !hasDep(crtx, prebuiltCrtx) {
170 t.Errorf("crtx missing dependency on prebuilt_crtx")
171 }
Paul Duffinbce90da2020-03-12 20:17:14 +0000172}
173
Paul Duffinbce90da2020-03-12 20:17:14 +0000174func TestPrebuiltLibraryShared(t *testing.T) {
175 ctx := testPrebuilt(t, `
176 cc_prebuilt_library_shared {
177 name: "libtest",
178 srcs: ["libf.so"],
179 strip: {
180 none: true,
181 },
182 }
Martin Stjernholmadeb0882020-04-01 23:02:57 +0100183 `, map[string][]byte{
184 "libf.so": nil,
185 })
Paul Duffinbce90da2020-03-12 20:17:14 +0000186
187 shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
Yo Chianga3ad9b22020-03-18 14:19:07 +0800188 assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
Paul Duffinbce90da2020-03-12 20:17:14 +0000189}
190
191func TestPrebuiltLibraryStatic(t *testing.T) {
192 ctx := testPrebuilt(t, `
193 cc_prebuilt_library_static {
194 name: "libtest",
195 srcs: ["libf.a"],
196 }
Martin Stjernholmadeb0882020-04-01 23:02:57 +0100197 `, map[string][]byte{
198 "libf.a": nil,
199 })
Paul Duffinbce90da2020-03-12 20:17:14 +0000200
201 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
Yo Chianga3ad9b22020-03-18 14:19:07 +0800202 assertString(t, static.OutputFile().Path().Base(), "libf.a")
Paul Duffinbce90da2020-03-12 20:17:14 +0000203}
204
205func TestPrebuiltLibrary(t *testing.T) {
206 ctx := testPrebuilt(t, `
207 cc_prebuilt_library {
208 name: "libtest",
209 static: {
210 srcs: ["libf.a"],
211 },
212 shared: {
213 srcs: ["libf.so"],
214 },
215 strip: {
216 none: true,
217 },
218 }
Martin Stjernholmadeb0882020-04-01 23:02:57 +0100219 `, map[string][]byte{
220 "libf.a": nil,
221 "libf.so": nil,
222 })
Paul Duffinbce90da2020-03-12 20:17:14 +0000223
224 shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
Yo Chianga3ad9b22020-03-18 14:19:07 +0800225 assertString(t, shared.OutputFile().Path().Base(), "libtest.so")
Paul Duffinbce90da2020-03-12 20:17:14 +0000226
227 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
Yo Chianga3ad9b22020-03-18 14:19:07 +0800228 assertString(t, static.OutputFile().Path().Base(), "libf.a")
229}
230
231func TestPrebuiltLibraryStem(t *testing.T) {
232 ctx := testPrebuilt(t, `
233 cc_prebuilt_library {
234 name: "libfoo",
235 stem: "libbar",
236 static: {
237 srcs: ["libfoo.a"],
238 },
239 shared: {
240 srcs: ["libfoo.so"],
241 },
242 strip: {
243 none: true,
244 },
245 }
246 `, map[string][]byte{
247 "libfoo.a": nil,
248 "libfoo.so": nil,
249 })
250
251 static := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module)
252 assertString(t, static.OutputFile().Path().Base(), "libfoo.a")
253
254 shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
255 assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
256}
257
258func TestPrebuiltLibrarySharedStem(t *testing.T) {
259 ctx := testPrebuilt(t, `
260 cc_prebuilt_library_shared {
261 name: "libfoo",
262 stem: "libbar",
263 srcs: ["libfoo.so"],
264 strip: {
265 none: true,
266 },
267 }
268 `, map[string][]byte{
269 "libfoo.so": nil,
270 })
271
272 shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module)
273 assertString(t, shared.OutputFile().Path().Base(), "libbar.so")
Colin Cross33b2fb72019-05-14 14:07:01 -0700274}
Martin Stjernholm837ee1a2020-08-20 02:54:52 +0100275
276func TestPrebuiltSymlinkedHostBinary(t *testing.T) {
Colin Cross0c66bc62021-07-20 09:47:41 -0700277 if runtime.GOOS != "linux" {
278 t.Skipf("Skipping host prebuilt testing that is only supported on linux not %s", runtime.GOOS)
Martin Stjernholm6a9a1462020-09-15 02:56:19 +0100279 }
280
Martin Stjernholm837ee1a2020-08-20 02:54:52 +0100281 ctx := testPrebuilt(t, `
282 cc_prebuilt_library_shared {
283 name: "libfoo",
284 device_supported: false,
285 host_supported: true,
286 target: {
287 linux_glibc_x86_64: {
288 srcs: ["linux_glibc_x86_64/lib64/libfoo.so"],
289 },
290 },
291 }
292
293 cc_prebuilt_binary {
294 name: "foo",
295 device_supported: false,
296 host_supported: true,
297 shared_libs: ["libfoo"],
298 target: {
299 linux_glibc_x86_64: {
300 srcs: ["linux_glibc_x86_64/bin/foo"],
301 },
302 },
303 }
304 `, map[string][]byte{
305 "libfoo.so": nil,
306 "foo": nil,
307 })
308
309 fooRule := ctx.ModuleForTests("foo", "linux_glibc_x86_64").Rule("Symlink")
Paul Duffine8366da2021-03-24 10:40:38 +0000310 assertString(t, fooRule.Output.String(), "out/soong/.intermediates/foo/linux_glibc_x86_64/foo")
Martin Stjernholm837ee1a2020-08-20 02:54:52 +0100311 assertString(t, fooRule.Args["fromPath"], "$$PWD/linux_glibc_x86_64/bin/foo")
312
313 var libfooDep android.Path
314 for _, dep := range fooRule.Implicits {
315 if dep.Base() == "libfoo.so" {
316 libfooDep = dep
317 break
318 }
319 }
Paul Duffine8366da2021-03-24 10:40:38 +0000320 assertString(t, libfooDep.String(), "out/soong/.intermediates/libfoo/linux_glibc_x86_64_shared/libfoo.so")
Martin Stjernholm837ee1a2020-08-20 02:54:52 +0100321}
Evgenii Stepanov2080bfe2020-07-24 15:35:40 -0700322
323func TestPrebuiltLibrarySanitized(t *testing.T) {
324 bp := `cc_prebuilt_library {
325 name: "libtest",
326 static: {
327 sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, },
328 },
329 shared: {
330 sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, },
331 },
332 }
333 cc_prebuilt_library_static {
334 name: "libtest_static",
335 sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, },
336 }
337 cc_prebuilt_library_shared {
338 name: "libtest_shared",
339 sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, },
340 }`
341
342 fs := map[string][]byte{
343 "libf.a": nil,
344 "libf.hwasan.a": nil,
345 "libf.so": nil,
346 "hwasan/libf.so": nil,
347 }
348
349 // Without SANITIZE_TARGET.
350 ctx := testPrebuilt(t, bp, fs)
351
352 shared_rule := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
353 assertString(t, shared_rule.Input.String(), "libf.so")
354
355 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
356 assertString(t, static.OutputFile().Path().Base(), "libf.a")
357
358 shared_rule2 := ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip")
359 assertString(t, shared_rule2.Input.String(), "libf.so")
360
361 static2 := ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static").Module().(*Module)
362 assertString(t, static2.OutputFile().Path().Base(), "libf.a")
363
364 // With SANITIZE_TARGET=hwaddress
Paul Duffin6a1160e2021-03-07 15:47:42 +0000365 ctx = testPrebuilt(t, bp, fs,
366 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
367 variables.SanitizeDevice = []string{"hwaddress"}
368 }),
369 )
Evgenii Stepanov2080bfe2020-07-24 15:35:40 -0700370
371 shared_rule = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
372 assertString(t, shared_rule.Input.String(), "hwasan/libf.so")
373
374 static = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
375 assertString(t, static.OutputFile().Path().Base(), "libf.hwasan.a")
376
377 shared_rule2 = ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip")
378 assertString(t, shared_rule2.Input.String(), "hwasan/libf.so")
379
380 static2 = ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module)
381 assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a")
382}
Alex Márquez Pérez Muñíz Díaz Púras Thaureauxc3b97c32021-10-05 13:43:23 -0400383
384func TestPrebuiltLibrarySharedWithBazelWithoutToc(t *testing.T) {
385 const bp = `
386cc_prebuilt_library_shared {
387 name: "foo",
388 srcs: ["foo.so"],
389 bazel_module: { label: "//foo/bar:bar" },
390}`
391 outBaseDir := "outputbase"
392 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
393 config.BazelContext = android.MockBazelContext{
394 OutputBaseDir: outBaseDir,
395 LabelToCcInfo: map[string]cquery.CcInfo{
396 "//foo/bar:bar": cquery.CcInfo{
397 CcSharedLibraryFiles: []string{"foo.so"},
398 },
399 },
400 }
401 ctx := testCcWithConfig(t, config)
402 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
403 pathPrefix := outBaseDir + "/execroot/__main__/"
404
405 info := ctx.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
406 android.AssertPathRelativeToTopEquals(t, "prebuilt shared library",
407 pathPrefix+"foo.so", info.SharedLibrary)
408 android.AssertPathRelativeToTopEquals(t, "prebuilt's 'nullary' ToC",
409 pathPrefix+"foo.so", info.TableOfContents.Path())
410
411 outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
412 if err != nil {
413 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
414 }
415 expectedOutputFiles := []string{pathPrefix + "foo.so"}
416 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
417}
418
419func TestPrebuiltLibrarySharedWithBazelWithToc(t *testing.T) {
420 const bp = `
421cc_prebuilt_library_shared {
422 name: "foo",
423 srcs: ["foo.so"],
424 bazel_module: { label: "//foo/bar:bar" },
425}`
426 outBaseDir := "outputbase"
427 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
428 config.BazelContext = android.MockBazelContext{
429 OutputBaseDir: outBaseDir,
430 LabelToCcInfo: map[string]cquery.CcInfo{
431 "//foo/bar:bar": cquery.CcInfo{
432 CcSharedLibraryFiles: []string{"foo.so"},
433 TocFile: "toc",
434 },
435 },
436 }
437 ctx := testCcWithConfig(t, config)
438 sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
439 pathPrefix := outBaseDir + "/execroot/__main__/"
440
441 info := ctx.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
442 android.AssertPathRelativeToTopEquals(t, "prebuilt shared library's ToC",
443 pathPrefix+"toc", info.TableOfContents.Path())
444 android.AssertPathRelativeToTopEquals(t, "prebuilt shared library",
445 pathPrefix+"foo.so", info.SharedLibrary)
446
447 outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
448 if err != nil {
449 t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
450 }
451 expectedOutputFiles := []string{pathPrefix + "foo.so"}
452 android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
453}
Martin Stjernholm5bdf2d52022-02-06 22:07:45 +0000454
455func TestPrebuiltStubNoinstall(t *testing.T) {
456 testFunc := func(t *testing.T, bp string) {
457 result := android.GroupFixturePreparers(
458 prepareForPrebuiltTest,
459 android.PrepareForTestWithMakevars,
460 ).RunTestWithBp(t, bp)
461
462 installRules := result.InstallMakeRulesForTesting(t)
463 var installedlibRule *android.InstallMakeRule
464 for i, rule := range installRules {
465 if rule.Target == "out/target/product/test_device/system/lib/installedlib.so" {
466 if installedlibRule != nil {
467 t.Errorf("Duplicate install rules for %s", rule.Target)
468 }
469 installedlibRule = &installRules[i]
470 }
471 }
472 if installedlibRule == nil {
473 t.Errorf("No install rule found for installedlib")
474 return
475 }
476
477 android.AssertStringListDoesNotContain(t,
478 "installedlib has install dependency on stub",
479 installedlibRule.Deps,
480 "out/target/product/test_device/system/lib/stublib.so")
481 android.AssertStringListDoesNotContain(t,
482 "installedlib has order-only install dependency on stub",
483 installedlibRule.OrderOnlyDeps,
484 "out/target/product/test_device/system/lib/stublib.so")
485 }
486
487 const prebuiltStublibBp = `
488 cc_prebuilt_library {
489 name: "stublib",
490 prefer: true,
491 srcs: ["foo.so"],
492 stubs: {
493 versions: ["1"],
494 },
495 }
496 `
497
498 const installedlibBp = `
499 cc_library {
500 name: "installedlib",
501 shared_libs: ["stublib"],
502 }
503 `
504
505 t.Run("prebuilt without source", func(t *testing.T) {
506 testFunc(t, prebuiltStublibBp+installedlibBp)
507 })
508
509 const disabledSourceStublibBp = `
510 cc_library {
511 name: "stublib",
512 enabled: false,
513 stubs: {
514 versions: ["1"],
515 },
516 }
517 `
518
519 t.Run("prebuilt with disabled source", func(t *testing.T) {
520 testFunc(t, disabledSourceStublibBp+prebuiltStublibBp+installedlibBp)
521 })
522}