1// 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" 21 "reflect" 22 "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: { 82 symbol_file: "libllndk.map.txt", 83 }, 84 } 85` 86 87 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 88 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 89 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 90 ctx := testCcWithConfig(t, config) 91 92 // Check Vendor snapshot output. 93 94 snapshotDir := "vendor-snapshot" 95 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 96 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") 97 98 var jsonFiles []string 99 100 for _, arch := range [][]string{ 101 []string{"arm64", "armv8-a"}, 102 []string{"arm", "armv7-a-neon"}, 103 } { 104 archType := arch[0] 105 archVariant := arch[1] 106 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 107 108 // For shared libraries, only non-VNDK vendor_available modules are captured 109 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant) 110 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 111 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) 112 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) 113 jsonFiles = append(jsonFiles, 114 filepath.Join(sharedDir, "libvendor.so.json"), 115 filepath.Join(sharedDir, "libvendor_available.so.json")) 116 117 // LLNDK modules are not captured 118 checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant) 119 120 // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. 121 // Also cfi variants are captured, except for prebuilts like toolchain_library 122 staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant) 123 staticCfiVariant := fmt.Sprintf("android_vendor.29_%s_%s_static_cfi", archType, archVariant) 124 staticDir := filepath.Join(snapshotVariantPath, archDir, "static") 125 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) 126 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant) 127 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant) 128 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant) 129 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant) 130 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant) 131 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant) 132 jsonFiles = append(jsonFiles, 133 filepath.Join(staticDir, "libb.a.json"), 134 filepath.Join(staticDir, "libvndk.a.json"), 135 filepath.Join(staticDir, "libvndk.cfi.a.json"), 136 filepath.Join(staticDir, "libvendor.a.json"), 137 filepath.Join(staticDir, "libvendor.cfi.a.json"), 138 filepath.Join(staticDir, "libvendor_available.a.json"), 139 filepath.Join(staticDir, "libvendor_available.cfi.a.json")) 140 141 // For binary executables, all vendor:true and vendor_available modules are captured. 142 if archType == "arm64" { 143 binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant) 144 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") 145 checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant) 146 checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant) 147 jsonFiles = append(jsonFiles, 148 filepath.Join(binaryDir, "vendor_bin.json"), 149 filepath.Join(binaryDir, "vendor_available_bin.json")) 150 } 151 152 // For header libraries, all vendor:true and vendor_available modules are captured. 153 headerDir := filepath.Join(snapshotVariantPath, archDir, "header") 154 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json")) 155 156 // For object modules, all vendor:true and vendor_available modules are captured. 157 objectVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant) 158 objectDir := filepath.Join(snapshotVariantPath, archDir, "object") 159 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) 160 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) 161 } 162 163 for _, jsonFile := range jsonFiles { 164 // verify all json files exist 165 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 166 t.Errorf("%q expected but not found", jsonFile) 167 } 168 } 169 170 // fake snapshot should have all outputs in the normal snapshot. 171 fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot") 172 for _, output := range snapshotSingleton.AllOutputs() { 173 fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1) 174 if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil { 175 t.Errorf("%q expected but not found", fakeOutput) 176 } 177 } 178} 179 180func TestVendorSnapshotDirected(t *testing.T) { 181 bp := ` 182 cc_library_shared { 183 name: "libvendor", 184 vendor: true, 185 nocrt: true, 186 } 187 188 cc_library_shared { 189 name: "libvendor_available", 190 vendor_available: true, 191 nocrt: true, 192 } 193 194 genrule { 195 name: "libfoo_gen", 196 cmd: "", 197 out: ["libfoo.so"], 198 } 199 200 cc_prebuilt_library_shared { 201 name: "libfoo", 202 vendor: true, 203 prefer: true, 204 srcs: [":libfoo_gen"], 205 } 206 207 cc_library_shared { 208 name: "libfoo", 209 vendor: true, 210 nocrt: true, 211 } 212` 213 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 214 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 215 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 216 config.TestProductVariables.DirectedVendorSnapshot = true 217 config.TestProductVariables.VendorSnapshotModules = make(map[string]bool) 218 config.TestProductVariables.VendorSnapshotModules["libvendor"] = true 219 config.TestProductVariables.VendorSnapshotModules["libfoo"] = true 220 ctx := testCcWithConfig(t, config) 221 222 // Check Vendor snapshot output. 223 224 snapshotDir := "vendor-snapshot" 225 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 226 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") 227 228 var includeJsonFiles []string 229 230 for _, arch := range [][]string{ 231 []string{"arm64", "armv8-a"}, 232 []string{"arm", "armv7-a-neon"}, 233 } { 234 archType := arch[0] 235 archVariant := arch[1] 236 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 237 238 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant) 239 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 240 241 // Included modules 242 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) 243 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json")) 244 // Check that snapshot captures "prefer: true" prebuilt 245 checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant) 246 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json")) 247 248 // Excluded modules. Modules not included in the directed vendor snapshot 249 // are still include as fake modules. 250 checkSnapshotRule(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) 251 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json")) 252 } 253 254 // Verify that each json file for an included module has a rule. 255 for _, jsonFile := range includeJsonFiles { 256 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 257 t.Errorf("include json file %q not found", jsonFile) 258 } 259 } 260} 261 262func TestVendorSnapshotUse(t *testing.T) { 263 frameworkBp := ` 264 cc_library { 265 name: "libvndk", 266 vendor_available: true, 267 product_available: true, 268 vndk: { 269 enabled: true, 270 }, 271 nocrt: true, 272 } 273 274 cc_library { 275 name: "libvendor", 276 vendor: true, 277 nocrt: true, 278 no_libcrt: true, 279 stl: "none", 280 system_shared_libs: [], 281 } 282 283 cc_library { 284 name: "libvendor_available", 285 vendor_available: true, 286 nocrt: true, 287 no_libcrt: true, 288 stl: "none", 289 system_shared_libs: [], 290 } 291 292 cc_library { 293 name: "lib32", 294 vendor: true, 295 nocrt: true, 296 no_libcrt: true, 297 stl: "none", 298 system_shared_libs: [], 299 compile_multilib: "32", 300 } 301 302 cc_library { 303 name: "lib64", 304 vendor: true, 305 nocrt: true, 306 no_libcrt: true, 307 stl: "none", 308 system_shared_libs: [], 309 compile_multilib: "64", 310 } 311 312 cc_library { 313 name: "libllndk", 314 llndk: { 315 symbol_file: "libllndk.map.txt", 316 }, 317 } 318 319 cc_binary { 320 name: "bin", 321 vendor: true, 322 nocrt: true, 323 no_libcrt: true, 324 stl: "none", 325 system_shared_libs: [], 326 } 327 328 cc_binary { 329 name: "bin32", 330 vendor: true, 331 nocrt: true, 332 no_libcrt: true, 333 stl: "none", 334 system_shared_libs: [], 335 compile_multilib: "32", 336 } 337` 338 339 vndkBp := ` 340 vndk_prebuilt_shared { 341 name: "libvndk", 342 version: "31", 343 target_arch: "arm64", 344 vendor_available: true, 345 product_available: true, 346 vndk: { 347 enabled: true, 348 }, 349 arch: { 350 arm64: { 351 srcs: ["libvndk.so"], 352 export_include_dirs: ["include/libvndk"], 353 }, 354 arm: { 355 srcs: ["libvndk.so"], 356 export_include_dirs: ["include/libvndk"], 357 }, 358 }, 359 } 360 361 // old snapshot module which has to be ignored 362 vndk_prebuilt_shared { 363 name: "libvndk", 364 version: "26", 365 target_arch: "arm64", 366 vendor_available: true, 367 product_available: true, 368 vndk: { 369 enabled: true, 370 }, 371 arch: { 372 arm64: { 373 srcs: ["libvndk.so"], 374 export_include_dirs: ["include/libvndk"], 375 }, 376 arm: { 377 srcs: ["libvndk.so"], 378 export_include_dirs: ["include/libvndk"], 379 }, 380 }, 381 } 382 383 // different arch snapshot which has to be ignored 384 vndk_prebuilt_shared { 385 name: "libvndk", 386 version: "31", 387 target_arch: "arm", 388 vendor_available: true, 389 product_available: true, 390 vndk: { 391 enabled: true, 392 }, 393 arch: { 394 arm: { 395 srcs: ["libvndk.so"], 396 export_include_dirs: ["include/libvndk"], 397 }, 398 }, 399 } 400 401 vndk_prebuilt_shared { 402 name: "libllndk", 403 version: "31", 404 target_arch: "arm64", 405 vendor_available: true, 406 product_available: true, 407 arch: { 408 arm64: { 409 srcs: ["libllndk.so"], 410 }, 411 arm: { 412 srcs: ["libllndk.so"], 413 }, 414 }, 415 } 416` 417 418 vendorProprietaryBp := ` 419 cc_library { 420 name: "libvendor_without_snapshot", 421 vendor: true, 422 nocrt: true, 423 no_libcrt: true, 424 stl: "none", 425 system_shared_libs: [], 426 } 427 428 cc_library_shared { 429 name: "libclient", 430 vendor: true, 431 nocrt: true, 432 no_libcrt: true, 433 stl: "none", 434 system_shared_libs: [], 435 shared_libs: ["libvndk", "libvendor_available", "libllndk"], 436 static_libs: ["libvendor", "libvendor_without_snapshot"], 437 arch: { 438 arm64: { 439 shared_libs: ["lib64"], 440 }, 441 arm: { 442 shared_libs: ["lib32"], 443 }, 444 }, 445 srcs: ["client.cpp"], 446 } 447 448 cc_library_shared { 449 name: "libclient_cfi", 450 vendor: true, 451 nocrt: true, 452 no_libcrt: true, 453 stl: "none", 454 system_shared_libs: [], 455 static_libs: ["libvendor"], 456 sanitize: { 457 cfi: true, 458 }, 459 srcs: ["client.cpp"], 460 } 461 462 cc_binary { 463 name: "bin_without_snapshot", 464 vendor: true, 465 nocrt: true, 466 no_libcrt: true, 467 stl: "libc++_static", 468 system_shared_libs: [], 469 static_libs: ["libvndk"], 470 srcs: ["bin.cpp"], 471 } 472 473 vendor_snapshot { 474 name: "vendor_snapshot", 475 version: "31", 476 arch: { 477 arm64: { 478 vndk_libs: [ 479 "libvndk", 480 "libllndk", 481 ], 482 static_libs: [ 483 "libc++_static", 484 "libc++demangle", 485 "libunwind", 486 "libvendor", 487 "libvendor_available", 488 "libvndk", 489 "lib64", 490 ], 491 shared_libs: [ 492 "libvendor", 493 "libvendor_available", 494 "lib64", 495 ], 496 binaries: [ 497 "bin", 498 ], 499 }, 500 arm: { 501 vndk_libs: [ 502 "libvndk", 503 "libllndk", 504 ], 505 static_libs: [ 506 "libvendor", 507 "libvendor_available", 508 "libvndk", 509 "lib32", 510 ], 511 shared_libs: [ 512 "libvendor", 513 "libvendor_available", 514 "lib32", 515 ], 516 binaries: [ 517 "bin32", 518 ], 519 }, 520 } 521 } 522 523 vendor_snapshot_static { 524 name: "libvndk", 525 version: "31", 526 target_arch: "arm64", 527 compile_multilib: "both", 528 vendor: true, 529 arch: { 530 arm64: { 531 src: "libvndk.a", 532 }, 533 arm: { 534 src: "libvndk.a", 535 }, 536 }, 537 shared_libs: ["libvndk"], 538 export_shared_lib_headers: ["libvndk"], 539 } 540 541 vendor_snapshot_shared { 542 name: "libvendor", 543 version: "31", 544 target_arch: "arm64", 545 compile_multilib: "both", 546 vendor: true, 547 shared_libs: [ 548 "libvendor_without_snapshot", 549 "libvendor_available", 550 "libvndk", 551 ], 552 arch: { 553 arm64: { 554 src: "libvendor.so", 555 export_include_dirs: ["include/libvendor"], 556 }, 557 arm: { 558 src: "libvendor.so", 559 export_include_dirs: ["include/libvendor"], 560 }, 561 }, 562 } 563 564 vendor_snapshot_static { 565 name: "lib32", 566 version: "31", 567 target_arch: "arm64", 568 compile_multilib: "32", 569 vendor: true, 570 arch: { 571 arm: { 572 src: "lib32.a", 573 }, 574 }, 575 } 576 577 vendor_snapshot_shared { 578 name: "lib32", 579 version: "31", 580 target_arch: "arm64", 581 compile_multilib: "32", 582 vendor: true, 583 arch: { 584 arm: { 585 src: "lib32.so", 586 }, 587 }, 588 } 589 590 vendor_snapshot_static { 591 name: "lib64", 592 version: "31", 593 target_arch: "arm64", 594 compile_multilib: "64", 595 vendor: true, 596 arch: { 597 arm64: { 598 src: "lib64.a", 599 }, 600 }, 601 } 602 603 vendor_snapshot_shared { 604 name: "lib64", 605 version: "31", 606 target_arch: "arm64", 607 compile_multilib: "64", 608 vendor: true, 609 arch: { 610 arm64: { 611 src: "lib64.so", 612 }, 613 }, 614 } 615 616 vendor_snapshot_static { 617 name: "libvendor", 618 version: "31", 619 target_arch: "arm64", 620 compile_multilib: "both", 621 vendor: true, 622 arch: { 623 arm64: { 624 cfi: { 625 src: "libvendor.cfi.a", 626 export_include_dirs: ["include/libvendor_cfi"], 627 }, 628 src: "libvendor.a", 629 export_include_dirs: ["include/libvendor"], 630 }, 631 arm: { 632 cfi: { 633 src: "libvendor.cfi.a", 634 export_include_dirs: ["include/libvendor_cfi"], 635 }, 636 src: "libvendor.a", 637 export_include_dirs: ["include/libvendor"], 638 }, 639 }, 640 } 641 642 vendor_snapshot_shared { 643 name: "libvendor_available", 644 version: "31", 645 target_arch: "arm64", 646 compile_multilib: "both", 647 vendor: true, 648 arch: { 649 arm64: { 650 src: "libvendor_available.so", 651 export_include_dirs: ["include/libvendor"], 652 }, 653 arm: { 654 src: "libvendor_available.so", 655 export_include_dirs: ["include/libvendor"], 656 }, 657 }, 658 } 659 660 vendor_snapshot_static { 661 name: "libvendor_available", 662 version: "31", 663 target_arch: "arm64", 664 compile_multilib: "both", 665 vendor: true, 666 arch: { 667 arm64: { 668 src: "libvendor_available.a", 669 export_include_dirs: ["include/libvendor"], 670 }, 671 arm: { 672 src: "libvendor_available.so", 673 export_include_dirs: ["include/libvendor"], 674 }, 675 }, 676 } 677 678 vendor_snapshot_static { 679 name: "libc++_static", 680 version: "31", 681 target_arch: "arm64", 682 compile_multilib: "64", 683 vendor: true, 684 arch: { 685 arm64: { 686 src: "libc++_static.a", 687 }, 688 }, 689 } 690 691 vendor_snapshot_static { 692 name: "libc++demangle", 693 version: "31", 694 target_arch: "arm64", 695 compile_multilib: "64", 696 vendor: true, 697 arch: { 698 arm64: { 699 src: "libc++demangle.a", 700 }, 701 }, 702 } 703 704 vendor_snapshot_static { 705 name: "libunwind", 706 version: "31", 707 target_arch: "arm64", 708 compile_multilib: "64", 709 vendor: true, 710 arch: { 711 arm64: { 712 src: "libunwind.a", 713 }, 714 }, 715 } 716 717 vendor_snapshot_binary { 718 name: "bin", 719 version: "31", 720 target_arch: "arm64", 721 compile_multilib: "64", 722 vendor: true, 723 arch: { 724 arm64: { 725 src: "bin", 726 }, 727 }, 728 } 729 730 vendor_snapshot_binary { 731 name: "bin32", 732 version: "31", 733 target_arch: "arm64", 734 compile_multilib: "32", 735 vendor: true, 736 arch: { 737 arm: { 738 src: "bin32", 739 }, 740 }, 741 } 742 743 // old snapshot module which has to be ignored 744 vendor_snapshot_binary { 745 name: "bin", 746 version: "26", 747 target_arch: "arm64", 748 compile_multilib: "first", 749 vendor: true, 750 arch: { 751 arm64: { 752 src: "bin", 753 }, 754 }, 755 } 756 757 // different arch snapshot which has to be ignored 758 vendor_snapshot_binary { 759 name: "bin", 760 version: "31", 761 target_arch: "arm", 762 compile_multilib: "first", 763 vendor: true, 764 arch: { 765 arm64: { 766 src: "bin", 767 }, 768 }, 769 } 770` 771 depsBp := GatherRequiredDepsForTest(android.Android) 772 773 mockFS := map[string][]byte{ 774 "deps/Android.bp": []byte(depsBp), 775 "framework/Android.bp": []byte(frameworkBp), 776 "framework/symbol.txt": nil, 777 "vendor/Android.bp": []byte(vendorProprietaryBp), 778 "vendor/bin": nil, 779 "vendor/bin32": nil, 780 "vendor/bin.cpp": nil, 781 "vendor/client.cpp": nil, 782 "vendor/include/libvndk/a.h": nil, 783 "vendor/include/libvendor/b.h": nil, 784 "vendor/include/libvendor_cfi/c.h": nil, 785 "vendor/libc++_static.a": nil, 786 "vendor/libc++demangle.a": nil, 787 "vendor/libunwind.a": nil, 788 "vendor/libvndk.a": nil, 789 "vendor/libvendor.a": nil, 790 "vendor/libvendor.cfi.a": nil, 791 "vendor/libvendor.so": nil, 792 "vendor/lib32.a": nil, 793 "vendor/lib32.so": nil, 794 "vendor/lib64.a": nil, 795 "vendor/lib64.so": nil, 796 "vndk/Android.bp": []byte(vndkBp), 797 "vndk/include/libvndk/a.h": nil, 798 "vndk/libvndk.so": nil, 799 "vndk/libllndk.so": nil, 800 } 801 802 config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS) 803 config.TestProductVariables.DeviceVndkVersion = StringPtr("31") 804 config.TestProductVariables.Platform_vndk_version = StringPtr("32") 805 ctx := CreateTestContext(config) 806 ctx.Register() 807 808 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"}) 809 android.FailIfErrored(t, errs) 810 _, errs = ctx.PrepareBuildActions(config) 811 android.FailIfErrored(t, errs) 812 813 sharedVariant := "android_vendor.31_arm64_armv8-a_shared" 814 staticVariant := "android_vendor.31_arm64_armv8-a_static" 815 binaryVariant := "android_vendor.31_arm64_armv8-a" 816 817 sharedCfiVariant := "android_vendor.31_arm64_armv8-a_shared_cfi" 818 staticCfiVariant := "android_vendor.31_arm64_armv8-a_static_cfi" 819 820 shared32Variant := "android_vendor.31_arm_armv7-a-neon_shared" 821 binary32Variant := "android_vendor.31_arm_armv7-a-neon" 822 823 // libclient uses libvndk.vndk.31.arm64, libvendor.vendor_static.31.arm64, libvendor_without_snapshot 824 libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"] 825 for _, includeFlags := range []string{ 826 "-Ivndk/include/libvndk", // libvndk 827 "-Ivendor/include/libvendor", // libvendor 828 } { 829 if !strings.Contains(libclientCcFlags, includeFlags) { 830 t.Errorf("flags for libclient must contain %#v, but was %#v.", 831 includeFlags, libclientCcFlags) 832 } 833 } 834 835 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"] 836 for _, input := range [][]string{ 837 []string{sharedVariant, "libvndk.vndk.31.arm64"}, 838 []string{sharedVariant, "libllndk.vndk.31.arm64"}, 839 []string{staticVariant, "libvendor.vendor_static.31.arm64"}, 840 []string{staticVariant, "libvendor_without_snapshot"}, 841 } { 842 outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */) 843 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) { 844 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags) 845 } 846 } 847 848 libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs 849 if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "libllndk.vendor", "lib64"}; !reflect.DeepEqual(g, w) { 850 t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g) 851 } 852 853 libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs 854 if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) { 855 t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g) 856 } 857 858 libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).Properties.AndroidMkSharedLibs 859 if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "libllndk.vendor", "lib32"}; !reflect.DeepEqual(g, w) { 860 t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g) 861 } 862 863 // libclient_cfi uses libvendor.vendor_static.31.arm64's cfi variant 864 libclientCfiCcFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("cc").Args["cFlags"] 865 if !strings.Contains(libclientCfiCcFlags, "-Ivendor/include/libvendor_cfi") { 866 t.Errorf("flags for libclient_cfi must contain %#v, but was %#v.", 867 "-Ivendor/include/libvendor_cfi", libclientCfiCcFlags) 868 } 869 870 libclientCfiLdFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("ld").Args["libFlags"] 871 libvendorCfiOutputPaths := getOutputPaths(ctx, staticCfiVariant, []string{"libvendor.vendor_static.31.arm64"}) 872 if !strings.Contains(libclientCfiLdFlags, libvendorCfiOutputPaths[0].String()) { 873 t.Errorf("libflags for libclientCfi must contain %#v, but was %#v", libvendorCfiOutputPaths[0], libclientCfiLdFlags) 874 } 875 876 // bin_without_snapshot uses libvndk.vendor_static.31.arm64 (which reexports vndk's exported headers) 877 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"] 878 if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivndk/include/libvndk") { 879 t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.", 880 "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags) 881 } 882 883 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"] 884 libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.31.arm64"}) 885 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) { 886 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v", 887 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags) 888 } 889 890 // libvendor.so is installed by libvendor.vendor_shared.31.arm64 891 ctx.ModuleForTests("libvendor.vendor_shared.31.arm64", sharedVariant).Output("libvendor.so") 892 893 // lib64.so is installed by lib64.vendor_shared.31.arm64 894 ctx.ModuleForTests("lib64.vendor_shared.31.arm64", sharedVariant).Output("lib64.so") 895 896 // lib32.so is installed by lib32.vendor_shared.31.arm64 897 ctx.ModuleForTests("lib32.vendor_shared.31.arm64", shared32Variant).Output("lib32.so") 898 899 // libvendor_available.so is installed by libvendor_available.vendor_shared.31.arm64 900 ctx.ModuleForTests("libvendor_available.vendor_shared.31.arm64", sharedVariant).Output("libvendor_available.so") 901 902 // libvendor_without_snapshot.so is installed by libvendor_without_snapshot 903 ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so") 904 905 // bin is installed by bin.vendor_binary.31.arm64 906 ctx.ModuleForTests("bin.vendor_binary.31.arm64", binaryVariant).Output("bin") 907 908 // bin32 is installed by bin32.vendor_binary.31.arm64 909 ctx.ModuleForTests("bin32.vendor_binary.31.arm64", binary32Variant).Output("bin32") 910 911 // bin_without_snapshot is installed by bin_without_snapshot 912 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot") 913 914 // libvendor, libvendor_available and bin don't have vendor.31 variant 915 libvendorVariants := ctx.ModuleVariantsForTests("libvendor") 916 if inList(sharedVariant, libvendorVariants) { 917 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant) 918 } 919 920 libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available") 921 if inList(sharedVariant, libvendorAvailableVariants) { 922 t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant) 923 } 924 925 binVariants := ctx.ModuleVariantsForTests("bin") 926 if inList(binaryVariant, binVariants) { 927 t.Errorf("bin must not have variant %#v, but it does", sharedVariant) 928 } 929} 930 931func TestVendorSnapshotSanitizer(t *testing.T) { 932 bp := ` 933 vendor_snapshot { 934 name: "vendor_snapshot", 935 version: "28", 936 arch: { 937 arm64: { 938 static_libs: [ 939 "libsnapshot", 940 "note_memtag_heap_sync", 941 ], 942 }, 943 }, 944 } 945 vendor_snapshot_static { 946 name: "libsnapshot", 947 vendor: true, 948 target_arch: "arm64", 949 version: "28", 950 arch: { 951 arm64: { 952 src: "libsnapshot.a", 953 cfi: { 954 src: "libsnapshot.cfi.a", 955 } 956 }, 957 }, 958 } 959 960 vendor_snapshot_static { 961 name: "note_memtag_heap_sync", 962 vendor: true, 963 target_arch: "arm64", 964 version: "28", 965 arch: { 966 arm64: { 967 src: "note_memtag_heap_sync.a", 968 }, 969 }, 970 } 971 972 cc_test { 973 name: "vstest", 974 gtest: false, 975 vendor: true, 976 compile_multilib: "64", 977 nocrt: true, 978 no_libcrt: true, 979 stl: "none", 980 static_libs: ["libsnapshot"], 981 system_shared_libs: [], 982 } 983` 984 985 mockFS := map[string][]byte{ 986 "vendor/Android.bp": []byte(bp), 987 "vendor/libc++demangle.a": nil, 988 "vendor/libsnapshot.a": nil, 989 "vendor/libsnapshot.cfi.a": nil, 990 "vendor/note_memtag_heap_sync.a": nil, 991 } 992 993 config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS) 994 config.TestProductVariables.DeviceVndkVersion = StringPtr("28") 995 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 996 ctx := testCcWithConfig(t, config) 997 998 // Check non-cfi and cfi variant. 999 staticVariant := "android_vendor.28_arm64_armv8-a_static" 1000 staticCfiVariant := "android_vendor.28_arm64_armv8-a_static_cfi" 1001 1002 staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.28.arm64", staticVariant).Module().(*Module) 1003 assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a") 1004 1005 staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.28.arm64", staticCfiVariant).Module().(*Module) 1006 assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a") 1007} 1008 1009func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) { 1010 t.Helper() 1011 m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module) 1012 if m.ExcludeFromVendorSnapshot() != expected { 1013 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected) 1014 } 1015} 1016 1017func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) { 1018 t.Helper() 1019 m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module) 1020 if m.ExcludeFromRecoverySnapshot() != expected { 1021 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected) 1022 } 1023} 1024 1025func TestVendorSnapshotExclude(t *testing.T) { 1026 1027 // This test verifies that the exclude_from_vendor_snapshot property 1028 // makes its way from the Android.bp source file into the module data 1029 // structure. It also verifies that modules are correctly included or 1030 // excluded in the vendor snapshot based on their path (framework or 1031 // vendor) and the exclude_from_vendor_snapshot property. 1032 1033 frameworkBp := ` 1034 cc_library_shared { 1035 name: "libinclude", 1036 srcs: ["src/include.cpp"], 1037 vendor_available: true, 1038 } 1039 cc_library_shared { 1040 name: "libexclude", 1041 srcs: ["src/exclude.cpp"], 1042 vendor: true, 1043 exclude_from_vendor_snapshot: true, 1044 } 1045 cc_library_shared { 1046 name: "libavailable_exclude", 1047 srcs: ["src/exclude.cpp"], 1048 vendor_available: true, 1049 exclude_from_vendor_snapshot: true, 1050 } 1051 ` 1052 1053 vendorProprietaryBp := ` 1054 cc_library_shared { 1055 name: "libvendor", 1056 srcs: ["vendor.cpp"], 1057 vendor: true, 1058 } 1059 ` 1060 1061 depsBp := GatherRequiredDepsForTest(android.Android) 1062 1063 mockFS := map[string][]byte{ 1064 "deps/Android.bp": []byte(depsBp), 1065 "framework/Android.bp": []byte(frameworkBp), 1066 "framework/include.cpp": nil, 1067 "framework/exclude.cpp": nil, 1068 "device/Android.bp": []byte(vendorProprietaryBp), 1069 "device/vendor.cpp": nil, 1070 } 1071 1072 config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS) 1073 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 1074 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1075 ctx := CreateTestContext(config) 1076 ctx.Register() 1077 1078 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"}) 1079 android.FailIfErrored(t, errs) 1080 _, errs = ctx.PrepareBuildActions(config) 1081 android.FailIfErrored(t, errs) 1082 1083 // Test an include and exclude framework module. 1084 assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false) 1085 assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true) 1086 assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true) 1087 1088 // A vendor module is excluded, but by its path, not the 1089 // exclude_from_vendor_snapshot property. 1090 assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false) 1091 1092 // Verify the content of the vendor snapshot. 1093 1094 snapshotDir := "vendor-snapshot" 1095 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1096 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") 1097 1098 var includeJsonFiles []string 1099 var excludeJsonFiles []string 1100 1101 for _, arch := range [][]string{ 1102 []string{"arm64", "armv8-a"}, 1103 []string{"arm", "armv7-a-neon"}, 1104 } { 1105 archType := arch[0] 1106 archVariant := arch[1] 1107 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1108 1109 sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant) 1110 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1111 1112 // Included modules 1113 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) 1114 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) 1115 1116 // Excluded modules 1117 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) 1118 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) 1119 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) 1120 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json")) 1121 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) 1122 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) 1123 } 1124 1125 // Verify that each json file for an included module has a rule. 1126 for _, jsonFile := range includeJsonFiles { 1127 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1128 t.Errorf("include json file %q not found", jsonFile) 1129 } 1130 } 1131 1132 // Verify that each json file for an excluded module has no rule. 1133 for _, jsonFile := range excludeJsonFiles { 1134 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { 1135 t.Errorf("exclude json file %q found", jsonFile) 1136 } 1137 } 1138} 1139 1140func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) { 1141 1142 // This test verifies that using the exclude_from_vendor_snapshot 1143 // property on a module in a vendor proprietary path generates an 1144 // error. These modules are already excluded, so we prohibit using the 1145 // property in this way, which could add to confusion. 1146 1147 vendorProprietaryBp := ` 1148 cc_library_shared { 1149 name: "libvendor", 1150 srcs: ["vendor.cpp"], 1151 vendor: true, 1152 exclude_from_vendor_snapshot: true, 1153 } 1154 ` 1155 1156 depsBp := GatherRequiredDepsForTest(android.Android) 1157 1158 mockFS := map[string][]byte{ 1159 "deps/Android.bp": []byte(depsBp), 1160 "device/Android.bp": []byte(vendorProprietaryBp), 1161 "device/vendor.cpp": nil, 1162 } 1163 1164 config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS) 1165 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 1166 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1167 ctx := CreateTestContext(config) 1168 ctx.Register() 1169 1170 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"}) 1171 android.FailIfErrored(t, errs) 1172 1173 _, errs = ctx.PrepareBuildActions(config) 1174 android.CheckErrorsAgainstExpectations(t, errs, []string{ 1175 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, 1176 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, 1177 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, 1178 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, 1179 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, 1180 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`, 1181 }) 1182} 1183 1184func TestRecoverySnapshotCapture(t *testing.T) { 1185 bp := ` 1186 cc_library { 1187 name: "libvndk", 1188 vendor_available: true, 1189 recovery_available: true, 1190 product_available: true, 1191 vndk: { 1192 enabled: true, 1193 }, 1194 nocrt: true, 1195 } 1196 1197 cc_library { 1198 name: "librecovery", 1199 recovery: true, 1200 nocrt: true, 1201 } 1202 1203 cc_library { 1204 name: "librecovery_available", 1205 recovery_available: true, 1206 nocrt: true, 1207 } 1208 1209 cc_library_headers { 1210 name: "librecovery_headers", 1211 recovery_available: true, 1212 nocrt: true, 1213 } 1214 1215 cc_binary { 1216 name: "recovery_bin", 1217 recovery: true, 1218 nocrt: true, 1219 } 1220 1221 cc_binary { 1222 name: "recovery_available_bin", 1223 recovery_available: true, 1224 nocrt: true, 1225 } 1226 1227 toolchain_library { 1228 name: "libb", 1229 recovery_available: true, 1230 src: "libb.a", 1231 } 1232 1233 cc_object { 1234 name: "obj", 1235 recovery_available: true, 1236 } 1237` 1238 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 1239 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") 1240 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1241 ctx := testCcWithConfig(t, config) 1242 1243 // Check Recovery snapshot output. 1244 1245 snapshotDir := "recovery-snapshot" 1246 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1247 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") 1248 1249 var jsonFiles []string 1250 1251 for _, arch := range [][]string{ 1252 []string{"arm64", "armv8-a"}, 1253 } { 1254 archType := arch[0] 1255 archVariant := arch[1] 1256 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1257 1258 // For shared libraries, only recovery_available modules are captured. 1259 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) 1260 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1261 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant) 1262 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) 1263 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) 1264 jsonFiles = append(jsonFiles, 1265 filepath.Join(sharedDir, "libvndk.so.json"), 1266 filepath.Join(sharedDir, "librecovery.so.json"), 1267 filepath.Join(sharedDir, "librecovery_available.so.json")) 1268 1269 // For static libraries, all recovery:true and recovery_available modules are captured. 1270 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant) 1271 staticDir := filepath.Join(snapshotVariantPath, archDir, "static") 1272 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) 1273 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant) 1274 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant) 1275 jsonFiles = append(jsonFiles, 1276 filepath.Join(staticDir, "libb.a.json"), 1277 filepath.Join(staticDir, "librecovery.a.json"), 1278 filepath.Join(staticDir, "librecovery_available.a.json")) 1279 1280 // For binary executables, all recovery:true and recovery_available modules are captured. 1281 if archType == "arm64" { 1282 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) 1283 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") 1284 checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant) 1285 checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant) 1286 jsonFiles = append(jsonFiles, 1287 filepath.Join(binaryDir, "recovery_bin.json"), 1288 filepath.Join(binaryDir, "recovery_available_bin.json")) 1289 } 1290 1291 // For header libraries, all vendor:true and vendor_available modules are captured. 1292 headerDir := filepath.Join(snapshotVariantPath, archDir, "header") 1293 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json")) 1294 1295 // For object modules, all vendor:true and vendor_available modules are captured. 1296 objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant) 1297 objectDir := filepath.Join(snapshotVariantPath, archDir, "object") 1298 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) 1299 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) 1300 } 1301 1302 for _, jsonFile := range jsonFiles { 1303 // verify all json files exist 1304 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1305 t.Errorf("%q expected but not found", jsonFile) 1306 } 1307 } 1308} 1309 1310func TestRecoverySnapshotExclude(t *testing.T) { 1311 // This test verifies that the exclude_from_recovery_snapshot property 1312 // makes its way from the Android.bp source file into the module data 1313 // structure. It also verifies that modules are correctly included or 1314 // excluded in the recovery snapshot based on their path (framework or 1315 // vendor) and the exclude_from_recovery_snapshot property. 1316 1317 frameworkBp := ` 1318 cc_library_shared { 1319 name: "libinclude", 1320 srcs: ["src/include.cpp"], 1321 recovery_available: true, 1322 } 1323 cc_library_shared { 1324 name: "libexclude", 1325 srcs: ["src/exclude.cpp"], 1326 recovery: true, 1327 exclude_from_recovery_snapshot: true, 1328 } 1329 cc_library_shared { 1330 name: "libavailable_exclude", 1331 srcs: ["src/exclude.cpp"], 1332 recovery_available: true, 1333 exclude_from_recovery_snapshot: true, 1334 } 1335 ` 1336 1337 vendorProprietaryBp := ` 1338 cc_library_shared { 1339 name: "librecovery", 1340 srcs: ["recovery.cpp"], 1341 recovery: true, 1342 } 1343 ` 1344 1345 depsBp := GatherRequiredDepsForTest(android.Android) 1346 1347 mockFS := map[string][]byte{ 1348 "deps/Android.bp": []byte(depsBp), 1349 "framework/Android.bp": []byte(frameworkBp), 1350 "framework/include.cpp": nil, 1351 "framework/exclude.cpp": nil, 1352 "device/Android.bp": []byte(vendorProprietaryBp), 1353 "device/recovery.cpp": nil, 1354 } 1355 1356 config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS) 1357 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") 1358 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1359 ctx := CreateTestContext(config) 1360 ctx.Register() 1361 1362 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"}) 1363 android.FailIfErrored(t, errs) 1364 _, errs = ctx.PrepareBuildActions(config) 1365 android.FailIfErrored(t, errs) 1366 1367 // Test an include and exclude framework module. 1368 assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false) 1369 assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true) 1370 assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true) 1371 1372 // A recovery module is excluded, but by its path, not the 1373 // exclude_from_recovery_snapshot property. 1374 assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false) 1375 1376 // Verify the content of the recovery snapshot. 1377 1378 snapshotDir := "recovery-snapshot" 1379 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1380 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") 1381 1382 var includeJsonFiles []string 1383 var excludeJsonFiles []string 1384 1385 for _, arch := range [][]string{ 1386 []string{"arm64", "armv8-a"}, 1387 } { 1388 archType := arch[0] 1389 archVariant := arch[1] 1390 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1391 1392 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) 1393 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1394 1395 // Included modules 1396 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant) 1397 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json")) 1398 1399 // Excluded modules 1400 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant) 1401 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json")) 1402 checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) 1403 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) 1404 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant) 1405 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json")) 1406 } 1407 1408 // Verify that each json file for an included module has a rule. 1409 for _, jsonFile := range includeJsonFiles { 1410 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1411 t.Errorf("include json file %q not found", jsonFile) 1412 } 1413 } 1414 1415 // Verify that each json file for an excluded module has no rule. 1416 for _, jsonFile := range excludeJsonFiles { 1417 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil { 1418 t.Errorf("exclude json file %q found", jsonFile) 1419 } 1420 } 1421} 1422 1423func TestRecoverySnapshotDirected(t *testing.T) { 1424 bp := ` 1425 cc_library_shared { 1426 name: "librecovery", 1427 recovery: true, 1428 nocrt: true, 1429 } 1430 1431 cc_library_shared { 1432 name: "librecovery_available", 1433 recovery_available: true, 1434 nocrt: true, 1435 } 1436 1437 genrule { 1438 name: "libfoo_gen", 1439 cmd: "", 1440 out: ["libfoo.so"], 1441 } 1442 1443 cc_prebuilt_library_shared { 1444 name: "libfoo", 1445 recovery: true, 1446 prefer: true, 1447 srcs: [":libfoo_gen"], 1448 } 1449 1450 cc_library_shared { 1451 name: "libfoo", 1452 recovery: true, 1453 nocrt: true, 1454 } 1455` 1456 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 1457 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 1458 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current") 1459 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1460 config.TestProductVariables.DirectedRecoverySnapshot = true 1461 config.TestProductVariables.RecoverySnapshotModules = make(map[string]bool) 1462 config.TestProductVariables.RecoverySnapshotModules["librecovery"] = true 1463 config.TestProductVariables.RecoverySnapshotModules["libfoo"] = true 1464 ctx := testCcWithConfig(t, config) 1465 1466 // Check recovery snapshot output. 1467 1468 snapshotDir := "recovery-snapshot" 1469 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 1470 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot") 1471 1472 var includeJsonFiles []string 1473 1474 for _, arch := range [][]string{ 1475 []string{"arm64", "armv8-a"}, 1476 } { 1477 archType := arch[0] 1478 archVariant := arch[1] 1479 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant) 1480 1481 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant) 1482 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") 1483 1484 // Included modules 1485 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant) 1486 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json")) 1487 // Check that snapshot captures "prefer: true" prebuilt 1488 checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant) 1489 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json")) 1490 1491 // Excluded modules. Modules not included in the directed recovery snapshot 1492 // are still include as fake modules. 1493 checkSnapshotRule(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant) 1494 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librecovery_available.so.json")) 1495 } 1496 1497 // Verify that each json file for an included module has a rule. 1498 for _, jsonFile := range includeJsonFiles { 1499 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { 1500 t.Errorf("include json file %q not found", jsonFile) 1501 } 1502 } 1503} 1504