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