github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/cc/cc_test.go (about) 1 // Copyright 2017 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 15 package cc 16 17 import ( 18 "android/soong/android" 19 "android/soong/genrule" 20 21 "fmt" 22 "io/ioutil" 23 "os" 24 "reflect" 25 "sort" 26 "strings" 27 "testing" 28 ) 29 30 var buildDir string 31 32 func setUp() { 33 var err error 34 buildDir, err = ioutil.TempDir("", "soong_cc_test") 35 if err != nil { 36 panic(err) 37 } 38 } 39 40 func tearDown() { 41 os.RemoveAll(buildDir) 42 } 43 44 func TestMain(m *testing.M) { 45 run := func() int { 46 setUp() 47 defer tearDown() 48 49 return m.Run() 50 } 51 52 os.Exit(run()) 53 } 54 55 func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext { 56 ctx := android.NewTestArchContext() 57 ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory)) 58 ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory)) 59 ctx.RegisterModuleType("cc_library_headers", android.ModuleFactoryAdaptor(LibraryHeaderFactory)) 60 ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(toolchainLibraryFactory)) 61 ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(llndkLibraryFactory)) 62 ctx.RegisterModuleType("llndk_headers", android.ModuleFactoryAdaptor(llndkHeadersFactory)) 63 ctx.RegisterModuleType("vendor_public_library", android.ModuleFactoryAdaptor(vendorPublicLibraryFactory)) 64 ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(objectFactory)) 65 ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(genrule.FileGroupFactory)) 66 ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { 67 ctx.BottomUp("image", vendorMutator).Parallel() 68 ctx.BottomUp("link", linkageMutator).Parallel() 69 ctx.BottomUp("vndk", vndkMutator).Parallel() 70 ctx.BottomUp("begin", beginMutator).Parallel() 71 }) 72 ctx.Register() 73 74 // add some modules that are required by the compiler and/or linker 75 bp = bp + ` 76 toolchain_library { 77 name: "libatomic", 78 vendor_available: true, 79 } 80 81 toolchain_library { 82 name: "libcompiler_rt-extras", 83 vendor_available: true, 84 } 85 86 toolchain_library { 87 name: "libgcc", 88 vendor_available: true, 89 } 90 91 cc_library { 92 name: "libc", 93 no_libgcc: true, 94 nocrt: true, 95 system_shared_libs: [], 96 } 97 llndk_library { 98 name: "libc", 99 symbol_file: "", 100 } 101 cc_library { 102 name: "libm", 103 no_libgcc: true, 104 nocrt: true, 105 system_shared_libs: [], 106 } 107 llndk_library { 108 name: "libm", 109 symbol_file: "", 110 } 111 cc_library { 112 name: "libdl", 113 no_libgcc: true, 114 nocrt: true, 115 system_shared_libs: [], 116 } 117 llndk_library { 118 name: "libdl", 119 symbol_file: "", 120 } 121 cc_library { 122 name: "libc++_static", 123 no_libgcc: true, 124 nocrt: true, 125 system_shared_libs: [], 126 stl: "none", 127 vendor_available: true, 128 } 129 cc_library { 130 name: "libc++", 131 no_libgcc: true, 132 nocrt: true, 133 system_shared_libs: [], 134 stl: "none", 135 vendor_available: true, 136 vndk: { 137 enabled: true, 138 support_system_process: true, 139 }, 140 } 141 cc_library { 142 name: "libunwind_llvm", 143 no_libgcc: true, 144 nocrt: true, 145 system_shared_libs: [], 146 stl: "none", 147 vendor_available: true, 148 } 149 150 cc_object { 151 name: "crtbegin_so", 152 } 153 154 cc_object { 155 name: "crtend_so", 156 } 157 158 cc_library { 159 name: "libprotobuf-cpp-lite", 160 } 161 162 ` 163 164 ctx.MockFileSystem(map[string][]byte{ 165 "Android.bp": []byte(bp), 166 "foo.c": nil, 167 "bar.c": nil, 168 "a.proto": nil, 169 "b.aidl": nil, 170 "my_include": nil, 171 }) 172 173 return ctx 174 } 175 176 func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext { 177 t.Helper() 178 ctx := createTestContext(t, config, bp) 179 180 _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) 181 android.FailIfErrored(t, errs) 182 _, errs = ctx.PrepareBuildActions(config) 183 android.FailIfErrored(t, errs) 184 185 return ctx 186 } 187 188 func testCc(t *testing.T, bp string) *android.TestContext { 189 t.Helper() 190 config := android.TestArchConfig(buildDir, nil) 191 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 192 config.TestProductVariables.Platform_vndk_version = StringPtr("VER") 193 194 return testCcWithConfig(t, bp, config) 195 } 196 197 func testCcNoVndk(t *testing.T, bp string) *android.TestContext { 198 t.Helper() 199 config := android.TestArchConfig(buildDir, nil) 200 config.TestProductVariables.Platform_vndk_version = StringPtr("VER") 201 202 return testCcWithConfig(t, bp, config) 203 } 204 205 func testCcError(t *testing.T, pattern string, bp string) { 206 t.Helper() 207 config := android.TestArchConfig(buildDir, nil) 208 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 209 config.TestProductVariables.Platform_vndk_version = StringPtr("VER") 210 211 ctx := createTestContext(t, config, bp) 212 213 _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) 214 if len(errs) > 0 { 215 android.FailIfNoMatchingErrors(t, pattern, errs) 216 return 217 } 218 219 _, errs = ctx.PrepareBuildActions(config) 220 if len(errs) > 0 { 221 android.FailIfNoMatchingErrors(t, pattern, errs) 222 return 223 } 224 225 t.Fatalf("missing expected error %q (0 errors are returned)", pattern) 226 } 227 228 const ( 229 coreVariant = "android_arm64_armv8-a_core_shared" 230 vendorVariant = "android_arm64_armv8-a_vendor_shared" 231 ) 232 233 func TestVendorSrc(t *testing.T) { 234 ctx := testCc(t, ` 235 cc_library { 236 name: "libTest", 237 srcs: ["foo.c"], 238 no_libgcc: true, 239 nocrt: true, 240 system_shared_libs: [], 241 vendor_available: true, 242 target: { 243 vendor: { 244 srcs: ["bar.c"], 245 }, 246 }, 247 } 248 `) 249 250 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld") 251 var objs []string 252 for _, o := range ld.Inputs { 253 objs = append(objs, o.Base()) 254 } 255 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" { 256 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs) 257 } 258 } 259 260 func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string, 261 isVndkSp bool, extends string) { 262 263 t.Helper() 264 265 mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module) 266 if !mod.hasVendorVariant() { 267 t.Errorf("%q must have vendor variant", name) 268 } 269 270 // Check library properties. 271 lib, ok := mod.compiler.(*libraryDecorator) 272 if !ok { 273 t.Errorf("%q must have libraryDecorator", name) 274 } else if lib.baseInstaller.subDir != subDir { 275 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir, 276 lib.baseInstaller.subDir) 277 } 278 279 // Check VNDK properties. 280 if mod.vndkdep == nil { 281 t.Fatalf("%q must have `vndkdep`", name) 282 } 283 if !mod.isVndk() { 284 t.Errorf("%q isVndk() must equal to true", name) 285 } 286 if mod.isVndkSp() != isVndkSp { 287 t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp) 288 } 289 290 // Check VNDK extension properties. 291 isVndkExt := extends != "" 292 if mod.isVndkExt() != isVndkExt { 293 t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt) 294 } 295 296 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends { 297 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends) 298 } 299 } 300 301 func TestVndk(t *testing.T) { 302 ctx := testCc(t, ` 303 cc_library { 304 name: "libvndk", 305 vendor_available: true, 306 vndk: { 307 enabled: true, 308 }, 309 nocrt: true, 310 } 311 312 cc_library { 313 name: "libvndk_private", 314 vendor_available: false, 315 vndk: { 316 enabled: true, 317 }, 318 nocrt: true, 319 } 320 321 cc_library { 322 name: "libvndk_sp", 323 vendor_available: true, 324 vndk: { 325 enabled: true, 326 support_system_process: true, 327 }, 328 nocrt: true, 329 } 330 331 cc_library { 332 name: "libvndk_sp_private", 333 vendor_available: false, 334 vndk: { 335 enabled: true, 336 support_system_process: true, 337 }, 338 nocrt: true, 339 } 340 `) 341 342 checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "") 343 checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "") 344 checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "") 345 checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "") 346 } 347 348 func TestVndkDepError(t *testing.T) { 349 // Check whether an error is emitted when a VNDK lib depends on a system lib. 350 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 351 cc_library { 352 name: "libvndk", 353 vendor_available: true, 354 vndk: { 355 enabled: true, 356 }, 357 shared_libs: ["libfwk"], // Cause error 358 nocrt: true, 359 } 360 361 cc_library { 362 name: "libfwk", 363 nocrt: true, 364 } 365 `) 366 367 // Check whether an error is emitted when a VNDK lib depends on a vendor lib. 368 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 369 cc_library { 370 name: "libvndk", 371 vendor_available: true, 372 vndk: { 373 enabled: true, 374 }, 375 shared_libs: ["libvendor"], // Cause error 376 nocrt: true, 377 } 378 379 cc_library { 380 name: "libvendor", 381 vendor: true, 382 nocrt: true, 383 } 384 `) 385 386 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib. 387 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 388 cc_library { 389 name: "libvndk_sp", 390 vendor_available: true, 391 vndk: { 392 enabled: true, 393 support_system_process: true, 394 }, 395 shared_libs: ["libfwk"], // Cause error 396 nocrt: true, 397 } 398 399 cc_library { 400 name: "libfwk", 401 nocrt: true, 402 } 403 `) 404 405 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib. 406 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 407 cc_library { 408 name: "libvndk_sp", 409 vendor_available: true, 410 vndk: { 411 enabled: true, 412 support_system_process: true, 413 }, 414 shared_libs: ["libvendor"], // Cause error 415 nocrt: true, 416 } 417 418 cc_library { 419 name: "libvendor", 420 vendor: true, 421 nocrt: true, 422 } 423 `) 424 425 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib. 426 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 427 cc_library { 428 name: "libvndk_sp", 429 vendor_available: true, 430 vndk: { 431 enabled: true, 432 support_system_process: true, 433 }, 434 shared_libs: ["libvndk"], // Cause error 435 nocrt: true, 436 } 437 438 cc_library { 439 name: "libvndk", 440 vendor_available: true, 441 vndk: { 442 enabled: true, 443 }, 444 nocrt: true, 445 } 446 `) 447 } 448 449 func TestVndkExt(t *testing.T) { 450 // This test checks the VNDK-Ext properties. 451 ctx := testCc(t, ` 452 cc_library { 453 name: "libvndk", 454 vendor_available: true, 455 vndk: { 456 enabled: true, 457 }, 458 nocrt: true, 459 } 460 461 cc_library { 462 name: "libvndk_ext", 463 vendor: true, 464 vndk: { 465 enabled: true, 466 extends: "libvndk", 467 }, 468 nocrt: true, 469 } 470 `) 471 472 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk") 473 } 474 475 func TestVndkExtWithoutBoardVndkVersion(t *testing.T) { 476 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set. 477 ctx := testCcNoVndk(t, ` 478 cc_library { 479 name: "libvndk", 480 vendor_available: true, 481 vndk: { 482 enabled: true, 483 }, 484 nocrt: true, 485 } 486 487 cc_library { 488 name: "libvndk_ext", 489 vendor: true, 490 vndk: { 491 enabled: true, 492 extends: "libvndk", 493 }, 494 nocrt: true, 495 } 496 `) 497 498 // Ensures that the core variant of "libvndk_ext" can be found. 499 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module) 500 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" { 501 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends) 502 } 503 } 504 505 func TestVndkExtError(t *testing.T) { 506 // This test ensures an error is emitted in ill-formed vndk-ext definition. 507 testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", ` 508 cc_library { 509 name: "libvndk", 510 vendor_available: true, 511 vndk: { 512 enabled: true, 513 }, 514 nocrt: true, 515 } 516 517 cc_library { 518 name: "libvndk_ext", 519 vndk: { 520 enabled: true, 521 extends: "libvndk", 522 }, 523 nocrt: true, 524 } 525 `) 526 527 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", ` 528 cc_library { 529 name: "libvndk", 530 vendor_available: true, 531 vndk: { 532 enabled: true, 533 }, 534 nocrt: true, 535 } 536 537 cc_library { 538 name: "libvndk_ext", 539 vendor: true, 540 vndk: { 541 enabled: true, 542 }, 543 nocrt: true, 544 } 545 `) 546 } 547 548 func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) { 549 // This test ensures an error is emitted for inconsistent support_system_process. 550 testCcError(t, "module \".*\" with mismatched support_system_process", ` 551 cc_library { 552 name: "libvndk", 553 vendor_available: true, 554 vndk: { 555 enabled: true, 556 }, 557 nocrt: true, 558 } 559 560 cc_library { 561 name: "libvndk_sp_ext", 562 vendor: true, 563 vndk: { 564 enabled: true, 565 extends: "libvndk", 566 support_system_process: true, 567 }, 568 nocrt: true, 569 } 570 `) 571 572 testCcError(t, "module \".*\" with mismatched support_system_process", ` 573 cc_library { 574 name: "libvndk_sp", 575 vendor_available: true, 576 vndk: { 577 enabled: true, 578 support_system_process: true, 579 }, 580 nocrt: true, 581 } 582 583 cc_library { 584 name: "libvndk_ext", 585 vendor: true, 586 vndk: { 587 enabled: true, 588 extends: "libvndk_sp", 589 }, 590 nocrt: true, 591 } 592 `) 593 } 594 595 func TestVndkExtVendorAvailableFalseError(t *testing.T) { 596 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library 597 // with `vendor_available: false`. 598 testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", ` 599 cc_library { 600 name: "libvndk", 601 vendor_available: false, 602 vndk: { 603 enabled: true, 604 }, 605 nocrt: true, 606 } 607 608 cc_library { 609 name: "libvndk_ext", 610 vendor: true, 611 vndk: { 612 enabled: true, 613 extends: "libvndk", 614 }, 615 nocrt: true, 616 } 617 `) 618 } 619 620 func TestVendorModuleUseVndkExt(t *testing.T) { 621 // This test ensures a vendor module can depend on a VNDK-Ext library. 622 testCc(t, ` 623 cc_library { 624 name: "libvndk", 625 vendor_available: true, 626 vndk: { 627 enabled: true, 628 }, 629 nocrt: true, 630 } 631 632 cc_library { 633 name: "libvndk_ext", 634 vendor: true, 635 vndk: { 636 enabled: true, 637 extends: "libvndk", 638 }, 639 nocrt: true, 640 } 641 642 cc_library { 643 644 name: "libvndk_sp", 645 vendor_available: true, 646 vndk: { 647 enabled: true, 648 support_system_process: true, 649 }, 650 nocrt: true, 651 } 652 653 cc_library { 654 name: "libvndk_sp_ext", 655 vendor: true, 656 vndk: { 657 enabled: true, 658 extends: "libvndk_sp", 659 support_system_process: true, 660 }, 661 nocrt: true, 662 } 663 664 cc_library { 665 name: "libvendor", 666 vendor: true, 667 shared_libs: ["libvndk_ext", "libvndk_sp_ext"], 668 nocrt: true, 669 } 670 `) 671 } 672 673 func TestVndkExtUseVendorLib(t *testing.T) { 674 // This test ensures a VNDK-Ext library can depend on a vendor library. 675 testCc(t, ` 676 cc_library { 677 name: "libvndk", 678 vendor_available: true, 679 vndk: { 680 enabled: true, 681 }, 682 nocrt: true, 683 } 684 685 cc_library { 686 name: "libvndk_ext", 687 vendor: true, 688 vndk: { 689 enabled: true, 690 extends: "libvndk", 691 }, 692 shared_libs: ["libvendor"], 693 nocrt: true, 694 } 695 696 cc_library { 697 name: "libvendor", 698 vendor: true, 699 nocrt: true, 700 } 701 `) 702 703 // This test ensures a VNDK-SP-Ext library can depend on a vendor library. 704 testCc(t, ` 705 cc_library { 706 name: "libvndk_sp", 707 vendor_available: true, 708 vndk: { 709 enabled: true, 710 support_system_process: true, 711 }, 712 nocrt: true, 713 } 714 715 cc_library { 716 name: "libvndk_sp_ext", 717 vendor: true, 718 vndk: { 719 enabled: true, 720 extends: "libvndk_sp", 721 support_system_process: true, 722 }, 723 shared_libs: ["libvendor"], // Cause an error 724 nocrt: true, 725 } 726 727 cc_library { 728 name: "libvendor", 729 vendor: true, 730 nocrt: true, 731 } 732 `) 733 } 734 735 func TestVndkSpExtUseVndkError(t *testing.T) { 736 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK 737 // library. 738 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 739 cc_library { 740 name: "libvndk", 741 vendor_available: true, 742 vndk: { 743 enabled: true, 744 }, 745 nocrt: true, 746 } 747 748 cc_library { 749 name: "libvndk_sp", 750 vendor_available: true, 751 vndk: { 752 enabled: true, 753 support_system_process: true, 754 }, 755 nocrt: true, 756 } 757 758 cc_library { 759 name: "libvndk_sp_ext", 760 vendor: true, 761 vndk: { 762 enabled: true, 763 extends: "libvndk_sp", 764 support_system_process: true, 765 }, 766 shared_libs: ["libvndk"], // Cause an error 767 nocrt: true, 768 } 769 `) 770 771 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext 772 // library. 773 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 774 cc_library { 775 name: "libvndk", 776 vendor_available: true, 777 vndk: { 778 enabled: true, 779 }, 780 nocrt: true, 781 } 782 783 cc_library { 784 name: "libvndk_ext", 785 vendor: true, 786 vndk: { 787 enabled: true, 788 extends: "libvndk", 789 }, 790 nocrt: true, 791 } 792 793 cc_library { 794 name: "libvndk_sp", 795 vendor_available: true, 796 vndk: { 797 enabled: true, 798 support_system_process: true, 799 }, 800 nocrt: true, 801 } 802 803 cc_library { 804 name: "libvndk_sp_ext", 805 vendor: true, 806 vndk: { 807 enabled: true, 808 extends: "libvndk_sp", 809 support_system_process: true, 810 }, 811 shared_libs: ["libvndk_ext"], // Cause an error 812 nocrt: true, 813 } 814 `) 815 } 816 817 func TestVndkUseVndkExtError(t *testing.T) { 818 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a 819 // VNDK-Ext/VNDK-SP-Ext library. 820 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 821 cc_library { 822 name: "libvndk", 823 vendor_available: true, 824 vndk: { 825 enabled: true, 826 }, 827 nocrt: true, 828 } 829 830 cc_library { 831 name: "libvndk_ext", 832 vendor: true, 833 vndk: { 834 enabled: true, 835 extends: "libvndk", 836 }, 837 nocrt: true, 838 } 839 840 cc_library { 841 name: "libvndk2", 842 vendor_available: true, 843 vndk: { 844 enabled: true, 845 }, 846 shared_libs: ["libvndk_ext"], 847 nocrt: true, 848 } 849 `) 850 851 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"" 852 // but target.vendor.shared_libs has not been supported yet. 853 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", ` 854 cc_library { 855 name: "libvndk", 856 vendor_available: true, 857 vndk: { 858 enabled: true, 859 }, 860 nocrt: true, 861 } 862 863 cc_library { 864 name: "libvndk_ext", 865 vendor: true, 866 vndk: { 867 enabled: true, 868 extends: "libvndk", 869 }, 870 nocrt: true, 871 } 872 873 cc_library { 874 name: "libvndk2", 875 vendor_available: true, 876 vndk: { 877 enabled: true, 878 }, 879 target: { 880 vendor: { 881 shared_libs: ["libvndk_ext"], 882 }, 883 }, 884 nocrt: true, 885 } 886 `) 887 888 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 889 cc_library { 890 name: "libvndk_sp", 891 vendor_available: true, 892 vndk: { 893 enabled: true, 894 support_system_process: true, 895 }, 896 nocrt: true, 897 } 898 899 cc_library { 900 name: "libvndk_sp_ext", 901 vendor: true, 902 vndk: { 903 enabled: true, 904 extends: "libvndk_sp", 905 support_system_process: true, 906 }, 907 nocrt: true, 908 } 909 910 cc_library { 911 name: "libvndk_sp_2", 912 vendor_available: true, 913 vndk: { 914 enabled: true, 915 support_system_process: true, 916 }, 917 shared_libs: ["libvndk_sp_ext"], 918 nocrt: true, 919 } 920 `) 921 922 // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"" 923 // but target.vendor.shared_libs has not been supported yet. 924 testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", ` 925 cc_library { 926 name: "libvndk_sp", 927 vendor_available: true, 928 vndk: { 929 enabled: true, 930 }, 931 nocrt: true, 932 } 933 934 cc_library { 935 name: "libvndk_sp_ext", 936 vendor: true, 937 vndk: { 938 enabled: true, 939 extends: "libvndk_sp", 940 }, 941 nocrt: true, 942 } 943 944 cc_library { 945 name: "libvndk_sp2", 946 vendor_available: true, 947 vndk: { 948 enabled: true, 949 }, 950 target: { 951 vendor: { 952 shared_libs: ["libvndk_sp_ext"], 953 }, 954 }, 955 nocrt: true, 956 } 957 `) 958 } 959 960 var ( 961 str11 = "01234567891" 962 str10 = str11[:10] 963 str9 = str11[:9] 964 str5 = str11[:5] 965 str4 = str11[:4] 966 ) 967 968 var splitListForSizeTestCases = []struct { 969 in []string 970 out [][]string 971 size int 972 }{ 973 { 974 in: []string{str10}, 975 out: [][]string{{str10}}, 976 size: 10, 977 }, 978 { 979 in: []string{str9}, 980 out: [][]string{{str9}}, 981 size: 10, 982 }, 983 { 984 in: []string{str5}, 985 out: [][]string{{str5}}, 986 size: 10, 987 }, 988 { 989 in: []string{str11}, 990 out: nil, 991 size: 10, 992 }, 993 { 994 in: []string{str10, str10}, 995 out: [][]string{{str10}, {str10}}, 996 size: 10, 997 }, 998 { 999 in: []string{str9, str10}, 1000 out: [][]string{{str9}, {str10}}, 1001 size: 10, 1002 }, 1003 { 1004 in: []string{str10, str9}, 1005 out: [][]string{{str10}, {str9}}, 1006 size: 10, 1007 }, 1008 { 1009 in: []string{str5, str4}, 1010 out: [][]string{{str5, str4}}, 1011 size: 10, 1012 }, 1013 { 1014 in: []string{str5, str4, str5}, 1015 out: [][]string{{str5, str4}, {str5}}, 1016 size: 10, 1017 }, 1018 { 1019 in: []string{str5, str4, str5, str4}, 1020 out: [][]string{{str5, str4}, {str5, str4}}, 1021 size: 10, 1022 }, 1023 { 1024 in: []string{str5, str4, str5, str5}, 1025 out: [][]string{{str5, str4}, {str5}, {str5}}, 1026 size: 10, 1027 }, 1028 { 1029 in: []string{str5, str5, str5, str4}, 1030 out: [][]string{{str5}, {str5}, {str5, str4}}, 1031 size: 10, 1032 }, 1033 { 1034 in: []string{str9, str11}, 1035 out: nil, 1036 size: 10, 1037 }, 1038 { 1039 in: []string{str11, str9}, 1040 out: nil, 1041 size: 10, 1042 }, 1043 } 1044 1045 func TestSplitListForSize(t *testing.T) { 1046 for _, testCase := range splitListForSizeTestCases { 1047 out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size) 1048 1049 var outStrings [][]string 1050 1051 if len(out) > 0 { 1052 outStrings = make([][]string, len(out)) 1053 for i, o := range out { 1054 outStrings[i] = o.Strings() 1055 } 1056 } 1057 1058 if !reflect.DeepEqual(outStrings, testCase.out) { 1059 t.Errorf("incorrect output:") 1060 t.Errorf(" input: %#v", testCase.in) 1061 t.Errorf(" size: %d", testCase.size) 1062 t.Errorf(" expected: %#v", testCase.out) 1063 t.Errorf(" got: %#v", outStrings) 1064 } 1065 } 1066 } 1067 1068 var staticLinkDepOrderTestCases = []struct { 1069 // This is a string representation of a map[moduleName][]moduleDependency . 1070 // It models the dependencies declared in an Android.bp file. 1071 inStatic string 1072 1073 // This is a string representation of a map[moduleName][]moduleDependency . 1074 // It models the dependencies declared in an Android.bp file. 1075 inShared string 1076 1077 // allOrdered is a string representation of a map[moduleName][]moduleDependency . 1078 // The keys of allOrdered specify which modules we would like to check. 1079 // The values of allOrdered specify the expected result (of the transitive closure of all 1080 // dependencies) for each module to test 1081 allOrdered string 1082 1083 // outOrdered is a string representation of a map[moduleName][]moduleDependency . 1084 // The keys of outOrdered specify which modules we would like to check. 1085 // The values of outOrdered specify the expected result (of the ordered linker command line) 1086 // for each module to test. 1087 outOrdered string 1088 }{ 1089 // Simple tests 1090 { 1091 inStatic: "", 1092 outOrdered: "", 1093 }, 1094 { 1095 inStatic: "a:", 1096 outOrdered: "a:", 1097 }, 1098 { 1099 inStatic: "a:b; b:", 1100 outOrdered: "a:b; b:", 1101 }, 1102 // Tests of reordering 1103 { 1104 // diamond example 1105 inStatic: "a:d,b,c; b:d; c:d; d:", 1106 outOrdered: "a:b,c,d; b:d; c:d; d:", 1107 }, 1108 { 1109 // somewhat real example 1110 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b", 1111 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b", 1112 }, 1113 { 1114 // multiple reorderings 1115 inStatic: "a:b,c,d,e; d:b; e:c", 1116 outOrdered: "a:d,b,e,c; d:b; e:c", 1117 }, 1118 { 1119 // should reorder without adding new transitive dependencies 1120 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional", 1121 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional", 1122 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional", 1123 }, 1124 { 1125 // multiple levels of dependencies 1126 inStatic: "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d", 1127 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d", 1128 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d", 1129 }, 1130 // shared dependencies 1131 { 1132 // Note that this test doesn't recurse, to minimize the amount of logic it tests. 1133 // So, we don't actually have to check that a shared dependency of c will change the order 1134 // of a library that depends statically on b and on c. We only need to check that if c has 1135 // a shared dependency on b, that that shows up in allOrdered. 1136 inShared: "c:b", 1137 allOrdered: "c:b", 1138 outOrdered: "c:", 1139 }, 1140 { 1141 // This test doesn't actually include any shared dependencies but it's a reminder of what 1142 // the second phase of the above test would look like 1143 inStatic: "a:b,c; c:b", 1144 allOrdered: "a:c,b; c:b", 1145 outOrdered: "a:c,b; c:b", 1146 }, 1147 // tiebreakers for when two modules specifying different orderings and there is no dependency 1148 // to dictate an order 1149 { 1150 // if the tie is between two modules at the end of a's deps, then a's order wins 1151 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d", 1152 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d", 1153 }, 1154 { 1155 // if the tie is between two modules at the start of a's deps, then c's order is used 1156 inStatic: "a1:d,e,b1,c1; b1:d,e; c1:e,d; a2:d,e,b2,c2; b2:d,e; c2:d,e", 1157 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e", 1158 }, 1159 // Tests involving duplicate dependencies 1160 { 1161 // simple duplicate 1162 inStatic: "a:b,c,c,b", 1163 outOrdered: "a:c,b", 1164 }, 1165 { 1166 // duplicates with reordering 1167 inStatic: "a:b,c,d,c; c:b", 1168 outOrdered: "a:d,c,b", 1169 }, 1170 // Tests to confirm the nonexistence of infinite loops. 1171 // These cases should never happen, so as long as the test terminates and the 1172 // result is deterministic then that should be fine. 1173 { 1174 inStatic: "a:a", 1175 outOrdered: "a:a", 1176 }, 1177 { 1178 inStatic: "a:b; b:c; c:a", 1179 allOrdered: "a:b,c; b:c,a; c:a,b", 1180 outOrdered: "a:b; b:c; c:a", 1181 }, 1182 { 1183 inStatic: "a:b,c; b:c,a; c:a,b", 1184 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a", 1185 outOrdered: "a:c,b; b:a,c; c:b,a", 1186 }, 1187 } 1188 1189 // converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}]) 1190 func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) { 1191 // convert from "a:b,c; d:e" to "a:b,c;d:e" 1192 strippedText := strings.Replace(text, " ", "", -1) 1193 if len(strippedText) < 1 { 1194 return []android.Path{}, make(map[android.Path][]android.Path, 0) 1195 } 1196 allDeps = make(map[android.Path][]android.Path, 0) 1197 1198 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"] 1199 moduleTexts := strings.Split(strippedText, ";") 1200 1201 outputForModuleName := func(moduleName string) android.Path { 1202 return android.PathForTesting(moduleName) 1203 } 1204 1205 for _, moduleText := range moduleTexts { 1206 // convert from "a:b,c" to ["a", "b,c"] 1207 components := strings.Split(moduleText, ":") 1208 if len(components) != 2 { 1209 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1)) 1210 } 1211 moduleName := components[0] 1212 moduleOutput := outputForModuleName(moduleName) 1213 modulesInOrder = append(modulesInOrder, moduleOutput) 1214 1215 depString := components[1] 1216 // convert from "b,c" to ["b", "c"] 1217 depNames := strings.Split(depString, ",") 1218 if len(depString) < 1 { 1219 depNames = []string{} 1220 } 1221 var deps []android.Path 1222 for _, depName := range depNames { 1223 deps = append(deps, outputForModuleName(depName)) 1224 } 1225 allDeps[moduleOutput] = deps 1226 } 1227 return modulesInOrder, allDeps 1228 } 1229 1230 func TestLinkReordering(t *testing.T) { 1231 for _, testCase := range staticLinkDepOrderTestCases { 1232 errs := []string{} 1233 1234 // parse testcase 1235 _, givenTransitiveDeps := parseModuleDeps(testCase.inStatic) 1236 expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered) 1237 if testCase.allOrdered == "" { 1238 // allow the test case to skip specifying allOrdered 1239 testCase.allOrdered = testCase.outOrdered 1240 } 1241 _, expectedAllDeps := parseModuleDeps(testCase.allOrdered) 1242 _, givenAllSharedDeps := parseModuleDeps(testCase.inShared) 1243 1244 // For each module whose post-reordered dependencies were specified, validate that 1245 // reordering the inputs produces the expected outputs. 1246 for _, moduleName := range expectedModuleNames { 1247 moduleDeps := givenTransitiveDeps[moduleName] 1248 givenSharedDeps := givenAllSharedDeps[moduleName] 1249 orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps) 1250 1251 correctAllOrdered := expectedAllDeps[moduleName] 1252 if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) { 1253 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+ 1254 "\nin static:%q"+ 1255 "\nin shared:%q"+ 1256 "\nmodule: %v"+ 1257 "\nexpected: %s"+ 1258 "\nactual: %s", 1259 testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps)) 1260 } 1261 1262 correctOutputDeps := expectedTransitiveDeps[moduleName] 1263 if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) { 1264 errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+ 1265 "\nin static:%q"+ 1266 "\nin shared:%q"+ 1267 "\nmodule: %v"+ 1268 "\nexpected: %s"+ 1269 "\nactual: %s", 1270 testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps)) 1271 } 1272 } 1273 1274 if len(errs) > 0 { 1275 sort.Strings(errs) 1276 for _, err := range errs { 1277 t.Error(err) 1278 } 1279 } 1280 } 1281 } 1282 1283 func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) { 1284 for _, moduleName := range moduleNames { 1285 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module) 1286 output := module.outputFile.Path() 1287 paths = append(paths, output) 1288 } 1289 return paths 1290 } 1291 1292 func TestStaticLibDepReordering(t *testing.T) { 1293 ctx := testCc(t, ` 1294 cc_library { 1295 name: "a", 1296 static_libs: ["b", "c", "d"], 1297 stl: "none", 1298 } 1299 cc_library { 1300 name: "b", 1301 stl: "none", 1302 } 1303 cc_library { 1304 name: "c", 1305 static_libs: ["b"], 1306 stl: "none", 1307 } 1308 cc_library { 1309 name: "d", 1310 stl: "none", 1311 } 1312 1313 `) 1314 1315 variant := "android_arm64_armv8-a_core_static" 1316 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) 1317 actual := moduleA.depsInLinkOrder 1318 expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"}) 1319 1320 if !reflect.DeepEqual(actual, expected) { 1321 t.Errorf("staticDeps orderings were not propagated correctly"+ 1322 "\nactual: %v"+ 1323 "\nexpected: %v", 1324 actual, 1325 expected, 1326 ) 1327 } 1328 } 1329 1330 func TestStaticLibDepReorderingWithShared(t *testing.T) { 1331 ctx := testCc(t, ` 1332 cc_library { 1333 name: "a", 1334 static_libs: ["b", "c"], 1335 stl: "none", 1336 } 1337 cc_library { 1338 name: "b", 1339 stl: "none", 1340 } 1341 cc_library { 1342 name: "c", 1343 shared_libs: ["b"], 1344 stl: "none", 1345 } 1346 1347 `) 1348 1349 variant := "android_arm64_armv8-a_core_static" 1350 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) 1351 actual := moduleA.depsInLinkOrder 1352 expected := getOutputPaths(ctx, variant, []string{"c", "b"}) 1353 1354 if !reflect.DeepEqual(actual, expected) { 1355 t.Errorf("staticDeps orderings did not account for shared libs"+ 1356 "\nactual: %v"+ 1357 "\nexpected: %v", 1358 actual, 1359 expected, 1360 ) 1361 } 1362 } 1363 1364 func TestLlndkHeaders(t *testing.T) { 1365 ctx := testCc(t, ` 1366 llndk_headers { 1367 name: "libllndk_headers", 1368 export_include_dirs: ["my_include"], 1369 } 1370 llndk_library { 1371 name: "libllndk", 1372 export_llndk_headers: ["libllndk_headers"], 1373 } 1374 cc_library { 1375 name: "libvendor", 1376 shared_libs: ["libllndk"], 1377 vendor: true, 1378 srcs: ["foo.c"], 1379 no_libgcc: true, 1380 nocrt: true, 1381 } 1382 `) 1383 1384 // _static variant is used since _shared reuses *.o from the static variant 1385 cc := ctx.ModuleForTests("libvendor", "android_arm_armv7-a-neon_vendor_static").Rule("cc") 1386 cflags := cc.Args["cFlags"] 1387 if !strings.Contains(cflags, "-Imy_include") { 1388 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags) 1389 } 1390 } 1391 1392 var compilerFlagsTestCases = []struct { 1393 in string 1394 out bool 1395 }{ 1396 { 1397 in: "a", 1398 out: false, 1399 }, 1400 { 1401 in: "-a", 1402 out: true, 1403 }, 1404 { 1405 in: "-Ipath/to/something", 1406 out: false, 1407 }, 1408 { 1409 in: "-isystempath/to/something", 1410 out: false, 1411 }, 1412 { 1413 in: "--coverage", 1414 out: false, 1415 }, 1416 { 1417 in: "-include a/b", 1418 out: true, 1419 }, 1420 { 1421 in: "-include a/b c/d", 1422 out: false, 1423 }, 1424 { 1425 in: "-DMACRO", 1426 out: true, 1427 }, 1428 { 1429 in: "-DMAC RO", 1430 out: false, 1431 }, 1432 { 1433 in: "-a -b", 1434 out: false, 1435 }, 1436 { 1437 in: "-DMACRO=definition", 1438 out: true, 1439 }, 1440 { 1441 in: "-DMACRO=defi nition", 1442 out: true, // TODO(jiyong): this should be false 1443 }, 1444 { 1445 in: "-DMACRO(x)=x + 1", 1446 out: true, 1447 }, 1448 { 1449 in: "-DMACRO=\"defi nition\"", 1450 out: true, 1451 }, 1452 } 1453 1454 type mockContext struct { 1455 BaseModuleContext 1456 result bool 1457 } 1458 1459 func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 1460 // CheckBadCompilerFlags calls this function when the flag should be rejected 1461 ctx.result = false 1462 } 1463 1464 func TestCompilerFlags(t *testing.T) { 1465 for _, testCase := range compilerFlagsTestCases { 1466 ctx := &mockContext{result: true} 1467 CheckBadCompilerFlags(ctx, "", []string{testCase.in}) 1468 if ctx.result != testCase.out { 1469 t.Errorf("incorrect output:") 1470 t.Errorf(" input: %#v", testCase.in) 1471 t.Errorf(" expected: %#v", testCase.out) 1472 t.Errorf(" got: %#v", ctx.result) 1473 } 1474 } 1475 } 1476 1477 func TestVendorPublicLibraries(t *testing.T) { 1478 ctx := testCc(t, ` 1479 cc_library_headers { 1480 name: "libvendorpublic_headers", 1481 export_include_dirs: ["my_include"], 1482 } 1483 vendor_public_library { 1484 name: "libvendorpublic", 1485 symbol_file: "", 1486 export_public_headers: ["libvendorpublic_headers"], 1487 } 1488 cc_library { 1489 name: "libvendorpublic", 1490 srcs: ["foo.c"], 1491 vendor: true, 1492 no_libgcc: true, 1493 nocrt: true, 1494 } 1495 1496 cc_library { 1497 name: "libsystem", 1498 shared_libs: ["libvendorpublic"], 1499 vendor: false, 1500 srcs: ["foo.c"], 1501 no_libgcc: true, 1502 nocrt: true, 1503 } 1504 cc_library { 1505 name: "libvendor", 1506 shared_libs: ["libvendorpublic"], 1507 vendor: true, 1508 srcs: ["foo.c"], 1509 no_libgcc: true, 1510 nocrt: true, 1511 } 1512 `) 1513 1514 variant := "android_arm64_armv8-a_core_shared" 1515 1516 // test if header search paths are correctly added 1517 // _static variant is used since _shared reuses *.o from the static variant 1518 cc := ctx.ModuleForTests("libsystem", strings.Replace(variant, "_shared", "_static", 1)).Rule("cc") 1519 cflags := cc.Args["cFlags"] 1520 if !strings.Contains(cflags, "-Imy_include") { 1521 t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags) 1522 } 1523 1524 // test if libsystem is linked to the stub 1525 ld := ctx.ModuleForTests("libsystem", variant).Rule("ld") 1526 libflags := ld.Args["libFlags"] 1527 stubPaths := getOutputPaths(ctx, variant, []string{"libvendorpublic" + vendorPublicLibrarySuffix}) 1528 if !strings.Contains(libflags, stubPaths[0].String()) { 1529 t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags) 1530 } 1531 1532 // test if libvendor is linked to the real shared lib 1533 ld = ctx.ModuleForTests("libvendor", strings.Replace(variant, "_core", "_vendor", 1)).Rule("ld") 1534 libflags = ld.Args["libFlags"] 1535 stubPaths = getOutputPaths(ctx, strings.Replace(variant, "_core", "_vendor", 1), []string{"libvendorpublic"}) 1536 if !strings.Contains(libflags, stubPaths[0].String()) { 1537 t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags) 1538 } 1539 1540 }