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