blob: 39c84f049d9ecea78671399a9860fb7ad7cfee05 [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 }
Colin Crosse0edaf92021-01-11 17:31:17 -0800332
333 // old snapshot module which has to be ignored
334 vndk_prebuilt_shared {
335 name: "libvndk",
336 version: "OLD",
337 target_arch: "arm64",
338 vendor_available: true,
339 product_available: true,
340 vndk: {
341 enabled: true,
342 },
343 arch: {
344 arm64: {
345 srcs: ["libvndk.so"],
346 export_include_dirs: ["include/libvndk"],
347 },
348 },
349 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800350`
351
352 vendorProprietaryBp := `
353 cc_library {
354 name: "libvendor_without_snapshot",
355 vendor: true,
356 nocrt: true,
357 no_libcrt: true,
358 stl: "none",
359 system_shared_libs: [],
360 compile_multilib: "64",
361 }
362
363 cc_library_shared {
364 name: "libclient",
365 vendor: true,
366 nocrt: true,
367 no_libcrt: true,
368 stl: "none",
369 system_shared_libs: [],
Colin Cross2e577f32021-01-22 13:06:25 -0800370 shared_libs: ["libvndk", "libvendor_available"],
Colin Cross0fce0ba2021-01-08 16:40:12 -0800371 static_libs: ["libvendor", "libvendor_without_snapshot"],
372 compile_multilib: "64",
373 srcs: ["client.cpp"],
374 }
375
376 cc_binary {
377 name: "bin_without_snapshot",
378 vendor: true,
379 nocrt: true,
380 no_libcrt: true,
381 stl: "none",
382 system_shared_libs: [],
383 static_libs: ["libvndk"],
384 compile_multilib: "64",
385 srcs: ["bin.cpp"],
386 }
387
Colin Crosse0edaf92021-01-11 17:31:17 -0800388 vendor_snapshot {
389 name: "vendor_snapshot",
390 compile_multilib: "first",
391 version: "BOARD",
392 vndk_libs: [
393 "libvndk",
394 ],
395 static_libs: [
396 "libvendor",
397 "libvendor_available",
398 "libvndk",
399 ],
400 shared_libs: [
401 "libvendor",
402 "libvendor_available",
403 ],
404 binaries: [
405 "bin",
406 ],
407 }
408
Colin Cross0fce0ba2021-01-08 16:40:12 -0800409 vendor_snapshot_static {
410 name: "libvndk",
411 version: "BOARD",
412 target_arch: "arm64",
413 vendor: true,
414 arch: {
415 arm64: {
416 src: "libvndk.a",
417 export_include_dirs: ["include/libvndk"],
418 },
419 },
420 }
421
422 vendor_snapshot_shared {
423 name: "libvendor",
424 version: "BOARD",
425 target_arch: "arm64",
426 vendor: true,
427 arch: {
428 arm64: {
429 src: "libvendor.so",
430 export_include_dirs: ["include/libvendor"],
431 },
432 },
433 }
434
435 vendor_snapshot_static {
436 name: "libvendor",
437 version: "BOARD",
438 target_arch: "arm64",
439 vendor: true,
440 arch: {
441 arm64: {
442 src: "libvendor.a",
443 export_include_dirs: ["include/libvendor"],
444 },
445 },
446 }
447
Colin Cross2e577f32021-01-22 13:06:25 -0800448 vendor_snapshot_shared {
449 name: "libvendor_available",
450 version: "BOARD",
451 target_arch: "arm64",
452 vendor: true,
453 arch: {
454 arm64: {
455 src: "libvendor_available.so",
456 export_include_dirs: ["include/libvendor"],
457 },
458 },
459 }
460
461 vendor_snapshot_static {
462 name: "libvendor_available",
463 version: "BOARD",
464 target_arch: "arm64",
465 vendor: true,
466 arch: {
467 arm64: {
468 src: "libvendor_available.a",
469 export_include_dirs: ["include/libvendor"],
470 },
471 },
472 }
473
Colin Cross0fce0ba2021-01-08 16:40:12 -0800474 vendor_snapshot_binary {
475 name: "bin",
476 version: "BOARD",
477 target_arch: "arm64",
478 vendor: true,
479 arch: {
480 arm64: {
481 src: "bin",
482 },
483 },
484 }
Colin Crosse0edaf92021-01-11 17:31:17 -0800485
486 // old snapshot module which has to be ignored
487 vendor_snapshot_binary {
488 name: "bin",
489 version: "OLD",
490 target_arch: "arm64",
491 vendor: true,
492 arch: {
493 arm64: {
494 src: "bin",
495 },
496 },
497 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800498`
499 depsBp := GatherRequiredDepsForTest(android.Android)
500
501 mockFS := map[string][]byte{
502 "deps/Android.bp": []byte(depsBp),
503 "framework/Android.bp": []byte(frameworkBp),
504 "vendor/Android.bp": []byte(vendorProprietaryBp),
505 "vendor/bin": nil,
506 "vendor/bin.cpp": nil,
507 "vendor/client.cpp": nil,
508 "vendor/include/libvndk/a.h": nil,
509 "vendor/include/libvendor/b.h": nil,
510 "vendor/libvndk.a": nil,
511 "vendor/libvendor.a": nil,
512 "vendor/libvendor.so": nil,
513 "vndk/Android.bp": []byte(vndkBp),
514 "vndk/include/libvndk/a.h": nil,
515 "vndk/libvndk.so": nil,
516 }
517
518 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
519 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
520 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
521 ctx := CreateTestContext(config)
522 ctx.Register()
523
524 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"})
525 android.FailIfErrored(t, errs)
526 _, errs = ctx.PrepareBuildActions(config)
527 android.FailIfErrored(t, errs)
528
529 sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared"
530 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
531 binaryVariant := "android_vendor.BOARD_arm64_armv8-a"
532
533 // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot
534 libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
535 for _, includeFlags := range []string{
536 "-Ivndk/include/libvndk", // libvndk
537 "-Ivendor/include/libvendor", // libvendor
538 } {
539 if !strings.Contains(libclientCcFlags, includeFlags) {
540 t.Errorf("flags for libclient must contain %#v, but was %#v.",
541 includeFlags, libclientCcFlags)
542 }
543 }
544
545 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
546 for _, input := range [][]string{
547 []string{sharedVariant, "libvndk.vndk.BOARD.arm64"},
548 []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"},
549 []string{staticVariant, "libvendor_without_snapshot"},
550 } {
551 outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
552 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
553 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
554 }
555 }
556
Colin Cross2e577f32021-01-22 13:06:25 -0800557 libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
558 if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor"}; !reflect.DeepEqual(g, w) {
559 t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
560 }
561
562 libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
563 if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) {
564 t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
565 }
566
Colin Cross0fce0ba2021-01-08 16:40:12 -0800567 // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64
568 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
569 if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
570 t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
571 "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
572 }
573
574 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
575 libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"})
576 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
577 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
578 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
579 }
580
581 // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64
582 ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so")
583
Colin Cross2e577f32021-01-22 13:06:25 -0800584 // libvendor_available.so is installed by libvendor_available.vendor_shared.BOARD.arm64
585 ctx.ModuleForTests("libvendor_available.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor_available.so")
586
Colin Cross0fce0ba2021-01-08 16:40:12 -0800587 // libvendor_without_snapshot.so is installed by libvendor_without_snapshot
588 ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
589
590 // bin is installed by bin.vendor_binary.BOARD.arm64
591 ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin")
592
593 // bin_without_snapshot is installed by bin_without_snapshot
594 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
595
Colin Cross2e577f32021-01-22 13:06:25 -0800596 // libvendor, libvendor_available and bin don't have vendor.BOARD variant
Colin Cross0fce0ba2021-01-08 16:40:12 -0800597 libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
598 if inList(sharedVariant, libvendorVariants) {
599 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
600 }
601
Colin Cross2e577f32021-01-22 13:06:25 -0800602 libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
603 if inList(sharedVariant, libvendorAvailableVariants) {
604 t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
605 }
606
Colin Cross0fce0ba2021-01-08 16:40:12 -0800607 binVariants := ctx.ModuleVariantsForTests("bin")
608 if inList(binaryVariant, binVariants) {
609 t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
610 }
611}
612
613func TestVendorSnapshotSanitizer(t *testing.T) {
614 bp := `
615 vendor_snapshot_static {
616 name: "libsnapshot",
617 vendor: true,
618 target_arch: "arm64",
619 version: "BOARD",
620 arch: {
621 arm64: {
622 src: "libsnapshot.a",
623 cfi: {
624 src: "libsnapshot.cfi.a",
625 }
626 },
627 },
628 }
629`
630 config := TestConfig(buildDir, android.Android, nil, bp, nil)
631 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
632 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
633 ctx := testCcWithConfig(t, config)
634
635 // Check non-cfi and cfi variant.
636 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
637 staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
638
639 staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
640 assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
641
642 staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
643 assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
644}
645
646func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
647 t.Helper()
648 m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
649 if m.ExcludeFromVendorSnapshot() != expected {
650 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
651 }
652}
653
654func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
655 t.Helper()
656 m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module)
657 if m.ExcludeFromRecoverySnapshot() != expected {
658 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
659 }
660}
661
662func TestVendorSnapshotExclude(t *testing.T) {
663
664 // This test verifies that the exclude_from_vendor_snapshot property
665 // makes its way from the Android.bp source file into the module data
666 // structure. It also verifies that modules are correctly included or
667 // excluded in the vendor snapshot based on their path (framework or
668 // vendor) and the exclude_from_vendor_snapshot property.
669
670 frameworkBp := `
671 cc_library_shared {
672 name: "libinclude",
673 srcs: ["src/include.cpp"],
674 vendor_available: true,
675 }
676 cc_library_shared {
677 name: "libexclude",
678 srcs: ["src/exclude.cpp"],
679 vendor: true,
680 exclude_from_vendor_snapshot: true,
681 }
682 cc_library_shared {
683 name: "libavailable_exclude",
684 srcs: ["src/exclude.cpp"],
685 vendor_available: true,
686 exclude_from_vendor_snapshot: true,
687 }
688 `
689
690 vendorProprietaryBp := `
691 cc_library_shared {
692 name: "libvendor",
693 srcs: ["vendor.cpp"],
694 vendor: true,
695 }
696 `
697
698 depsBp := GatherRequiredDepsForTest(android.Android)
699
700 mockFS := map[string][]byte{
701 "deps/Android.bp": []byte(depsBp),
702 "framework/Android.bp": []byte(frameworkBp),
703 "framework/include.cpp": nil,
704 "framework/exclude.cpp": nil,
705 "device/Android.bp": []byte(vendorProprietaryBp),
706 "device/vendor.cpp": nil,
707 }
708
709 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
710 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
711 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
712 ctx := CreateTestContext(config)
713 ctx.Register()
714
715 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
716 android.FailIfErrored(t, errs)
717 _, errs = ctx.PrepareBuildActions(config)
718 android.FailIfErrored(t, errs)
719
720 // Test an include and exclude framework module.
721 assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false)
722 assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true)
723 assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true)
724
725 // A vendor module is excluded, but by its path, not the
726 // exclude_from_vendor_snapshot property.
727 assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false)
728
729 // Verify the content of the vendor snapshot.
730
731 snapshotDir := "vendor-snapshot"
732 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
733 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
734
735 var includeJsonFiles []string
736 var excludeJsonFiles []string
737
738 for _, arch := range [][]string{
739 []string{"arm64", "armv8-a"},
740 []string{"arm", "armv7-a-neon"},
741 } {
742 archType := arch[0]
743 archVariant := arch[1]
744 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
745
746 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
747 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
748
749 // Included modules
750 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
751 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
752
753 // Excluded modules
754 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
755 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
756 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
757 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
758 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
759 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
760 }
761
762 // Verify that each json file for an included module has a rule.
763 for _, jsonFile := range includeJsonFiles {
764 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
765 t.Errorf("include json file %q not found", jsonFile)
766 }
767 }
768
769 // Verify that each json file for an excluded module has no rule.
770 for _, jsonFile := range excludeJsonFiles {
771 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
772 t.Errorf("exclude json file %q found", jsonFile)
773 }
774 }
775}
776
777func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
778
779 // This test verifies that using the exclude_from_vendor_snapshot
780 // property on a module in a vendor proprietary path generates an
781 // error. These modules are already excluded, so we prohibit using the
782 // property in this way, which could add to confusion.
783
784 vendorProprietaryBp := `
785 cc_library_shared {
786 name: "libvendor",
787 srcs: ["vendor.cpp"],
788 vendor: true,
789 exclude_from_vendor_snapshot: true,
790 }
791 `
792
793 depsBp := GatherRequiredDepsForTest(android.Android)
794
795 mockFS := map[string][]byte{
796 "deps/Android.bp": []byte(depsBp),
797 "device/Android.bp": []byte(vendorProprietaryBp),
798 "device/vendor.cpp": nil,
799 }
800
801 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
802 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
803 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
804 ctx := CreateTestContext(config)
805 ctx.Register()
806
807 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"})
808 android.FailIfErrored(t, errs)
809
810 _, errs = ctx.PrepareBuildActions(config)
811 android.CheckErrorsAgainstExpectations(t, errs, []string{
812 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
813 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
814 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
815 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
816 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
817 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
818 })
819}
820
821func TestRecoverySnapshotCapture(t *testing.T) {
822 bp := `
823 cc_library {
824 name: "libvndk",
825 vendor_available: true,
826 recovery_available: true,
827 product_available: true,
828 vndk: {
829 enabled: true,
830 },
831 nocrt: true,
832 }
833
834 cc_library {
835 name: "librecovery",
836 recovery: true,
837 nocrt: true,
838 }
839
840 cc_library {
841 name: "librecovery_available",
842 recovery_available: true,
843 nocrt: true,
844 }
845
846 cc_library_headers {
847 name: "librecovery_headers",
848 recovery_available: true,
849 nocrt: true,
850 }
851
852 cc_binary {
853 name: "recovery_bin",
854 recovery: true,
855 nocrt: true,
856 }
857
858 cc_binary {
859 name: "recovery_available_bin",
860 recovery_available: true,
861 nocrt: true,
862 }
863
864 toolchain_library {
865 name: "libb",
866 recovery_available: true,
867 src: "libb.a",
868 }
869
870 cc_object {
871 name: "obj",
872 recovery_available: true,
873 }
874`
875 config := TestConfig(buildDir, android.Android, nil, bp, nil)
876 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
877 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
878 ctx := testCcWithConfig(t, config)
879
880 // Check Recovery snapshot output.
881
882 snapshotDir := "recovery-snapshot"
883 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
884 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
885
886 var jsonFiles []string
887
888 for _, arch := range [][]string{
889 []string{"arm64", "armv8-a"},
890 } {
891 archType := arch[0]
892 archVariant := arch[1]
893 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
894
895 // For shared libraries, only recovery_available modules are captured.
896 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
897 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
898 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
899 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
900 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
901 jsonFiles = append(jsonFiles,
902 filepath.Join(sharedDir, "libvndk.so.json"),
903 filepath.Join(sharedDir, "librecovery.so.json"),
904 filepath.Join(sharedDir, "librecovery_available.so.json"))
905
906 // For static libraries, all recovery:true and recovery_available modules are captured.
907 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
908 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
909 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
910 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
911 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
912 jsonFiles = append(jsonFiles,
913 filepath.Join(staticDir, "libb.a.json"),
914 filepath.Join(staticDir, "librecovery.a.json"),
915 filepath.Join(staticDir, "librecovery_available.a.json"))
916
917 // For binary executables, all recovery:true and recovery_available modules are captured.
918 if archType == "arm64" {
919 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
920 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
921 checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
922 checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
923 jsonFiles = append(jsonFiles,
924 filepath.Join(binaryDir, "recovery_bin.json"),
925 filepath.Join(binaryDir, "recovery_available_bin.json"))
926 }
927
928 // For header libraries, all vendor:true and vendor_available modules are captured.
929 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
930 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json"))
931
932 // For object modules, all vendor:true and vendor_available modules are captured.
933 objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
934 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
935 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
936 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
937 }
938
939 for _, jsonFile := range jsonFiles {
940 // verify all json files exist
941 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
942 t.Errorf("%q expected but not found", jsonFile)
943 }
944 }
945}
946
947func TestRecoverySnapshotExclude(t *testing.T) {
948 // This test verifies that the exclude_from_recovery_snapshot property
949 // makes its way from the Android.bp source file into the module data
950 // structure. It also verifies that modules are correctly included or
951 // excluded in the recovery snapshot based on their path (framework or
952 // vendor) and the exclude_from_recovery_snapshot property.
953
954 frameworkBp := `
955 cc_library_shared {
956 name: "libinclude",
957 srcs: ["src/include.cpp"],
958 recovery_available: true,
959 }
960 cc_library_shared {
961 name: "libexclude",
962 srcs: ["src/exclude.cpp"],
963 recovery: true,
964 exclude_from_recovery_snapshot: true,
965 }
966 cc_library_shared {
967 name: "libavailable_exclude",
968 srcs: ["src/exclude.cpp"],
969 recovery_available: true,
970 exclude_from_recovery_snapshot: true,
971 }
972 `
973
974 vendorProprietaryBp := `
975 cc_library_shared {
976 name: "librecovery",
977 srcs: ["recovery.cpp"],
978 recovery: true,
979 }
980 `
981
982 depsBp := GatherRequiredDepsForTest(android.Android)
983
984 mockFS := map[string][]byte{
985 "deps/Android.bp": []byte(depsBp),
986 "framework/Android.bp": []byte(frameworkBp),
987 "framework/include.cpp": nil,
988 "framework/exclude.cpp": nil,
989 "device/Android.bp": []byte(vendorProprietaryBp),
990 "device/recovery.cpp": nil,
991 }
992
993 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
994 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
995 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
996 ctx := CreateTestContext(config)
997 ctx.Register()
998
999 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
1000 android.FailIfErrored(t, errs)
1001 _, errs = ctx.PrepareBuildActions(config)
1002 android.FailIfErrored(t, errs)
1003
1004 // Test an include and exclude framework module.
1005 assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false)
1006 assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true)
1007 assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true)
1008
1009 // A recovery module is excluded, but by its path, not the
1010 // exclude_from_recovery_snapshot property.
1011 assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false)
1012
1013 // Verify the content of the recovery snapshot.
1014
1015 snapshotDir := "recovery-snapshot"
1016 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
1017 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
1018
1019 var includeJsonFiles []string
1020 var excludeJsonFiles []string
1021
1022 for _, arch := range [][]string{
1023 []string{"arm64", "armv8-a"},
1024 } {
1025 archType := arch[0]
1026 archVariant := arch[1]
1027 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
1028
1029 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
1030 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
1031
1032 // Included modules
1033 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
1034 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
1035
1036 // Excluded modules
1037 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
1038 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
1039 checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
1040 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
1041 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
1042 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
1043 }
1044
1045 // Verify that each json file for an included module has a rule.
1046 for _, jsonFile := range includeJsonFiles {
1047 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
1048 t.Errorf("include json file %q not found", jsonFile)
1049 }
1050 }
1051
1052 // Verify that each json file for an excluded module has no rule.
1053 for _, jsonFile := range excludeJsonFiles {
1054 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
1055 t.Errorf("exclude json file %q found", jsonFile)
1056 }
1057 }
1058}