blob: cce28b0f8d352376f1b2fd57a7c0ffe9247d5563 [file] [log] [blame]
Colin Cross0fce0ba2021-01-08 16:40:12 -08001// 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 cc
16
17import (
18 "android/soong/android"
19 "fmt"
20 "path/filepath"
Colin Cross2e577f32021-01-22 13:06:25 -080021 "reflect"
Colin Cross0fce0ba2021-01-08 16:40:12 -080022 "strings"
23 "testing"
24)
25
26func TestVendorSnapshotCapture(t *testing.T) {
27 bp := `
28 cc_library {
29 name: "libvndk",
30 vendor_available: true,
31 product_available: true,
32 vndk: {
33 enabled: true,
34 },
35 nocrt: true,
36 }
37
38 cc_library {
39 name: "libvendor",
40 vendor: true,
41 nocrt: true,
42 }
43
44 cc_library {
45 name: "libvendor_available",
46 vendor_available: true,
47 nocrt: true,
48 }
49
50 cc_library_headers {
51 name: "libvendor_headers",
52 vendor_available: true,
53 nocrt: true,
54 }
55
56 cc_binary {
57 name: "vendor_bin",
58 vendor: true,
59 nocrt: true,
60 }
61
62 cc_binary {
63 name: "vendor_available_bin",
64 vendor_available: true,
65 nocrt: true,
66 }
67
68 toolchain_library {
69 name: "libb",
70 vendor_available: true,
71 src: "libb.a",
72 }
73
74 cc_object {
75 name: "obj",
76 vendor_available: true,
77 }
78
79 cc_library {
80 name: "libllndk",
81 llndk_stubs: "libllndk.llndk",
82 }
83
84 llndk_library {
85 name: "libllndk.llndk",
86 symbol_file: "",
87 }
88`
89 config := TestConfig(buildDir, android.Android, nil, bp, nil)
90 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
91 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
92 ctx := testCcWithConfig(t, config)
93
94 // Check Vendor snapshot output.
95
96 snapshotDir := "vendor-snapshot"
97 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
98 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
99
100 var jsonFiles []string
101
102 for _, arch := range [][]string{
103 []string{"arm64", "armv8-a"},
104 []string{"arm", "armv7-a-neon"},
105 } {
106 archType := arch[0]
107 archVariant := arch[1]
108 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
109
110 // For shared libraries, only non-VNDK vendor_available modules are captured
111 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
112 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
113 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
114 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
115 jsonFiles = append(jsonFiles,
116 filepath.Join(sharedDir, "libvendor.so.json"),
117 filepath.Join(sharedDir, "libvendor_available.so.json"))
118
119 // LLNDK modules are not captured
120 checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
121
122 // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
123 // Also cfi variants are captured, except for prebuilts like toolchain_library
124 staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
125 staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant)
126 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
127 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
128 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
129 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
130 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
131 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
132 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
133 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
134 jsonFiles = append(jsonFiles,
135 filepath.Join(staticDir, "libb.a.json"),
136 filepath.Join(staticDir, "libvndk.a.json"),
137 filepath.Join(staticDir, "libvndk.cfi.a.json"),
138 filepath.Join(staticDir, "libvendor.a.json"),
139 filepath.Join(staticDir, "libvendor.cfi.a.json"),
140 filepath.Join(staticDir, "libvendor_available.a.json"),
141 filepath.Join(staticDir, "libvendor_available.cfi.a.json"))
142
143 // For binary executables, all vendor:true and vendor_available modules are captured.
144 if archType == "arm64" {
145 binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
146 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
147 checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
148 checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
149 jsonFiles = append(jsonFiles,
150 filepath.Join(binaryDir, "vendor_bin.json"),
151 filepath.Join(binaryDir, "vendor_available_bin.json"))
152 }
153
154 // For header libraries, all vendor:true and vendor_available modules are captured.
155 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
156 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json"))
157
158 // For object modules, all vendor:true and vendor_available modules are captured.
159 objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
160 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
161 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
162 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
163 }
164
165 for _, jsonFile := range jsonFiles {
166 // verify all json files exist
167 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
168 t.Errorf("%q expected but not found", jsonFile)
169 }
170 }
171
172 // fake snapshot should have all outputs in the normal snapshot.
173 fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
174 for _, output := range snapshotSingleton.AllOutputs() {
175 fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
176 if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
177 t.Errorf("%q expected but not found", fakeOutput)
178 }
179 }
180}
181
182func TestVendorSnapshotDirected(t *testing.T) {
183 bp := `
184 cc_library_shared {
185 name: "libvendor",
186 vendor: true,
187 nocrt: true,
188 }
189
190 cc_library_shared {
191 name: "libvendor_available",
192 vendor_available: true,
193 nocrt: true,
194 }
195
196 genrule {
197 name: "libfoo_gen",
198 cmd: "",
199 out: ["libfoo.so"],
200 }
201
202 cc_prebuilt_library_shared {
203 name: "libfoo",
204 vendor: true,
205 prefer: true,
206 srcs: [":libfoo_gen"],
207 }
208
209 cc_library_shared {
210 name: "libfoo",
211 vendor: true,
212 nocrt: true,
213 }
214`
215 config := TestConfig(buildDir, android.Android, nil, bp, nil)
216 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
217 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
218 config.TestProductVariables.DirectedVendorSnapshot = true
219 config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
220 config.TestProductVariables.VendorSnapshotModules["libvendor"] = true
221 config.TestProductVariables.VendorSnapshotModules["libfoo"] = true
222 ctx := testCcWithConfig(t, config)
223
224 // Check Vendor snapshot output.
225
226 snapshotDir := "vendor-snapshot"
227 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
228 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
229
230 var includeJsonFiles []string
231 var excludeJsonFiles []string
232
233 for _, arch := range [][]string{
234 []string{"arm64", "armv8-a"},
235 []string{"arm", "armv7-a-neon"},
236 } {
237 archType := arch[0]
238 archVariant := arch[1]
239 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
240
241 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
242 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
243
244 // Included modules
245 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
246 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
247 // Check that snapshot captures "prefer: true" prebuilt
248 checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
249 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
250
251 // Excluded modules
252 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
253 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json"))
254 }
255
256 // Verify that each json file for an included module has a rule.
257 for _, jsonFile := range includeJsonFiles {
258 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
259 t.Errorf("include json file %q not found", jsonFile)
260 }
261 }
262
263 // Verify that each json file for an excluded module has no rule.
264 for _, jsonFile := range excludeJsonFiles {
265 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
266 t.Errorf("exclude json file %q found", jsonFile)
267 }
268 }
269}
270
271func TestVendorSnapshotUse(t *testing.T) {
272 frameworkBp := `
273 cc_library {
274 name: "libvndk",
275 vendor_available: true,
276 product_available: true,
277 vndk: {
278 enabled: true,
279 },
280 nocrt: true,
281 compile_multilib: "64",
282 }
283
284 cc_library {
285 name: "libvendor",
286 vendor: true,
287 nocrt: true,
288 no_libcrt: true,
289 stl: "none",
290 system_shared_libs: [],
291 compile_multilib: "64",
292 }
293
Colin Cross2e577f32021-01-22 13:06:25 -0800294 cc_library {
295 name: "libvendor_available",
296 vendor_available: true,
297 nocrt: true,
298 no_libcrt: true,
299 stl: "none",
300 system_shared_libs: [],
301 compile_multilib: "64",
302 }
303
Colin Cross0fce0ba2021-01-08 16:40:12 -0800304 cc_binary {
305 name: "bin",
306 vendor: true,
307 nocrt: true,
308 no_libcrt: true,
309 stl: "none",
310 system_shared_libs: [],
311 compile_multilib: "64",
312 }
313`
314
315 vndkBp := `
316 vndk_prebuilt_shared {
317 name: "libvndk",
318 version: "BOARD",
319 target_arch: "arm64",
320 vendor_available: true,
321 product_available: true,
322 vndk: {
323 enabled: true,
324 },
325 arch: {
326 arm64: {
327 srcs: ["libvndk.so"],
328 export_include_dirs: ["include/libvndk"],
329 },
330 },
331 }
332`
333
334 vendorProprietaryBp := `
335 cc_library {
336 name: "libvendor_without_snapshot",
337 vendor: true,
338 nocrt: true,
339 no_libcrt: true,
340 stl: "none",
341 system_shared_libs: [],
342 compile_multilib: "64",
343 }
344
345 cc_library_shared {
346 name: "libclient",
347 vendor: true,
348 nocrt: true,
349 no_libcrt: true,
350 stl: "none",
351 system_shared_libs: [],
Colin Cross2e577f32021-01-22 13:06:25 -0800352 shared_libs: ["libvndk", "libvendor_available"],
Colin Cross0fce0ba2021-01-08 16:40:12 -0800353 static_libs: ["libvendor", "libvendor_without_snapshot"],
354 compile_multilib: "64",
355 srcs: ["client.cpp"],
356 }
357
358 cc_binary {
359 name: "bin_without_snapshot",
360 vendor: true,
361 nocrt: true,
362 no_libcrt: true,
363 stl: "none",
364 system_shared_libs: [],
365 static_libs: ["libvndk"],
366 compile_multilib: "64",
367 srcs: ["bin.cpp"],
368 }
369
370 vendor_snapshot_static {
371 name: "libvndk",
372 version: "BOARD",
373 target_arch: "arm64",
374 vendor: true,
375 arch: {
376 arm64: {
377 src: "libvndk.a",
378 export_include_dirs: ["include/libvndk"],
379 },
380 },
381 }
382
383 vendor_snapshot_shared {
384 name: "libvendor",
385 version: "BOARD",
386 target_arch: "arm64",
387 vendor: true,
388 arch: {
389 arm64: {
390 src: "libvendor.so",
391 export_include_dirs: ["include/libvendor"],
392 },
393 },
394 }
395
396 vendor_snapshot_static {
397 name: "libvendor",
398 version: "BOARD",
399 target_arch: "arm64",
400 vendor: true,
401 arch: {
402 arm64: {
403 src: "libvendor.a",
404 export_include_dirs: ["include/libvendor"],
405 },
406 },
407 }
408
Colin Cross2e577f32021-01-22 13:06:25 -0800409 vendor_snapshot_shared {
410 name: "libvendor_available",
411 version: "BOARD",
412 target_arch: "arm64",
413 vendor: true,
414 arch: {
415 arm64: {
416 src: "libvendor_available.so",
417 export_include_dirs: ["include/libvendor"],
418 },
419 },
420 }
421
422 vendor_snapshot_static {
423 name: "libvendor_available",
424 version: "BOARD",
425 target_arch: "arm64",
426 vendor: true,
427 arch: {
428 arm64: {
429 src: "libvendor_available.a",
430 export_include_dirs: ["include/libvendor"],
431 },
432 },
433 }
434
Colin Cross0fce0ba2021-01-08 16:40:12 -0800435 vendor_snapshot_binary {
436 name: "bin",
437 version: "BOARD",
438 target_arch: "arm64",
439 vendor: true,
440 arch: {
441 arm64: {
442 src: "bin",
443 },
444 },
445 }
446`
447 depsBp := GatherRequiredDepsForTest(android.Android)
448
449 mockFS := map[string][]byte{
450 "deps/Android.bp": []byte(depsBp),
451 "framework/Android.bp": []byte(frameworkBp),
452 "vendor/Android.bp": []byte(vendorProprietaryBp),
453 "vendor/bin": nil,
454 "vendor/bin.cpp": nil,
455 "vendor/client.cpp": nil,
456 "vendor/include/libvndk/a.h": nil,
457 "vendor/include/libvendor/b.h": nil,
458 "vendor/libvndk.a": nil,
459 "vendor/libvendor.a": nil,
460 "vendor/libvendor.so": nil,
461 "vndk/Android.bp": []byte(vndkBp),
462 "vndk/include/libvndk/a.h": nil,
463 "vndk/libvndk.so": nil,
464 }
465
466 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
467 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
468 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
469 ctx := CreateTestContext(config)
470 ctx.Register()
471
472 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"})
473 android.FailIfErrored(t, errs)
474 _, errs = ctx.PrepareBuildActions(config)
475 android.FailIfErrored(t, errs)
476
477 sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared"
478 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
479 binaryVariant := "android_vendor.BOARD_arm64_armv8-a"
480
481 // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot
482 libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
483 for _, includeFlags := range []string{
484 "-Ivndk/include/libvndk", // libvndk
485 "-Ivendor/include/libvendor", // libvendor
486 } {
487 if !strings.Contains(libclientCcFlags, includeFlags) {
488 t.Errorf("flags for libclient must contain %#v, but was %#v.",
489 includeFlags, libclientCcFlags)
490 }
491 }
492
493 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
494 for _, input := range [][]string{
495 []string{sharedVariant, "libvndk.vndk.BOARD.arm64"},
496 []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"},
497 []string{staticVariant, "libvendor_without_snapshot"},
498 } {
499 outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
500 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
501 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
502 }
503 }
504
Colin Cross2e577f32021-01-22 13:06:25 -0800505 libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
506 if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor"}; !reflect.DeepEqual(g, w) {
507 t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
508 }
509
510 libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
511 if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) {
512 t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
513 }
514
Colin Cross0fce0ba2021-01-08 16:40:12 -0800515 // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64
516 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
517 if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
518 t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
519 "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
520 }
521
522 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
523 libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"})
524 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
525 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
526 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
527 }
528
529 // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64
530 ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so")
531
Colin Cross2e577f32021-01-22 13:06:25 -0800532 // libvendor_available.so is installed by libvendor_available.vendor_shared.BOARD.arm64
533 ctx.ModuleForTests("libvendor_available.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor_available.so")
534
Colin Cross0fce0ba2021-01-08 16:40:12 -0800535 // libvendor_without_snapshot.so is installed by libvendor_without_snapshot
536 ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
537
538 // bin is installed by bin.vendor_binary.BOARD.arm64
539 ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin")
540
541 // bin_without_snapshot is installed by bin_without_snapshot
542 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
543
Colin Cross2e577f32021-01-22 13:06:25 -0800544 // libvendor, libvendor_available and bin don't have vendor.BOARD variant
Colin Cross0fce0ba2021-01-08 16:40:12 -0800545 libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
546 if inList(sharedVariant, libvendorVariants) {
547 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
548 }
549
Colin Cross2e577f32021-01-22 13:06:25 -0800550 libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
551 if inList(sharedVariant, libvendorAvailableVariants) {
552 t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
553 }
554
Colin Cross0fce0ba2021-01-08 16:40:12 -0800555 binVariants := ctx.ModuleVariantsForTests("bin")
556 if inList(binaryVariant, binVariants) {
557 t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
558 }
559}
560
561func TestVendorSnapshotSanitizer(t *testing.T) {
562 bp := `
563 vendor_snapshot_static {
564 name: "libsnapshot",
565 vendor: true,
566 target_arch: "arm64",
567 version: "BOARD",
568 arch: {
569 arm64: {
570 src: "libsnapshot.a",
571 cfi: {
572 src: "libsnapshot.cfi.a",
573 }
574 },
575 },
576 }
577`
578 config := TestConfig(buildDir, android.Android, nil, bp, nil)
579 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
580 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
581 ctx := testCcWithConfig(t, config)
582
583 // Check non-cfi and cfi variant.
584 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
585 staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
586
587 staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
588 assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
589
590 staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
591 assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
592}
593
594func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
595 t.Helper()
596 m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
597 if m.ExcludeFromVendorSnapshot() != expected {
598 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
599 }
600}
601
602func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
603 t.Helper()
604 m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module)
605 if m.ExcludeFromRecoverySnapshot() != expected {
606 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
607 }
608}
609
610func TestVendorSnapshotExclude(t *testing.T) {
611
612 // This test verifies that the exclude_from_vendor_snapshot property
613 // makes its way from the Android.bp source file into the module data
614 // structure. It also verifies that modules are correctly included or
615 // excluded in the vendor snapshot based on their path (framework or
616 // vendor) and the exclude_from_vendor_snapshot property.
617
618 frameworkBp := `
619 cc_library_shared {
620 name: "libinclude",
621 srcs: ["src/include.cpp"],
622 vendor_available: true,
623 }
624 cc_library_shared {
625 name: "libexclude",
626 srcs: ["src/exclude.cpp"],
627 vendor: true,
628 exclude_from_vendor_snapshot: true,
629 }
630 cc_library_shared {
631 name: "libavailable_exclude",
632 srcs: ["src/exclude.cpp"],
633 vendor_available: true,
634 exclude_from_vendor_snapshot: true,
635 }
636 `
637
638 vendorProprietaryBp := `
639 cc_library_shared {
640 name: "libvendor",
641 srcs: ["vendor.cpp"],
642 vendor: true,
643 }
644 `
645
646 depsBp := GatherRequiredDepsForTest(android.Android)
647
648 mockFS := map[string][]byte{
649 "deps/Android.bp": []byte(depsBp),
650 "framework/Android.bp": []byte(frameworkBp),
651 "framework/include.cpp": nil,
652 "framework/exclude.cpp": nil,
653 "device/Android.bp": []byte(vendorProprietaryBp),
654 "device/vendor.cpp": nil,
655 }
656
657 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
658 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
659 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
660 ctx := CreateTestContext(config)
661 ctx.Register()
662
663 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
664 android.FailIfErrored(t, errs)
665 _, errs = ctx.PrepareBuildActions(config)
666 android.FailIfErrored(t, errs)
667
668 // Test an include and exclude framework module.
669 assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false)
670 assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true)
671 assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true)
672
673 // A vendor module is excluded, but by its path, not the
674 // exclude_from_vendor_snapshot property.
675 assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false)
676
677 // Verify the content of the vendor snapshot.
678
679 snapshotDir := "vendor-snapshot"
680 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
681 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
682
683 var includeJsonFiles []string
684 var excludeJsonFiles []string
685
686 for _, arch := range [][]string{
687 []string{"arm64", "armv8-a"},
688 []string{"arm", "armv7-a-neon"},
689 } {
690 archType := arch[0]
691 archVariant := arch[1]
692 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
693
694 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
695 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
696
697 // Included modules
698 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
699 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
700
701 // Excluded modules
702 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
703 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
704 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
705 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
706 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
707 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
708 }
709
710 // Verify that each json file for an included module has a rule.
711 for _, jsonFile := range includeJsonFiles {
712 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
713 t.Errorf("include json file %q not found", jsonFile)
714 }
715 }
716
717 // Verify that each json file for an excluded module has no rule.
718 for _, jsonFile := range excludeJsonFiles {
719 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
720 t.Errorf("exclude json file %q found", jsonFile)
721 }
722 }
723}
724
725func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
726
727 // This test verifies that using the exclude_from_vendor_snapshot
728 // property on a module in a vendor proprietary path generates an
729 // error. These modules are already excluded, so we prohibit using the
730 // property in this way, which could add to confusion.
731
732 vendorProprietaryBp := `
733 cc_library_shared {
734 name: "libvendor",
735 srcs: ["vendor.cpp"],
736 vendor: true,
737 exclude_from_vendor_snapshot: true,
738 }
739 `
740
741 depsBp := GatherRequiredDepsForTest(android.Android)
742
743 mockFS := map[string][]byte{
744 "deps/Android.bp": []byte(depsBp),
745 "device/Android.bp": []byte(vendorProprietaryBp),
746 "device/vendor.cpp": nil,
747 }
748
749 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
750 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
751 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
752 ctx := CreateTestContext(config)
753 ctx.Register()
754
755 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"})
756 android.FailIfErrored(t, errs)
757
758 _, errs = ctx.PrepareBuildActions(config)
759 android.CheckErrorsAgainstExpectations(t, errs, []string{
760 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
761 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
762 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
763 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
764 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
765 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
766 })
767}
768
769func TestRecoverySnapshotCapture(t *testing.T) {
770 bp := `
771 cc_library {
772 name: "libvndk",
773 vendor_available: true,
774 recovery_available: true,
775 product_available: true,
776 vndk: {
777 enabled: true,
778 },
779 nocrt: true,
780 }
781
782 cc_library {
783 name: "librecovery",
784 recovery: true,
785 nocrt: true,
786 }
787
788 cc_library {
789 name: "librecovery_available",
790 recovery_available: true,
791 nocrt: true,
792 }
793
794 cc_library_headers {
795 name: "librecovery_headers",
796 recovery_available: true,
797 nocrt: true,
798 }
799
800 cc_binary {
801 name: "recovery_bin",
802 recovery: true,
803 nocrt: true,
804 }
805
806 cc_binary {
807 name: "recovery_available_bin",
808 recovery_available: true,
809 nocrt: true,
810 }
811
812 toolchain_library {
813 name: "libb",
814 recovery_available: true,
815 src: "libb.a",
816 }
817
818 cc_object {
819 name: "obj",
820 recovery_available: true,
821 }
822`
823 config := TestConfig(buildDir, android.Android, nil, bp, nil)
824 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
825 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
826 ctx := testCcWithConfig(t, config)
827
828 // Check Recovery snapshot output.
829
830 snapshotDir := "recovery-snapshot"
831 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
832 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
833
834 var jsonFiles []string
835
836 for _, arch := range [][]string{
837 []string{"arm64", "armv8-a"},
838 } {
839 archType := arch[0]
840 archVariant := arch[1]
841 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
842
843 // For shared libraries, only recovery_available modules are captured.
844 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
845 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
846 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
847 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
848 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
849 jsonFiles = append(jsonFiles,
850 filepath.Join(sharedDir, "libvndk.so.json"),
851 filepath.Join(sharedDir, "librecovery.so.json"),
852 filepath.Join(sharedDir, "librecovery_available.so.json"))
853
854 // For static libraries, all recovery:true and recovery_available modules are captured.
855 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
856 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
857 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
858 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
859 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
860 jsonFiles = append(jsonFiles,
861 filepath.Join(staticDir, "libb.a.json"),
862 filepath.Join(staticDir, "librecovery.a.json"),
863 filepath.Join(staticDir, "librecovery_available.a.json"))
864
865 // For binary executables, all recovery:true and recovery_available modules are captured.
866 if archType == "arm64" {
867 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
868 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
869 checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
870 checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
871 jsonFiles = append(jsonFiles,
872 filepath.Join(binaryDir, "recovery_bin.json"),
873 filepath.Join(binaryDir, "recovery_available_bin.json"))
874 }
875
876 // For header libraries, all vendor:true and vendor_available modules are captured.
877 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
878 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json"))
879
880 // For object modules, all vendor:true and vendor_available modules are captured.
881 objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
882 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
883 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
884 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
885 }
886
887 for _, jsonFile := range jsonFiles {
888 // verify all json files exist
889 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
890 t.Errorf("%q expected but not found", jsonFile)
891 }
892 }
893}
894
895func TestRecoverySnapshotExclude(t *testing.T) {
896 // This test verifies that the exclude_from_recovery_snapshot property
897 // makes its way from the Android.bp source file into the module data
898 // structure. It also verifies that modules are correctly included or
899 // excluded in the recovery snapshot based on their path (framework or
900 // vendor) and the exclude_from_recovery_snapshot property.
901
902 frameworkBp := `
903 cc_library_shared {
904 name: "libinclude",
905 srcs: ["src/include.cpp"],
906 recovery_available: true,
907 }
908 cc_library_shared {
909 name: "libexclude",
910 srcs: ["src/exclude.cpp"],
911 recovery: true,
912 exclude_from_recovery_snapshot: true,
913 }
914 cc_library_shared {
915 name: "libavailable_exclude",
916 srcs: ["src/exclude.cpp"],
917 recovery_available: true,
918 exclude_from_recovery_snapshot: true,
919 }
920 `
921
922 vendorProprietaryBp := `
923 cc_library_shared {
924 name: "librecovery",
925 srcs: ["recovery.cpp"],
926 recovery: true,
927 }
928 `
929
930 depsBp := GatherRequiredDepsForTest(android.Android)
931
932 mockFS := map[string][]byte{
933 "deps/Android.bp": []byte(depsBp),
934 "framework/Android.bp": []byte(frameworkBp),
935 "framework/include.cpp": nil,
936 "framework/exclude.cpp": nil,
937 "device/Android.bp": []byte(vendorProprietaryBp),
938 "device/recovery.cpp": nil,
939 }
940
941 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
942 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
943 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
944 ctx := CreateTestContext(config)
945 ctx.Register()
946
947 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
948 android.FailIfErrored(t, errs)
949 _, errs = ctx.PrepareBuildActions(config)
950 android.FailIfErrored(t, errs)
951
952 // Test an include and exclude framework module.
953 assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false)
954 assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true)
955 assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true)
956
957 // A recovery module is excluded, but by its path, not the
958 // exclude_from_recovery_snapshot property.
959 assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false)
960
961 // Verify the content of the recovery snapshot.
962
963 snapshotDir := "recovery-snapshot"
964 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
965 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
966
967 var includeJsonFiles []string
968 var excludeJsonFiles []string
969
970 for _, arch := range [][]string{
971 []string{"arm64", "armv8-a"},
972 } {
973 archType := arch[0]
974 archVariant := arch[1]
975 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
976
977 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
978 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
979
980 // Included modules
981 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
982 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
983
984 // Excluded modules
985 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
986 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
987 checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
988 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
989 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
990 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
991 }
992
993 // Verify that each json file for an included module has a rule.
994 for _, jsonFile := range includeJsonFiles {
995 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
996 t.Errorf("include json file %q not found", jsonFile)
997 }
998 }
999
1000 // Verify that each json file for an excluded module has no rule.
1001 for _, jsonFile := range excludeJsonFiles {
1002 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
1003 t.Errorf("exclude json file %q found", jsonFile)
1004 }
1005 }
1006}