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 15package cc 16 17import ( 18 "fmt" 19 "os" 20 "reflect" 21 "regexp" 22 "runtime" 23 "slices" 24 "strings" 25 "testing" 26 27 "android/soong/aidl_library" 28 "android/soong/android" 29 30 "github.com/google/blueprint" 31) 32 33func init() { 34 registerTestMutators(android.InitRegistrationContext) 35} 36 37func TestMain(m *testing.M) { 38 os.Exit(m.Run()) 39} 40 41var prepareForCcTest = android.GroupFixturePreparers( 42 PrepareForIntegrationTestWithCc, 43) 44 45var apexVariationName = "apex28" 46var apexVersion = "28" 47 48func registerTestMutators(ctx android.RegistrationContext) { 49 ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { 50 ctx.Transition("apex", &testApexTransitionMutator{}) 51 }) 52} 53 54type testApexTransitionMutator struct{} 55 56func (t *testApexTransitionMutator) Split(ctx android.BaseModuleContext) []string { 57 return []string{apexVariationName} 58} 59 60func (t *testApexTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { 61 return sourceVariation 62} 63 64func (t *testApexTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { 65 return incomingVariation 66} 67 68func (t *testApexTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { 69 apexInfo := android.ApexInfo{ 70 ApexVariationName: apexVariationName, 71 MinSdkVersion: android.ApiLevelForTest(apexVersion), 72 } 73 android.SetProvider(ctx, android.ApexInfoProvider, apexInfo) 74} 75 76// testCcWithConfig runs tests using the prepareForCcTest 77// 78// See testCc for an explanation as to how to stop using this deprecated method. 79// 80// deprecated 81func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext { 82 t.Helper() 83 result := prepareForCcTest.RunTestWithConfig(t, config) 84 return result.TestContext 85} 86 87// testCc runs tests using the prepareForCcTest 88// 89// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much 90// easier to customize the test behavior. 91// 92// If it is necessary to customize the behavior of an existing test that uses this then please first 93// convert the test to using prepareForCcTest first and then in a following change add the 94// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify 95// that it did not change the test behavior unexpectedly. 96// 97// deprecated 98func testCc(t *testing.T, bp string) *android.TestContext { 99 t.Helper() 100 result := prepareForCcTest.RunTestWithBp(t, bp) 101 return result.TestContext 102} 103 104// testCcErrorWithConfig runs tests using the prepareForCcTest 105// 106// See testCc for an explanation as to how to stop using this deprecated method. 107// 108// deprecated 109func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) { 110 t.Helper() 111 112 prepareForCcTest. 113 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 114 RunTestWithConfig(t, config) 115} 116 117// testCcError runs tests using the prepareForCcTest 118// 119// See testCc for an explanation as to how to stop using this deprecated method. 120// 121// deprecated 122func testCcError(t *testing.T, pattern string, bp string) { 123 t.Helper() 124 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 125 testCcErrorWithConfig(t, pattern, config) 126 return 127} 128 129const ( 130 coreVariant = "android_arm64_armv8-a_shared" 131 vendorVariant = "android_vendor_arm64_armv8-a_shared" 132 productVariant = "android_product_arm64_armv8-a_shared" 133 recoveryVariant = "android_recovery_arm64_armv8-a_shared" 134) 135 136// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by 137// running it in a fixture that requires all source files to exist. 138func TestPrepareForTestWithCcDefaultModules(t *testing.T) { 139 android.GroupFixturePreparers( 140 PrepareForTestWithCcDefaultModules, 141 android.PrepareForTestDisallowNonExistentPaths, 142 ).RunTest(t) 143} 144 145func TestVendorSrc(t *testing.T) { 146 t.Parallel() 147 ctx := testCc(t, ` 148 cc_library { 149 name: "libTest", 150 srcs: ["foo.c"], 151 no_libcrt: true, 152 nocrt: true, 153 system_shared_libs: [], 154 vendor_available: true, 155 target: { 156 vendor: { 157 srcs: ["bar.c"], 158 }, 159 }, 160 } 161 `) 162 163 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld") 164 var objs []string 165 for _, o := range ld.Inputs { 166 objs = append(objs, o.Base()) 167 } 168 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" { 169 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs) 170 } 171} 172 173func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) { 174 mod := ctx.ModuleForTests(name, variant).Module().(*Module) 175 partitionDefined := false 176 checkPartition := func(specific bool, partition string) { 177 if specific { 178 if expected != partition && !partitionDefined { 179 // The variant is installed to the 'partition' 180 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition) 181 } 182 partitionDefined = true 183 } else { 184 // The variant is not installed to the 'partition' 185 if expected == partition { 186 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition) 187 } 188 } 189 } 190 socSpecific := func(m *Module) bool { 191 return m.SocSpecific() || m.InstallInVendor() 192 } 193 deviceSpecific := func(m *Module) bool { 194 return m.DeviceSpecific() || m.InstallInOdm() 195 } 196 productSpecific := func(m *Module) bool { 197 return m.ProductSpecific() || m.InstallInProduct() 198 } 199 systemExtSpecific := func(m *Module) bool { 200 return m.SystemExtSpecific() 201 } 202 checkPartition(socSpecific(mod), "vendor") 203 checkPartition(deviceSpecific(mod), "odm") 204 checkPartition(productSpecific(mod), "product") 205 checkPartition(systemExtSpecific(mod), "system_ext") 206 if !partitionDefined && expected != "system" { 207 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+ 208 " but installed to system partition", variant, name, expected) 209 } 210} 211 212func TestInstallPartition(t *testing.T) { 213 t.Parallel() 214 t.Helper() 215 ctx := prepareForCcTest.RunTestWithBp(t, ` 216 cc_library { 217 name: "libsystem", 218 } 219 cc_library { 220 name: "libsystem_ext", 221 system_ext_specific: true, 222 } 223 cc_library { 224 name: "libproduct", 225 product_specific: true, 226 } 227 cc_library { 228 name: "libvendor", 229 vendor: true, 230 } 231 cc_library { 232 name: "libodm", 233 device_specific: true, 234 } 235 cc_library { 236 name: "liball_available", 237 vendor_available: true, 238 product_available: true, 239 } 240 cc_library { 241 name: "libsystem_ext_all_available", 242 system_ext_specific: true, 243 vendor_available: true, 244 product_available: true, 245 } 246 cc_library { 247 name: "liball_available_odm", 248 odm_available: true, 249 product_available: true, 250 } 251 cc_library { 252 name: "libproduct_vendoravailable", 253 product_specific: true, 254 vendor_available: true, 255 } 256 cc_library { 257 name: "libproduct_odmavailable", 258 product_specific: true, 259 odm_available: true, 260 } 261 `).TestContext 262 263 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system") 264 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext") 265 checkInstallPartition(t, ctx, "libproduct", productVariant, "product") 266 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor") 267 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm") 268 269 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system") 270 checkInstallPartition(t, ctx, "liball_available", productVariant, "product") 271 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor") 272 273 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext") 274 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product") 275 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor") 276 277 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system") 278 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product") 279 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm") 280 281 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product") 282 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor") 283 284 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product") 285 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm") 286} 287 288func checkWriteFileOutput(t *testing.T, ctx *android.TestContext, params android.TestingBuildParams, expected []string) { 289 t.Helper() 290 content := android.ContentFromFileRuleForTests(t, ctx, params) 291 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' }) 292 assertArrayString(t, actual, expected) 293} 294 295func TestDataLibs(t *testing.T) { 296 t.Parallel() 297 bp := ` 298 cc_test_library { 299 name: "test_lib", 300 srcs: ["test_lib.cpp"], 301 gtest: false, 302 } 303 304 cc_test { 305 name: "main_test", 306 data_libs: ["test_lib"], 307 gtest: false, 308 } 309 ` 310 311 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 312 313 ctx := testCcWithConfig(t, config) 314 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon") 315 testBinary := testingModule.Module().(*Module).linker.(*testBinary) 316 outputFiles := testingModule.OutputFiles(ctx, t, "") 317 if len(outputFiles) != 1 { 318 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles) 319 return 320 } 321 if len(testBinary.dataPaths()) != 1 { 322 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths()) 323 return 324 } 325 326 outputPath := outputFiles[0].String() 327 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String() 328 329 if !strings.HasSuffix(outputPath, "/main_test") { 330 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) 331 return 332 } 333 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") { 334 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath) 335 return 336 } 337} 338 339func TestDataLibsRelativeInstallPath(t *testing.T) { 340 t.Parallel() 341 bp := ` 342 cc_test_library { 343 name: "test_lib", 344 srcs: ["test_lib.cpp"], 345 relative_install_path: "foo/bar/baz", 346 gtest: false, 347 } 348 349 cc_binary { 350 name: "test_bin", 351 relative_install_path: "foo/bar/baz", 352 compile_multilib: "both", 353 } 354 355 cc_test { 356 name: "main_test", 357 data_libs: ["test_lib"], 358 data_bins: ["test_bin"], 359 gtest: false, 360 } 361 ` 362 363 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 364 365 ctx := testCcWithConfig(t, config) 366 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon") 367 module := testingModule.Module() 368 testBinary := module.(*Module).linker.(*testBinary) 369 outputFiles := testingModule.OutputFiles(ctx, t, "") 370 if len(outputFiles) != 1 { 371 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) 372 } 373 if len(testBinary.dataPaths()) != 2 { 374 t.Fatalf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths()) 375 } 376 377 outputPath := outputFiles[0].String() 378 379 if !strings.HasSuffix(outputPath, "/main_test") { 380 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) 381 } 382 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo 383 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") { 384 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+ 385 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0]) 386 } 387 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") { 388 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+ 389 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1]) 390 } 391} 392 393func TestTestBinaryTestSuites(t *testing.T) { 394 t.Parallel() 395 bp := ` 396 cc_test { 397 name: "main_test", 398 srcs: ["main_test.cpp"], 399 test_suites: [ 400 "suite_1", 401 "suite_2", 402 ], 403 gtest: false, 404 } 405 ` 406 407 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext 408 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module() 409 410 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo 411 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"] 412 if len(compatEntries) != 2 { 413 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries)) 414 } 415 if compatEntries[0] != "suite_1" { 416 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+ 417 " but was '%s'", compatEntries[0]) 418 } 419 if compatEntries[1] != "suite_2" { 420 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+ 421 " but was '%s'", compatEntries[1]) 422 } 423} 424 425func TestTestLibraryTestSuites(t *testing.T) { 426 t.Parallel() 427 bp := ` 428 cc_test_library { 429 name: "main_test_lib", 430 srcs: ["main_test_lib.cpp"], 431 test_suites: [ 432 "suite_1", 433 "suite_2", 434 ], 435 gtest: false, 436 } 437 ` 438 439 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext 440 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module() 441 442 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo 443 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"] 444 if len(compatEntries) != 2 { 445 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries)) 446 } 447 if compatEntries[0] != "suite_1" { 448 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+ 449 " but was '%s'", compatEntries[0]) 450 } 451 if compatEntries[1] != "suite_2" { 452 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+ 453 " but was '%s'", compatEntries[1]) 454 } 455} 456 457func TestDoubleLoadbleDep(t *testing.T) { 458 t.Parallel() 459 // okay to link : LLNDK -> double_loadable 460 testCc(t, ` 461 cc_library { 462 name: "libllndk", 463 shared_libs: ["libdoubleloadable"], 464 llndk: { 465 symbol_file: "libllndk.map.txt", 466 } 467 } 468 469 cc_library { 470 name: "libdoubleloadable", 471 vendor_available: true, 472 product_available: true, 473 double_loadable: true, 474 } 475 `) 476 // okay to link : double_loadable -> double_loadable 477 testCc(t, ` 478 cc_library { 479 name: "libdoubleloadable1", 480 shared_libs: ["libdoubleloadable2"], 481 vendor_available: true, 482 double_loadable: true, 483 } 484 485 cc_library { 486 name: "libdoubleloadable2", 487 vendor_available: true, 488 double_loadable: true, 489 } 490 `) 491 // okay to link : double_loadable -> double_loadable 492 testCc(t, ` 493 cc_library { 494 name: "libdoubleloadable", 495 vendor_available: true, 496 product_available: true, 497 double_loadable: true, 498 shared_libs: ["libnondoubleloadable"], 499 } 500 501 cc_library { 502 name: "libnondoubleloadable", 503 vendor_available: true, 504 product_available: true, 505 double_loadable: true, 506 } 507 `) 508 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable 509 testCc(t, ` 510 cc_library { 511 name: "libllndk", 512 shared_libs: ["libcoreonly"], 513 llndk: { 514 symbol_file: "libllndk.map.txt", 515 } 516 } 517 518 cc_library { 519 name: "libcoreonly", 520 shared_libs: ["libvendoravailable"], 521 } 522 523 // indirect dependency of LLNDK 524 cc_library { 525 name: "libvendoravailable", 526 vendor_available: true, 527 double_loadable: true, 528 } 529 `) 530} 531 532func TestDoubleLoadableDepError(t *testing.T) { 533 t.Parallel() 534 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable lib. 535 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` 536 cc_library { 537 name: "libllndk", 538 shared_libs: ["libnondoubleloadable"], 539 llndk: { 540 symbol_file: "libllndk.map.txt", 541 } 542 } 543 544 cc_library { 545 name: "libnondoubleloadable", 546 vendor_available: true, 547 product_available: true, 548 } 549 `) 550 551 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib. 552 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` 553 cc_library { 554 name: "libllndk", 555 no_libcrt: true, 556 shared_libs: ["libnondoubleloadable"], 557 llndk: { 558 symbol_file: "libllndk.map.txt", 559 } 560 } 561 562 cc_library { 563 name: "libnondoubleloadable", 564 vendor_available: true, 565 } 566 `) 567 568 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly. 569 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` 570 cc_library { 571 name: "libllndk", 572 shared_libs: ["libcoreonly"], 573 llndk: { 574 symbol_file: "libllndk.map.txt", 575 } 576 } 577 578 cc_library { 579 name: "libcoreonly", 580 shared_libs: ["libvendoravailable"], 581 } 582 583 // indirect dependency of LLNDK 584 cc_library { 585 name: "libvendoravailable", 586 vendor_available: true, 587 } 588 `) 589 590 // The error is not from 'client' but from 'libllndk' 591 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", ` 592 cc_library { 593 name: "client", 594 vendor_available: true, 595 double_loadable: true, 596 shared_libs: ["libllndk"], 597 } 598 cc_library { 599 name: "libllndk", 600 shared_libs: ["libnondoubleloadable"], 601 llndk: { 602 symbol_file: "libllndk.map.txt", 603 } 604 } 605 cc_library { 606 name: "libnondoubleloadable", 607 vendor_available: true, 608 } 609 `) 610} 611 612func TestMakeLinkType(t *testing.T) { 613 t.Parallel() 614 bp := ` 615 cc_library { 616 name: "libvendor", 617 vendor: true, 618 } 619 vndk_prebuilt_shared { 620 name: "prevndk", 621 version: "27", 622 target_arch: "arm", 623 binder32bit: true, 624 vendor_available: true, 625 product_available: true, 626 vndk: { 627 enabled: true, 628 }, 629 arch: { 630 arm: { 631 srcs: ["liba.so"], 632 }, 633 }, 634 } 635 cc_library { 636 name: "libllndk", 637 llndk: { 638 symbol_file: "libllndk.map.txt", 639 } 640 } 641 cc_library { 642 name: "libllndkprivate", 643 llndk: { 644 symbol_file: "libllndkprivate.map.txt", 645 private: true, 646 } 647 } 648 llndk_libraries_txt { 649 name: "llndk.libraries.txt", 650 } 651 ` 652 653 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 654 // native:vndk 655 ctx := testCcWithConfig(t, config) 656 657 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared" 658 659 tests := []struct { 660 variant string 661 name string 662 expected string 663 }{ 664 {vendorVariant, "libvendor", "native:vendor"}, 665 {vendorVariant, "libllndk", "native:vndk"}, 666 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vendor"}, 667 {coreVariant, "libllndk", "native:platform"}, 668 } 669 for _, test := range tests { 670 t.Run(test.name, func(t *testing.T) { 671 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module) 672 assertString(t, module.makeLinkType, test.expected) 673 }) 674 } 675} 676 677var staticLinkDepOrderTestCases = []struct { 678 // This is a string representation of a map[moduleName][]moduleDependency . 679 // It models the dependencies declared in an Android.bp file. 680 inStatic string 681 682 // This is a string representation of a map[moduleName][]moduleDependency . 683 // It models the dependencies declared in an Android.bp file. 684 inShared string 685 686 // allOrdered is a string representation of a map[moduleName][]moduleDependency . 687 // The keys of allOrdered specify which modules we would like to check. 688 // The values of allOrdered specify the expected result (of the transitive closure of all 689 // dependencies) for each module to test 690 allOrdered string 691 692 // outOrdered is a string representation of a map[moduleName][]moduleDependency . 693 // The keys of outOrdered specify which modules we would like to check. 694 // The values of outOrdered specify the expected result (of the ordered linker command line) 695 // for each module to test. 696 outOrdered string 697}{ 698 // Simple tests 699 { 700 inStatic: "", 701 outOrdered: "", 702 }, 703 { 704 inStatic: "a:", 705 outOrdered: "a:", 706 }, 707 { 708 inStatic: "a:b; b:", 709 outOrdered: "a:b; b:", 710 }, 711 // Tests of reordering 712 { 713 // diamond example 714 inStatic: "a:d,b,c; b:d; c:d; d:", 715 outOrdered: "a:b,c,d; b:d; c:d; d:", 716 }, 717 { 718 // somewhat real example 719 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b", 720 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b", 721 }, 722 { 723 // multiple reorderings 724 inStatic: "a:b,c,d,e; d:b; e:c", 725 outOrdered: "a:d,b,e,c; d:b; e:c", 726 }, 727 { 728 // should reorder without adding new transitive dependencies 729 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional", 730 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional", 731 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional", 732 }, 733 { 734 // multiple levels of dependencies 735 inStatic: "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d", 736 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d", 737 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d", 738 }, 739 // shared dependencies 740 { 741 // Note that this test doesn't recurse, to minimize the amount of logic it tests. 742 // So, we don't actually have to check that a shared dependency of c will change the order 743 // of a library that depends statically on b and on c. We only need to check that if c has 744 // a shared dependency on b, that that shows up in allOrdered. 745 inShared: "c:b", 746 allOrdered: "c:b", 747 outOrdered: "c:", 748 }, 749 { 750 // This test doesn't actually include any shared dependencies but it's a reminder of what 751 // the second phase of the above test would look like 752 inStatic: "a:b,c; c:b", 753 allOrdered: "a:c,b; c:b", 754 outOrdered: "a:c,b; c:b", 755 }, 756 // tiebreakers for when two modules specifying different orderings and there is no dependency 757 // to dictate an order 758 { 759 // if the tie is between two modules at the end of a's deps, then a's order wins 760 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d", 761 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d", 762 }, 763 { 764 // if the tie is between two modules at the start of a's deps, then c's order is used 765 inStatic: "a1:d,e,b1,c1; b1:d,e; c1:e,d; a2:d,e,b2,c2; b2:d,e; c2:d,e", 766 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e", 767 }, 768 // Tests involving duplicate dependencies 769 { 770 // simple duplicate 771 inStatic: "a:b,c,c,b", 772 outOrdered: "a:c,b", 773 }, 774 { 775 // duplicates with reordering 776 inStatic: "a:b,c,d,c; c:b", 777 outOrdered: "a:d,c,b", 778 }, 779 // Tests to confirm the nonexistence of infinite loops. 780 // These cases should never happen, so as long as the test terminates and the 781 // result is deterministic then that should be fine. 782 { 783 inStatic: "a:a", 784 outOrdered: "a:a", 785 }, 786 { 787 inStatic: "a:b; b:c; c:a", 788 allOrdered: "a:b,c; b:c,a; c:a,b", 789 outOrdered: "a:b; b:c; c:a", 790 }, 791 { 792 inStatic: "a:b,c; b:c,a; c:a,b", 793 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a", 794 outOrdered: "a:c,b; b:a,c; c:b,a", 795 }, 796} 797 798// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}]) 799func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) { 800 // convert from "a:b,c; d:e" to "a:b,c;d:e" 801 strippedText := strings.Replace(text, " ", "", -1) 802 if len(strippedText) < 1 { 803 return []android.Path{}, make(map[android.Path][]android.Path, 0) 804 } 805 allDeps = make(map[android.Path][]android.Path, 0) 806 807 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"] 808 moduleTexts := strings.Split(strippedText, ";") 809 810 outputForModuleName := func(moduleName string) android.Path { 811 return android.PathForTesting(moduleName) 812 } 813 814 for _, moduleText := range moduleTexts { 815 // convert from "a:b,c" to ["a", "b,c"] 816 components := strings.Split(moduleText, ":") 817 if len(components) != 2 { 818 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1)) 819 } 820 moduleName := components[0] 821 moduleOutput := outputForModuleName(moduleName) 822 modulesInOrder = append(modulesInOrder, moduleOutput) 823 824 depString := components[1] 825 // convert from "b,c" to ["b", "c"] 826 depNames := strings.Split(depString, ",") 827 if len(depString) < 1 { 828 depNames = []string{} 829 } 830 var deps []android.Path 831 for _, depName := range depNames { 832 deps = append(deps, outputForModuleName(depName)) 833 } 834 allDeps[moduleOutput] = deps 835 } 836 return modulesInOrder, allDeps 837} 838 839func TestStaticLibDepReordering(t *testing.T) { 840 t.Parallel() 841 ctx := testCc(t, ` 842 cc_library { 843 name: "a", 844 static_libs: ["b", "c", "d"], 845 stl: "none", 846 } 847 cc_library { 848 name: "b", 849 stl: "none", 850 } 851 cc_library { 852 name: "c", 853 static_libs: ["b"], 854 stl: "none", 855 } 856 cc_library { 857 name: "d", 858 stl: "none", 859 } 860 861 `) 862 863 variant := "android_arm64_armv8-a_static" 864 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) 865 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider) 866 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop() 867 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"}) 868 869 if !reflect.DeepEqual(actual, expected) { 870 t.Errorf("staticDeps orderings were not propagated correctly"+ 871 "\nactual: %v"+ 872 "\nexpected: %v", 873 actual, 874 expected, 875 ) 876 } 877} 878 879func TestStaticLibDepReorderingWithShared(t *testing.T) { 880 t.Parallel() 881 ctx := testCc(t, ` 882 cc_library { 883 name: "a", 884 static_libs: ["b", "c"], 885 stl: "none", 886 } 887 cc_library { 888 name: "b", 889 stl: "none", 890 } 891 cc_library { 892 name: "c", 893 shared_libs: ["b"], 894 stl: "none", 895 } 896 897 `) 898 899 variant := "android_arm64_armv8-a_static" 900 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) 901 staticLibInfo, _ := android.OtherModuleProvider(ctx, moduleA, StaticLibraryInfoProvider) 902 actual := android.Paths(staticLibInfo.TransitiveStaticLibrariesForOrdering.ToList()).RelativeToTop() 903 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"}) 904 905 if !reflect.DeepEqual(actual, expected) { 906 t.Errorf("staticDeps orderings did not account for shared libs"+ 907 "\nactual: %v"+ 908 "\nexpected: %v", 909 actual, 910 expected, 911 ) 912 } 913} 914 915func checkEquals(t *testing.T, message string, expected, actual interface{}) { 916 t.Helper() 917 if !reflect.DeepEqual(actual, expected) { 918 t.Errorf(message+ 919 "\nactual: %v"+ 920 "\nexpected: %v", 921 actual, 922 expected, 923 ) 924 } 925} 926 927func TestLlndkLibrary(t *testing.T) { 928 t.Parallel() 929 result := prepareForCcTest.RunTestWithBp(t, ` 930 cc_library { 931 name: "libllndk", 932 stubs: { versions: ["1", "2"] }, 933 llndk: { 934 symbol_file: "libllndk.map.txt", 935 }, 936 export_include_dirs: ["include"], 937 } 938 939 cc_prebuilt_library_shared { 940 name: "libllndkprebuilt", 941 stubs: { versions: ["1", "2"] , symbol_file: "libllndkprebuilt.map.txt" }, 942 llndk: { 943 symbol_file: "libllndkprebuilt.map.txt", 944 }, 945 } 946 947 cc_library { 948 name: "libllndk_with_external_headers", 949 stubs: { versions: ["1", "2"] }, 950 llndk: { 951 symbol_file: "libllndk.map.txt", 952 export_llndk_headers: ["libexternal_llndk_headers"], 953 }, 954 header_libs: ["libexternal_headers"], 955 export_header_lib_headers: ["libexternal_headers"], 956 } 957 cc_library_headers { 958 name: "libexternal_headers", 959 export_include_dirs: ["include"], 960 vendor_available: true, 961 product_available: true, 962 } 963 cc_library_headers { 964 name: "libexternal_llndk_headers", 965 export_include_dirs: ["include_llndk"], 966 export_system_include_dirs: ["include_system_llndk"], 967 llndk: { 968 symbol_file: "libllndk.map.txt", 969 }, 970 vendor_available: true, 971 } 972 973 cc_library { 974 name: "libllndk_with_override_headers", 975 stubs: { versions: ["1", "2"] }, 976 llndk: { 977 symbol_file: "libllndk.map.txt", 978 override_export_include_dirs: ["include_llndk"], 979 }, 980 export_include_dirs: ["include"], 981 } 982 983 cc_library { 984 name: "libllndk_with_system_headers", 985 llndk: { 986 symbol_file: "libllndk.map.txt", 987 export_llndk_headers: ["libexternal_llndk_headers"], 988 export_headers_as_system: true, 989 }, 990 export_include_dirs: ["include"], 991 export_system_include_dirs: ["include_system"], 992 } 993 `) 994 actual := result.ModuleVariantsForTests("libllndk") 995 for i := 0; i < len(actual); i++ { 996 if !strings.HasPrefix(actual[i], "android_vendor_") { 997 actual = append(actual[:i], actual[i+1:]...) 998 i-- 999 } 1000 } 1001 expected := []string{ 1002 "android_vendor_arm64_armv8-a_shared", 1003 "android_vendor_arm_armv7-a-neon_shared", 1004 } 1005 android.AssertArrayString(t, "variants for llndk stubs", expected, actual) 1006 1007 params := result.ModuleForTests("libllndk", "android_vendor_arm_armv7-a-neon_shared").Description("generate stub") 1008 android.AssertSame(t, "use Vendor API level for default stubs", "35", params.Args["apiLevel"]) 1009 1010 checkExportedIncludeDirs := func(module, variant string, expectedSystemDirs []string, expectedDirs ...string) { 1011 t.Helper() 1012 m := result.ModuleForTests(module, variant).Module() 1013 f, _ := android.OtherModuleProvider(result, m, FlagExporterInfoProvider) 1014 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]", 1015 expectedDirs, f.IncludeDirs) 1016 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]", 1017 expectedSystemDirs, f.SystemIncludeDirs) 1018 } 1019 1020 checkExportedIncludeDirs("libllndk", coreVariant, nil, "include") 1021 checkExportedIncludeDirs("libllndk", vendorVariant, nil, "include") 1022 checkExportedIncludeDirs("libllndk_with_external_headers", coreVariant, nil, "include") 1023 checkExportedIncludeDirs("libllndk_with_external_headers", vendorVariant, 1024 []string{"include_system_llndk"}, "include_llndk") 1025 checkExportedIncludeDirs("libllndk_with_override_headers", coreVariant, nil, "include") 1026 checkExportedIncludeDirs("libllndk_with_override_headers", vendorVariant, nil, "include_llndk") 1027 checkExportedIncludeDirs("libllndk_with_system_headers", coreVariant, []string{"include_system"}, "include") 1028 checkExportedIncludeDirs("libllndk_with_system_headers", vendorVariant, 1029 []string{"include_system", "include", "include_system_llndk"}, "include_llndk") 1030 1031 checkAbiLinkerIncludeDirs := func(module string) { 1032 t.Helper() 1033 coreModule := result.ModuleForTests(module, coreVariant) 1034 abiCheckFlags := "" 1035 for _, output := range coreModule.AllOutputs() { 1036 if strings.HasSuffix(output, ".so.llndk.lsdump") { 1037 abiCheckFlags = coreModule.Output(output).Args["exportedHeaderFlags"] 1038 } 1039 } 1040 vendorModule := result.ModuleForTests(module, vendorVariant).Module() 1041 vendorInfo, _ := android.OtherModuleProvider(result, vendorModule, FlagExporterInfoProvider) 1042 vendorDirs := android.Concat(vendorInfo.IncludeDirs, vendorInfo.SystemIncludeDirs) 1043 android.AssertStringEquals(t, module+" has different exported include dirs for vendor variant and ABI check", 1044 android.JoinPathsWithPrefix(vendorDirs, "-I"), abiCheckFlags) 1045 } 1046 checkAbiLinkerIncludeDirs("libllndk") 1047 checkAbiLinkerIncludeDirs("libllndk_with_override_headers") 1048 checkAbiLinkerIncludeDirs("libllndk_with_external_headers") 1049 checkAbiLinkerIncludeDirs("libllndk_with_system_headers") 1050} 1051 1052func TestLlndkHeaders(t *testing.T) { 1053 t.Parallel() 1054 ctx := testCc(t, ` 1055 cc_library_headers { 1056 name: "libllndk_headers", 1057 export_include_dirs: ["my_include"], 1058 llndk: { 1059 llndk_headers: true, 1060 }, 1061 } 1062 cc_library { 1063 name: "libllndk", 1064 llndk: { 1065 symbol_file: "libllndk.map.txt", 1066 export_llndk_headers: ["libllndk_headers"], 1067 } 1068 } 1069 1070 cc_library { 1071 name: "libvendor", 1072 shared_libs: ["libllndk"], 1073 vendor: true, 1074 srcs: ["foo.c"], 1075 no_libcrt: true, 1076 nocrt: true, 1077 } 1078 `) 1079 1080 // _static variant is used since _shared reuses *.o from the static variant 1081 cc := ctx.ModuleForTests("libvendor", "android_vendor_arm_armv7-a-neon_static").Rule("cc") 1082 cflags := cc.Args["cFlags"] 1083 if !strings.Contains(cflags, "-Imy_include") { 1084 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags) 1085 } 1086} 1087 1088func checkRuntimeLibs(t *testing.T, expected []string, module *Module) { 1089 actual := module.Properties.AndroidMkRuntimeLibs 1090 if !reflect.DeepEqual(actual, expected) { 1091 t.Errorf("incorrect runtime_libs for shared libs"+ 1092 "\nactual: %v"+ 1093 "\nexpected: %v", 1094 actual, 1095 expected, 1096 ) 1097 } 1098} 1099 1100const runtimeLibAndroidBp = ` 1101 cc_library { 1102 name: "liball_available", 1103 vendor_available: true, 1104 product_available: true, 1105 no_libcrt : true, 1106 nocrt : true, 1107 system_shared_libs : [], 1108 } 1109 cc_library { 1110 name: "libvendor_available1", 1111 vendor_available: true, 1112 runtime_libs: ["liball_available"], 1113 no_libcrt : true, 1114 nocrt : true, 1115 system_shared_libs : [], 1116 } 1117 cc_library { 1118 name: "libvendor_available2", 1119 vendor_available: true, 1120 runtime_libs: ["liball_available"], 1121 target: { 1122 vendor: { 1123 exclude_runtime_libs: ["liball_available"], 1124 } 1125 }, 1126 no_libcrt : true, 1127 nocrt : true, 1128 system_shared_libs : [], 1129 } 1130 cc_library { 1131 name: "libproduct_vendor", 1132 product_specific: true, 1133 vendor_available: true, 1134 no_libcrt : true, 1135 nocrt : true, 1136 system_shared_libs : [], 1137 } 1138 cc_library { 1139 name: "libcore", 1140 runtime_libs: ["liball_available"], 1141 no_libcrt : true, 1142 nocrt : true, 1143 system_shared_libs : [], 1144 } 1145 cc_library { 1146 name: "libvendor1", 1147 vendor: true, 1148 no_libcrt : true, 1149 nocrt : true, 1150 system_shared_libs : [], 1151 } 1152 cc_library { 1153 name: "libvendor2", 1154 vendor: true, 1155 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"], 1156 no_libcrt : true, 1157 nocrt : true, 1158 system_shared_libs : [], 1159 } 1160 cc_library { 1161 name: "libproduct_available1", 1162 product_available: true, 1163 runtime_libs: ["liball_available"], 1164 no_libcrt : true, 1165 nocrt : true, 1166 system_shared_libs : [], 1167 } 1168 cc_library { 1169 name: "libproduct1", 1170 product_specific: true, 1171 no_libcrt : true, 1172 nocrt : true, 1173 system_shared_libs : [], 1174 } 1175 cc_library { 1176 name: "libproduct2", 1177 product_specific: true, 1178 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"], 1179 no_libcrt : true, 1180 nocrt : true, 1181 system_shared_libs : [], 1182 } 1183` 1184 1185func TestRuntimeLibs(t *testing.T) { 1186 t.Parallel() 1187 ctx := testCc(t, runtimeLibAndroidBp) 1188 1189 // runtime_libs for core variants use the module names without suffixes. 1190 variant := "android_arm64_armv8-a_shared" 1191 1192 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module) 1193 checkRuntimeLibs(t, []string{"liball_available"}, module) 1194 1195 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module) 1196 checkRuntimeLibs(t, []string{"liball_available"}, module) 1197 1198 module = ctx.ModuleForTests("libcore", variant).Module().(*Module) 1199 checkRuntimeLibs(t, []string{"liball_available"}, module) 1200 1201 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core 1202 // and vendor variants. 1203 variant = "android_vendor_arm64_armv8-a_shared" 1204 1205 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module) 1206 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module) 1207 1208 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module) 1209 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module) 1210 1211 // runtime_libs for product variants have '.product' suffixes if the modules have both core 1212 // and product variants. 1213 variant = "android_product_arm64_armv8-a_shared" 1214 1215 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module) 1216 checkRuntimeLibs(t, []string{"liball_available.product"}, module) 1217 1218 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module) 1219 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module) 1220} 1221 1222func TestExcludeRuntimeLibs(t *testing.T) { 1223 t.Parallel() 1224 ctx := testCc(t, runtimeLibAndroidBp) 1225 1226 variant := "android_arm64_armv8-a_shared" 1227 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module) 1228 checkRuntimeLibs(t, []string{"liball_available"}, module) 1229 1230 variant = "android_vendor_arm64_armv8-a_shared" 1231 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module) 1232 checkRuntimeLibs(t, nil, module) 1233} 1234 1235func checkStaticLibs(t *testing.T, expected []string, module *Module) { 1236 t.Helper() 1237 actual := module.Properties.AndroidMkStaticLibs 1238 if !reflect.DeepEqual(actual, expected) { 1239 t.Errorf("incorrect static_libs"+ 1240 "\nactual: %v"+ 1241 "\nexpected: %v", 1242 actual, 1243 expected, 1244 ) 1245 } 1246} 1247 1248const staticLibAndroidBp = ` 1249 cc_library { 1250 name: "lib1", 1251 } 1252 cc_library { 1253 name: "lib2", 1254 static_libs: ["lib1"], 1255 } 1256` 1257 1258func TestStaticLibDepExport(t *testing.T) { 1259 t.Parallel() 1260 ctx := testCc(t, staticLibAndroidBp) 1261 1262 // Check the shared version of lib2. 1263 variant := "android_arm64_armv8-a_shared" 1264 module := ctx.ModuleForTests("lib2", variant).Module().(*Module) 1265 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module) 1266 1267 // Check the static version of lib2. 1268 variant = "android_arm64_armv8-a_static" 1269 module = ctx.ModuleForTests("lib2", variant).Module().(*Module) 1270 // libc++_static is linked additionally. 1271 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module) 1272} 1273 1274var compilerFlagsTestCases = []struct { 1275 in string 1276 out bool 1277}{ 1278 { 1279 in: "a", 1280 out: false, 1281 }, 1282 { 1283 in: "-a", 1284 out: true, 1285 }, 1286 { 1287 in: "-Ipath/to/something", 1288 out: false, 1289 }, 1290 { 1291 in: "-isystempath/to/something", 1292 out: false, 1293 }, 1294 { 1295 in: "--coverage", 1296 out: false, 1297 }, 1298 { 1299 in: "-include a/b", 1300 out: true, 1301 }, 1302 { 1303 in: "-include a/b c/d", 1304 out: false, 1305 }, 1306 { 1307 in: "-DMACRO", 1308 out: true, 1309 }, 1310 { 1311 in: "-DMAC RO", 1312 out: false, 1313 }, 1314 { 1315 in: "-a -b", 1316 out: false, 1317 }, 1318 { 1319 in: "-DMACRO=definition", 1320 out: true, 1321 }, 1322 { 1323 in: "-DMACRO=defi nition", 1324 out: true, // TODO(jiyong): this should be false 1325 }, 1326 { 1327 in: "-DMACRO(x)=x + 1", 1328 out: true, 1329 }, 1330 { 1331 in: "-DMACRO=\"defi nition\"", 1332 out: true, 1333 }, 1334} 1335 1336type mockContext struct { 1337 BaseModuleContext 1338 result bool 1339} 1340 1341func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 1342 // CheckBadCompilerFlags calls this function when the flag should be rejected 1343 ctx.result = false 1344} 1345 1346func TestCompilerFlags(t *testing.T) { 1347 t.Parallel() 1348 for _, testCase := range compilerFlagsTestCases { 1349 ctx := &mockContext{result: true} 1350 CheckBadCompilerFlags(ctx, "", []string{testCase.in}) 1351 if ctx.result != testCase.out { 1352 t.Errorf("incorrect output:") 1353 t.Errorf(" input: %#v", testCase.in) 1354 t.Errorf(" expected: %#v", testCase.out) 1355 t.Errorf(" got: %#v", ctx.result) 1356 } 1357 } 1358} 1359 1360func TestRecovery(t *testing.T) { 1361 t.Parallel() 1362 ctx := testCc(t, ` 1363 cc_library_shared { 1364 name: "librecovery", 1365 recovery: true, 1366 } 1367 cc_library_shared { 1368 name: "librecovery32", 1369 recovery: true, 1370 compile_multilib:"32", 1371 } 1372 cc_library_shared { 1373 name: "libHalInRecovery", 1374 recovery_available: true, 1375 vendor: true, 1376 } 1377 `) 1378 1379 variants := ctx.ModuleVariantsForTests("librecovery") 1380 const arm64 = "android_recovery_arm64_armv8-a_shared" 1381 if len(variants) != 1 || !android.InList(arm64, variants) { 1382 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants) 1383 } 1384 1385 variants = ctx.ModuleVariantsForTests("librecovery32") 1386 if android.InList(arm64, variants) { 1387 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64) 1388 } 1389 1390 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module) 1391 if !recoveryModule.Platform() { 1392 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product") 1393 } 1394} 1395 1396func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) { 1397 t.Parallel() 1398 bp := ` 1399 cc_prebuilt_test_library_shared { 1400 name: "test_lib", 1401 relative_install_path: "foo/bar/baz", 1402 srcs: ["srcpath/dontusethispath/baz.so"], 1403 } 1404 1405 cc_test { 1406 name: "main_test", 1407 data_libs: ["test_lib"], 1408 gtest: false, 1409 } 1410 ` 1411 1412 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 1413 1414 ctx := testCcWithConfig(t, config) 1415 testingModule := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon") 1416 module := testingModule.Module() 1417 testBinary := module.(*Module).linker.(*testBinary) 1418 outputFiles := testingModule.OutputFiles(ctx, t, "") 1419 if len(outputFiles) != 1 { 1420 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles) 1421 } 1422 if len(testBinary.dataPaths()) != 1 { 1423 t.Errorf("expected exactly one test data file. test data files: [%v]", testBinary.dataPaths()) 1424 } 1425 1426 outputPath := outputFiles[0].String() 1427 1428 if !strings.HasSuffix(outputPath, "/main_test") { 1429 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) 1430 } 1431 entries := android.AndroidMkInfoForTest(t, ctx, module).PrimaryInfo 1432 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") { 1433 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+ 1434 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0]) 1435 } 1436} 1437 1438func TestVersionedStubs(t *testing.T) { 1439 t.Parallel() 1440 ctx := testCc(t, ` 1441 cc_library_shared { 1442 name: "libFoo", 1443 srcs: ["foo.c"], 1444 stubs: { 1445 symbol_file: "foo.map.txt", 1446 versions: ["1", "2", "3"], 1447 }, 1448 } 1449 1450 cc_library_shared { 1451 name: "libBar", 1452 srcs: ["bar.c"], 1453 shared_libs: ["libFoo#1"], 1454 }`) 1455 1456 variants := ctx.ModuleVariantsForTests("libFoo") 1457 expectedVariants := []string{ 1458 "android_arm64_armv8-a_shared", 1459 "android_arm64_armv8-a_shared_1", 1460 "android_arm64_armv8-a_shared_2", 1461 "android_arm64_armv8-a_shared_3", 1462 "android_arm64_armv8-a_shared_current", 1463 "android_arm_armv7-a-neon_shared", 1464 "android_arm_armv7-a-neon_shared_1", 1465 "android_arm_armv7-a-neon_shared_2", 1466 "android_arm_armv7-a-neon_shared_3", 1467 "android_arm_armv7-a-neon_shared_current", 1468 } 1469 variantsMismatch := false 1470 if len(variants) != len(expectedVariants) { 1471 variantsMismatch = true 1472 } else { 1473 for _, v := range expectedVariants { 1474 if !inList(v, variants) { 1475 variantsMismatch = false 1476 } 1477 } 1478 } 1479 if variantsMismatch { 1480 t.Errorf("variants of libFoo expected:\n") 1481 for _, v := range expectedVariants { 1482 t.Errorf("%q\n", v) 1483 } 1484 t.Errorf(", but got:\n") 1485 for _, v := range variants { 1486 t.Errorf("%q\n", v) 1487 } 1488 } 1489 1490 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld") 1491 libFlags := libBarLinkRule.Args["libFlags"] 1492 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so" 1493 if !strings.Contains(libFlags, libFoo1StubPath) { 1494 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags) 1495 } 1496 1497 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc") 1498 cFlags := libBarCompileRule.Args["cFlags"] 1499 libFoo1VersioningMacro := "-D__LIBFOO_API__=1" 1500 if !strings.Contains(cFlags, libFoo1VersioningMacro) { 1501 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags) 1502 } 1503} 1504 1505func TestVersioningMacro(t *testing.T) { 1506 t.Parallel() 1507 for _, tc := range []struct{ moduleName, expected string }{ 1508 {"libc", "__LIBC_API__"}, 1509 {"libfoo", "__LIBFOO_API__"}, 1510 {"libfoo@1", "__LIBFOO_1_API__"}, 1511 {"libfoo-v1", "__LIBFOO_V1_API__"}, 1512 {"libfoo.v1", "__LIBFOO_V1_API__"}, 1513 } { 1514 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName)) 1515 } 1516} 1517 1518func pathsToBase(paths android.Paths) []string { 1519 var ret []string 1520 for _, p := range paths { 1521 ret = append(ret, p.Base()) 1522 } 1523 return ret 1524} 1525 1526func TestStaticLibArchiveArgs(t *testing.T) { 1527 t.Parallel() 1528 ctx := testCc(t, ` 1529 cc_library_static { 1530 name: "foo", 1531 srcs: ["foo.c"], 1532 } 1533 1534 cc_library_static { 1535 name: "bar", 1536 srcs: ["bar.c"], 1537 } 1538 1539 cc_library_shared { 1540 name: "qux", 1541 srcs: ["qux.c"], 1542 } 1543 1544 cc_library_static { 1545 name: "baz", 1546 srcs: ["baz.c"], 1547 static_libs: ["foo"], 1548 shared_libs: ["qux"], 1549 whole_static_libs: ["bar"], 1550 }`) 1551 1552 variant := "android_arm64_armv8-a_static" 1553 arRule := ctx.ModuleForTests("baz", variant).Rule("ar") 1554 1555 // For static libraries, the object files of a whole static dep are included in the archive 1556 // directly 1557 if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) { 1558 t.Errorf("Expected input objects %q, got %q", w, g) 1559 } 1560 1561 // non whole static dependencies are not linked into the archive 1562 if len(arRule.Implicits) > 0 { 1563 t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits) 1564 } 1565} 1566 1567func TestSharedLibLinkingArgs(t *testing.T) { 1568 t.Parallel() 1569 ctx := testCc(t, ` 1570 cc_library_static { 1571 name: "foo", 1572 srcs: ["foo.c"], 1573 } 1574 1575 cc_library_static { 1576 name: "bar", 1577 srcs: ["bar.c"], 1578 } 1579 1580 cc_library_shared { 1581 name: "qux", 1582 srcs: ["qux.c"], 1583 } 1584 1585 cc_library_shared { 1586 name: "baz", 1587 srcs: ["baz.c"], 1588 static_libs: ["foo"], 1589 shared_libs: ["qux"], 1590 whole_static_libs: ["bar"], 1591 }`) 1592 1593 variant := "android_arm64_armv8-a_shared" 1594 linkRule := ctx.ModuleForTests("baz", variant).Rule("ld") 1595 libFlags := linkRule.Args["libFlags"] 1596 // When dynamically linking, we expect static dependencies to be found on the command line 1597 if expected := "foo.a"; !strings.Contains(libFlags, expected) { 1598 t.Errorf("Static lib %q was not found in %q", expected, libFlags) 1599 } 1600 // When dynamically linking, we expect whole static dependencies to be found on the command line 1601 if expected := "bar.a"; !strings.Contains(libFlags, expected) { 1602 t.Errorf("Static lib %q was not found in %q", expected, libFlags) 1603 } 1604 1605 // When dynamically linking, we expect shared dependencies to be found on the command line 1606 if expected := "qux.so"; !strings.Contains(libFlags, expected) { 1607 t.Errorf("Shared lib %q was not found in %q", expected, libFlags) 1608 } 1609 1610 // We should only have the objects from the shared library srcs, not the whole static dependencies 1611 if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) { 1612 t.Errorf("Expected input objects %q, got %q", w, g) 1613 } 1614} 1615 1616func TestStaticExecutable(t *testing.T) { 1617 t.Parallel() 1618 ctx := testCc(t, ` 1619 cc_binary { 1620 name: "static_test", 1621 srcs: ["foo.c", "baz.o"], 1622 static_executable: true, 1623 }`) 1624 1625 variant := "android_arm64_armv8-a" 1626 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld") 1627 libFlags := binModuleRule.Args["libFlags"] 1628 systemStaticLibs := []string{"libc.a", "libm.a"} 1629 for _, lib := range systemStaticLibs { 1630 if !strings.Contains(libFlags, lib) { 1631 t.Errorf("Static lib %q was not found in %q", lib, libFlags) 1632 } 1633 } 1634 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"} 1635 for _, lib := range systemSharedLibs { 1636 if strings.Contains(libFlags, lib) { 1637 t.Errorf("Shared lib %q was found in %q", lib, libFlags) 1638 } 1639 } 1640} 1641 1642func TestStaticDepsOrderWithStubs(t *testing.T) { 1643 t.Parallel() 1644 ctx := testCc(t, ` 1645 cc_binary { 1646 name: "mybin", 1647 srcs: ["foo.c"], 1648 static_libs: ["libfooC", "libfooB"], 1649 static_executable: true, 1650 stl: "none", 1651 } 1652 1653 cc_library { 1654 name: "libfooB", 1655 srcs: ["foo.c"], 1656 shared_libs: ["libfooC"], 1657 stl: "none", 1658 } 1659 1660 cc_library { 1661 name: "libfooC", 1662 srcs: ["foo.c"], 1663 stl: "none", 1664 stubs: { 1665 versions: ["1"], 1666 }, 1667 }`) 1668 1669 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld") 1670 actual := mybin.Implicits[:2] 1671 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"}) 1672 1673 if !reflect.DeepEqual(actual, expected) { 1674 t.Errorf("staticDeps orderings were not propagated correctly"+ 1675 "\nactual: %v"+ 1676 "\nexpected: %v", 1677 actual, 1678 expected, 1679 ) 1680 } 1681} 1682 1683func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) { 1684 t.Parallel() 1685 testCcError(t, `module "libA" .* depends on disabled module "libB"`, ` 1686 cc_library { 1687 name: "libA", 1688 srcs: ["foo.c"], 1689 shared_libs: ["libB"], 1690 stl: "none", 1691 } 1692 1693 cc_library { 1694 name: "libB", 1695 srcs: ["foo.c"], 1696 enabled: false, 1697 stl: "none", 1698 } 1699 `) 1700} 1701 1702func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) { 1703 bp := ` 1704 cc_fuzz { 1705 name: "test_afl_fuzz_target", 1706 srcs: ["foo.c"], 1707 host_supported: true, 1708 static_libs: [ 1709 "afl_fuzz_static_lib", 1710 ], 1711 shared_libs: [ 1712 "afl_fuzz_shared_lib", 1713 ], 1714 fuzzing_frameworks: { 1715 afl: true, 1716 libfuzzer: false, 1717 }, 1718 } 1719 cc_library { 1720 name: "afl_fuzz_static_lib", 1721 host_supported: true, 1722 srcs: ["static_file.c"], 1723 } 1724 cc_library { 1725 name: "libfuzzer_only_static_lib", 1726 host_supported: true, 1727 srcs: ["static_file.c"], 1728 } 1729 cc_library { 1730 name: "afl_fuzz_shared_lib", 1731 host_supported: true, 1732 srcs: ["shared_file.c"], 1733 static_libs: [ 1734 "second_static_lib", 1735 ], 1736 } 1737 cc_library_headers { 1738 name: "libafl_headers", 1739 vendor_available: true, 1740 host_supported: true, 1741 export_include_dirs: [ 1742 "include", 1743 "instrumentation", 1744 ], 1745 } 1746 cc_object { 1747 name: "afl-compiler-rt", 1748 vendor_available: true, 1749 host_supported: true, 1750 cflags: [ 1751 "-fPIC", 1752 ], 1753 srcs: [ 1754 "instrumentation/afl-compiler-rt.o.c", 1755 ], 1756 } 1757 cc_library { 1758 name: "second_static_lib", 1759 host_supported: true, 1760 srcs: ["second_file.c"], 1761 } 1762 cc_object { 1763 name: "aflpp_driver", 1764 host_supported: true, 1765 srcs: [ 1766 "aflpp_driver.c", 1767 ], 1768 }` 1769 1770 testEnv := map[string]string{ 1771 "FUZZ_FRAMEWORK": "AFL", 1772 } 1773 1774 ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp) 1775 1776 checkPcGuardFlag := func( 1777 modName string, variantName string, shouldHave bool) { 1778 cc := ctx.ModuleForTests(modName, variantName).Rule("cc") 1779 1780 cFlags, ok := cc.Args["cFlags"] 1781 if !ok { 1782 t.Errorf("Could not find cFlags for module %s and variant %s", 1783 modName, variantName) 1784 } 1785 1786 if strings.Contains( 1787 cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave { 1788 t.Errorf("Flag was found: %t. Expected to find flag: %t. "+ 1789 "Test failed for module %s and variant %s", 1790 !shouldHave, shouldHave, modName, variantName) 1791 } 1792 } 1793 1794 moduleName := "test_afl_fuzz_target" 1795 checkPcGuardFlag(moduleName, variant+"_fuzzer", true) 1796 1797 moduleName = "afl_fuzz_static_lib" 1798 checkPcGuardFlag(moduleName, variant+"_static", false) 1799 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true) 1800 1801 moduleName = "second_static_lib" 1802 checkPcGuardFlag(moduleName, variant+"_static", false) 1803 checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true) 1804 1805 ctx.ModuleForTests("afl_fuzz_shared_lib", 1806 "android_arm64_armv8-a_shared").Rule("cc") 1807 ctx.ModuleForTests("afl_fuzz_shared_lib", 1808 "android_arm64_armv8-a_shared_fuzzer").Rule("cc") 1809} 1810 1811func TestAFLFuzzTargetForDevice(t *testing.T) { 1812 t.Parallel() 1813 VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a") 1814} 1815 1816func TestAFLFuzzTargetForLinuxHost(t *testing.T) { 1817 t.Parallel() 1818 if runtime.GOOS != "linux" { 1819 t.Skip("requires linux") 1820 } 1821 1822 VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64") 1823} 1824 1825// Simple smoke test for the cc_fuzz target that ensures the rule compiles 1826// correctly. 1827func TestFuzzTarget(t *testing.T) { 1828 t.Parallel() 1829 ctx := testCc(t, ` 1830 cc_fuzz { 1831 name: "fuzz_smoke_test", 1832 srcs: ["foo.c"], 1833 }`) 1834 1835 variant := "android_arm64_armv8-a_fuzzer" 1836 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc") 1837} 1838 1839func assertString(t *testing.T, got, expected string) { 1840 t.Helper() 1841 if got != expected { 1842 t.Errorf("expected %q got %q", expected, got) 1843 } 1844} 1845 1846func assertArrayString(t *testing.T, got, expected []string) { 1847 t.Helper() 1848 if len(got) != len(expected) { 1849 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got) 1850 return 1851 } 1852 for i := range got { 1853 if got[i] != expected[i] { 1854 t.Errorf("expected %d-th %q (%q) got %q (%q)", 1855 i, expected[i], expected, got[i], got) 1856 return 1857 } 1858 } 1859} 1860 1861func assertMapKeys(t *testing.T, m map[string]string, expected []string) { 1862 t.Helper() 1863 assertArrayString(t, android.SortedKeys(m), expected) 1864} 1865 1866func TestDefaults(t *testing.T) { 1867 t.Parallel() 1868 ctx := testCc(t, ` 1869 cc_defaults { 1870 name: "defaults", 1871 srcs: ["foo.c"], 1872 static: { 1873 srcs: ["bar.c"], 1874 }, 1875 shared: { 1876 srcs: ["baz.c"], 1877 }, 1878 } 1879 1880 cc_library_static { 1881 name: "libstatic", 1882 defaults: ["defaults"], 1883 } 1884 1885 cc_library_shared { 1886 name: "libshared", 1887 defaults: ["defaults"], 1888 } 1889 1890 cc_library { 1891 name: "libboth", 1892 defaults: ["defaults"], 1893 } 1894 1895 cc_binary { 1896 name: "binary", 1897 defaults: ["defaults"], 1898 }`) 1899 1900 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld") 1901 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) { 1902 t.Errorf("libshared ld rule wanted %q, got %q", w, g) 1903 } 1904 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld") 1905 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) { 1906 t.Errorf("libboth ld rule wanted %q, got %q", w, g) 1907 } 1908 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld") 1909 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) { 1910 t.Errorf("binary ld rule wanted %q, got %q", w, g) 1911 } 1912 1913 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar") 1914 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) { 1915 t.Errorf("libstatic ar rule wanted %q, got %q", w, g) 1916 } 1917 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar") 1918 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) { 1919 t.Errorf("libboth ar rule wanted %q, got %q", w, g) 1920 } 1921} 1922 1923func TestProductVariableDefaults(t *testing.T) { 1924 t.Parallel() 1925 bp := ` 1926 cc_defaults { 1927 name: "libfoo_defaults", 1928 srcs: ["foo.c"], 1929 cppflags: ["-DFOO"], 1930 product_variables: { 1931 debuggable: { 1932 cppflags: ["-DBAR"], 1933 }, 1934 }, 1935 } 1936 1937 cc_library { 1938 name: "libfoo", 1939 defaults: ["libfoo_defaults"], 1940 } 1941 ` 1942 1943 result := android.GroupFixturePreparers( 1944 prepareForCcTest, 1945 android.PrepareForTestWithVariables, 1946 1947 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 1948 variables.Debuggable = BoolPtr(true) 1949 }), 1950 ).RunTestWithBp(t, bp) 1951 1952 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module) 1953 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR") 1954} 1955 1956func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) { 1957 t.Parallel() 1958 bp := ` 1959 cc_library_static { 1960 name: "libfoo", 1961 srcs: ["foo.c"], 1962 whole_static_libs: ["libbar"], 1963 } 1964 1965 cc_library_static { 1966 name: "libbar", 1967 whole_static_libs: ["libmissing"], 1968 } 1969 ` 1970 1971 result := android.GroupFixturePreparers( 1972 prepareForCcTest, 1973 android.PrepareForTestWithAllowMissingDependencies, 1974 ).RunTestWithBp(t, bp) 1975 1976 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a") 1977 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule) 1978 1979 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing") 1980 1981 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a") 1982 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String()) 1983} 1984 1985func TestInstallSharedLibs(t *testing.T) { 1986 t.Parallel() 1987 bp := ` 1988 cc_binary { 1989 name: "bin", 1990 host_supported: true, 1991 shared_libs: ["libshared"], 1992 runtime_libs: ["libruntime"], 1993 srcs: [":gen"], 1994 } 1995 1996 cc_library_shared { 1997 name: "libshared", 1998 host_supported: true, 1999 shared_libs: ["libtransitive"], 2000 } 2001 2002 cc_library_shared { 2003 name: "libtransitive", 2004 host_supported: true, 2005 } 2006 2007 cc_library_shared { 2008 name: "libruntime", 2009 host_supported: true, 2010 } 2011 2012 cc_binary_host { 2013 name: "tool", 2014 srcs: ["foo.cpp"], 2015 } 2016 2017 genrule { 2018 name: "gen", 2019 tools: ["tool"], 2020 out: ["gen.cpp"], 2021 cmd: "$(location tool) $(out)", 2022 } 2023 ` 2024 2025 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 2026 ctx := testCcWithConfig(t, config) 2027 2028 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install") 2029 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install") 2030 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install") 2031 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install") 2032 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install") 2033 2034 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) { 2035 t.Errorf("expected host bin dependency %q, got %q", w, g) 2036 } 2037 2038 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) { 2039 t.Errorf("expected host bin dependency %q, got %q", w, g) 2040 } 2041 2042 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) { 2043 t.Errorf("expected host bin dependency %q, got %q", w, g) 2044 } 2045 2046 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) { 2047 t.Errorf("expected host bin dependency %q, got %q", w, g) 2048 } 2049 2050 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) { 2051 t.Errorf("expected no host bin dependency %q, got %q", w, g) 2052 } 2053 2054 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install") 2055 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install") 2056 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install") 2057 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install") 2058 2059 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) { 2060 t.Errorf("expected device bin dependency %q, got %q", w, g) 2061 } 2062 2063 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) { 2064 t.Errorf("expected device bin dependency %q, got %q", w, g) 2065 } 2066 2067 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) { 2068 t.Errorf("expected device bin dependency %q, got %q", w, g) 2069 } 2070 2071 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) { 2072 t.Errorf("expected device bin dependency %q, got %q", w, g) 2073 } 2074 2075 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) { 2076 t.Errorf("expected no device bin dependency %q, got %q", w, g) 2077 } 2078 2079} 2080 2081func TestStubsLibReexportsHeaders(t *testing.T) { 2082 t.Parallel() 2083 ctx := testCc(t, ` 2084 cc_library_shared { 2085 name: "libclient", 2086 srcs: ["foo.c"], 2087 shared_libs: ["libfoo#1"], 2088 } 2089 2090 cc_library_shared { 2091 name: "libfoo", 2092 srcs: ["foo.c"], 2093 shared_libs: ["libbar"], 2094 export_shared_lib_headers: ["libbar"], 2095 stubs: { 2096 symbol_file: "foo.map.txt", 2097 versions: ["1", "2", "3"], 2098 }, 2099 } 2100 2101 cc_library_shared { 2102 name: "libbar", 2103 export_include_dirs: ["include/libbar"], 2104 srcs: ["foo.c"], 2105 }`) 2106 2107 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 2108 2109 if !strings.Contains(cFlags, "-Iinclude/libbar") { 2110 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags) 2111 } 2112} 2113 2114func TestAidlLibraryWithHeaders(t *testing.T) { 2115 t.Parallel() 2116 ctx := android.GroupFixturePreparers( 2117 prepareForCcTest, 2118 aidl_library.PrepareForTestWithAidlLibrary, 2119 android.MockFS{ 2120 "package_bar/Android.bp": []byte(` 2121 aidl_library { 2122 name: "bar", 2123 srcs: ["x/y/Bar.aidl"], 2124 hdrs: ["x/HeaderBar.aidl"], 2125 strip_import_prefix: "x", 2126 } 2127 `)}.AddToFixture(), 2128 android.MockFS{ 2129 "package_foo/Android.bp": []byte(` 2130 aidl_library { 2131 name: "foo", 2132 srcs: ["a/b/Foo.aidl"], 2133 hdrs: ["a/HeaderFoo.aidl"], 2134 strip_import_prefix: "a", 2135 deps: ["bar"], 2136 } 2137 cc_library { 2138 name: "libfoo", 2139 aidl: { 2140 libs: ["foo"], 2141 } 2142 } 2143 `), 2144 }.AddToFixture(), 2145 ).RunTest(t).TestContext 2146 2147 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") 2148 2149 android.AssertPathsRelativeToTopEquals( 2150 t, 2151 "aidl headers", 2152 []string{ 2153 "package_bar/x/HeaderBar.aidl", 2154 "package_foo/a/HeaderFoo.aidl", 2155 "package_foo/a/b/Foo.aidl", 2156 "out/soong/.intermediates/package_foo/libfoo/android_arm64_armv8-a_static/gen/aidl_library.sbox.textproto", 2157 }, 2158 libfoo.Rule("aidl_library").Implicits, 2159 ) 2160 2161 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl_library.sbox.textproto")) 2162 aidlCommand := manifest.Commands[0].GetCommand() 2163 2164 expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x" 2165 if !strings.Contains(aidlCommand, expectedAidlFlags) { 2166 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags) 2167 } 2168 2169 outputs := strings.Join(libfoo.AllOutputs(), " ") 2170 2171 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BpFoo.h") 2172 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/BnFoo.h") 2173 android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl_library/b/Foo.h") 2174 android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp") 2175 // Confirm that the aidl header doesn't get compiled to cpp and h files 2176 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BpBar.h") 2177 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/BnBar.h") 2178 android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl_library/y/Bar.h") 2179 android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp") 2180} 2181 2182func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) { 2183 t.Parallel() 2184 ctx := android.GroupFixturePreparers( 2185 prepareForCcTest, 2186 aidl_library.PrepareForTestWithAidlLibrary, 2187 ).RunTestWithBp(t, ` 2188 cc_library { 2189 name: "libfoo", 2190 srcs: ["a/Foo.aidl"], 2191 aidl: { flags: ["-Werror"], }, 2192 } 2193 `) 2194 2195 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") 2196 manifest := android.RuleBuilderSboxProtoForTests(t, ctx.TestContext, libfoo.Output("aidl.sbox.textproto")) 2197 aidlCommand := manifest.Commands[0].GetCommand() 2198 expectedAidlFlag := "-Werror" 2199 if !strings.Contains(aidlCommand, expectedAidlFlag) { 2200 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 2201 } 2202} 2203 2204func TestAidlFlagsWithMinSdkVersion(t *testing.T) { 2205 t.Parallel() 2206 for _, tc := range []struct { 2207 name string 2208 sdkVersion string 2209 variant string 2210 expected string 2211 }{ 2212 { 2213 name: "default is current", 2214 sdkVersion: "", 2215 variant: "android_arm64_armv8-a_static", 2216 expected: "platform_apis", 2217 }, 2218 { 2219 name: "use sdk_version", 2220 sdkVersion: `sdk_version: "29"`, 2221 variant: "android_arm64_armv8-a_static", 2222 expected: "platform_apis", 2223 }, 2224 { 2225 name: "use sdk_version(sdk variant)", 2226 sdkVersion: `sdk_version: "29"`, 2227 variant: "android_arm64_armv8-a_sdk_static", 2228 expected: "29", 2229 }, 2230 { 2231 name: "use min_sdk_version", 2232 sdkVersion: `min_sdk_version: "29"`, 2233 variant: "android_arm64_armv8-a_static", 2234 expected: "29", 2235 }, 2236 } { 2237 t.Run(tc.name, func(t *testing.T) { 2238 ctx := testCc(t, ` 2239 cc_library { 2240 name: "libfoo", 2241 stl: "none", 2242 srcs: ["a/Foo.aidl"], 2243 `+tc.sdkVersion+` 2244 } 2245 `) 2246 libfoo := ctx.ModuleForTests("libfoo", tc.variant) 2247 manifest := android.RuleBuilderSboxProtoForTests(t, ctx, libfoo.Output("aidl.sbox.textproto")) 2248 aidlCommand := manifest.Commands[0].GetCommand() 2249 expectedAidlFlag := "--min_sdk_version=" + tc.expected 2250 if !strings.Contains(aidlCommand, expectedAidlFlag) { 2251 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 2252 } 2253 }) 2254 } 2255} 2256 2257func TestInvalidAidlProp(t *testing.T) { 2258 t.Parallel() 2259 2260 testCases := []struct { 2261 description string 2262 bp string 2263 }{ 2264 { 2265 description: "Invalid use of aidl.libs and aidl.include_dirs", 2266 bp: ` 2267 cc_library { 2268 name: "foo", 2269 aidl: { 2270 libs: ["foo_aidl"], 2271 include_dirs: ["bar/include"], 2272 } 2273 } 2274 `, 2275 }, 2276 { 2277 description: "Invalid use of aidl.libs and aidl.local_include_dirs", 2278 bp: ` 2279 cc_library { 2280 name: "foo", 2281 aidl: { 2282 libs: ["foo_aidl"], 2283 local_include_dirs: ["include"], 2284 } 2285 } 2286 `, 2287 }, 2288 } 2289 2290 for _, testCase := range testCases { 2291 t.Run(testCase.description, func(t *testing.T) { 2292 bp := ` 2293 aidl_library { 2294 name: "foo_aidl", 2295 srcs: ["Foo.aidl"], 2296 } ` + testCase.bp 2297 android.GroupFixturePreparers( 2298 prepareForCcTest, 2299 aidl_library.PrepareForTestWithAidlLibrary. 2300 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("For aidl headers, please only use aidl.libs prop")), 2301 ).RunTestWithBp(t, bp) 2302 }) 2303 } 2304} 2305 2306func TestMinSdkVersionInClangTriple(t *testing.T) { 2307 t.Parallel() 2308 ctx := testCc(t, ` 2309 cc_library_shared { 2310 name: "libfoo", 2311 srcs: ["foo.c"], 2312 min_sdk_version: "29", 2313 }`) 2314 2315 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 2316 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29") 2317} 2318 2319func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) { 2320 t.Parallel() 2321 bp := ` 2322 cc_library_shared { 2323 name: "libfoo", 2324 srcs: ["foo.c"], 2325 min_sdk_version: "S", 2326 } 2327 ` 2328 result := android.GroupFixturePreparers( 2329 prepareForCcTest, 2330 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2331 variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"} 2332 }), 2333 ).RunTestWithBp(t, bp) 2334 ctx := result.TestContext 2335 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 2336 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31") 2337} 2338 2339func TestIncludeDirsExporting(t *testing.T) { 2340 t.Parallel() 2341 2342 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves 2343 // embedded newline characters alone. 2344 trimIndentingSpaces := func(s string) string { 2345 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1")) 2346 } 2347 2348 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) { 2349 t.Helper() 2350 expected = trimIndentingSpaces(expected) 2351 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n")) 2352 if expected != actual { 2353 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual) 2354 } 2355 } 2356 2357 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo) 2358 2359 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) { 2360 t.Helper() 2361 exported, _ := android.OtherModuleProvider(ctx, module, FlagExporterInfoProvider) 2362 name := module.Name() 2363 2364 for _, checker := range checkers { 2365 checker(t, name, exported) 2366 } 2367 } 2368 2369 expectedIncludeDirs := func(expectedPaths string) exportedChecker { 2370 return func(t *testing.T, name string, exported FlagExporterInfo) { 2371 t.Helper() 2372 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs) 2373 } 2374 } 2375 2376 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker { 2377 return func(t *testing.T, name string, exported FlagExporterInfo) { 2378 t.Helper() 2379 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs) 2380 } 2381 } 2382 2383 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker { 2384 return func(t *testing.T, name string, exported FlagExporterInfo) { 2385 t.Helper() 2386 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders) 2387 } 2388 } 2389 2390 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker { 2391 return func(t *testing.T, name string, exported FlagExporterInfo) { 2392 t.Helper() 2393 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps) 2394 } 2395 } 2396 2397 genRuleModules := ` 2398 genrule { 2399 name: "genrule_foo", 2400 cmd: "generate-foo", 2401 out: [ 2402 "generated_headers/foo/generated_header.h", 2403 ], 2404 export_include_dirs: [ 2405 "generated_headers", 2406 ], 2407 } 2408 2409 genrule { 2410 name: "genrule_bar", 2411 cmd: "generate-bar", 2412 out: [ 2413 "generated_headers/bar/generated_header.h", 2414 ], 2415 export_include_dirs: [ 2416 "generated_headers", 2417 ], 2418 } 2419 ` 2420 2421 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) { 2422 ctx := testCc(t, genRuleModules+` 2423 cc_library { 2424 name: "libfoo", 2425 srcs: ["foo.c"], 2426 export_include_dirs: ["foo/standard"], 2427 export_system_include_dirs: ["foo/system"], 2428 generated_headers: ["genrule_foo"], 2429 export_generated_headers: ["genrule_foo"], 2430 } 2431 2432 cc_library { 2433 name: "libbar", 2434 srcs: ["bar.c"], 2435 shared_libs: ["libfoo"], 2436 export_include_dirs: ["bar/standard"], 2437 export_system_include_dirs: ["bar/system"], 2438 generated_headers: ["genrule_bar"], 2439 export_generated_headers: ["genrule_bar"], 2440 } 2441 `) 2442 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 2443 checkIncludeDirs(t, ctx, foo, 2444 expectedIncludeDirs(` 2445 foo/standard 2446 .intermediates/genrule_foo/gen/generated_headers 2447 `), 2448 expectedSystemIncludeDirs(`foo/system`), 2449 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 2450 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 2451 ) 2452 2453 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module() 2454 checkIncludeDirs(t, ctx, bar, 2455 expectedIncludeDirs(` 2456 bar/standard 2457 .intermediates/genrule_bar/gen/generated_headers 2458 `), 2459 expectedSystemIncludeDirs(`bar/system`), 2460 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`), 2461 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`), 2462 ) 2463 }) 2464 2465 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) { 2466 ctx := testCc(t, genRuleModules+` 2467 cc_library { 2468 name: "libfoo", 2469 srcs: ["foo.c"], 2470 export_include_dirs: ["foo/standard"], 2471 export_system_include_dirs: ["foo/system"], 2472 generated_headers: ["genrule_foo"], 2473 export_generated_headers: ["genrule_foo"], 2474 } 2475 2476 cc_library { 2477 name: "libbar", 2478 srcs: ["bar.c"], 2479 whole_static_libs: ["libfoo"], 2480 export_include_dirs: ["bar/standard"], 2481 export_system_include_dirs: ["bar/system"], 2482 generated_headers: ["genrule_bar"], 2483 export_generated_headers: ["genrule_bar"], 2484 } 2485 `) 2486 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 2487 checkIncludeDirs(t, ctx, foo, 2488 expectedIncludeDirs(` 2489 foo/standard 2490 .intermediates/genrule_foo/gen/generated_headers 2491 `), 2492 expectedSystemIncludeDirs(`foo/system`), 2493 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 2494 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 2495 ) 2496 2497 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module() 2498 checkIncludeDirs(t, ctx, bar, 2499 expectedIncludeDirs(` 2500 bar/standard 2501 foo/standard 2502 .intermediates/genrule_foo/gen/generated_headers 2503 .intermediates/genrule_bar/gen/generated_headers 2504 `), 2505 expectedSystemIncludeDirs(` 2506 bar/system 2507 foo/system 2508 `), 2509 expectedGeneratedHeaders(` 2510 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h 2511 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h 2512 `), 2513 expectedOrderOnlyDeps(` 2514 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h 2515 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h 2516 `), 2517 ) 2518 }) 2519 2520 t.Run("ensure only aidl headers are exported", func(t *testing.T) { 2521 ctx := android.GroupFixturePreparers( 2522 prepareForCcTest, 2523 aidl_library.PrepareForTestWithAidlLibrary, 2524 ).RunTestWithBp(t, ` 2525 aidl_library { 2526 name: "libfoo_aidl", 2527 srcs: ["x/y/Bar.aidl"], 2528 strip_import_prefix: "x", 2529 } 2530 cc_library_shared { 2531 name: "libfoo", 2532 srcs: [ 2533 "foo.c", 2534 "b.aidl", 2535 "a.proto", 2536 ], 2537 aidl: { 2538 libs: ["libfoo_aidl"], 2539 export_aidl_headers: true, 2540 } 2541 } 2542 `).TestContext 2543 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 2544 checkIncludeDirs(t, ctx, foo, 2545 expectedIncludeDirs(` 2546 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl 2547 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library 2548 `), 2549 expectedSystemIncludeDirs(``), 2550 expectedGeneratedHeaders(` 2551 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h 2552 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h 2553 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h 2554 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h 2555 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h 2556 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h 2557 `), 2558 expectedOrderOnlyDeps(` 2559 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h 2560 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h 2561 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h 2562 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/Bar.h 2563 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BnBar.h 2564 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl_library/y/BpBar.h 2565 `), 2566 ) 2567 }) 2568 2569 t.Run("ensure only proto headers are exported", func(t *testing.T) { 2570 ctx := testCc(t, genRuleModules+` 2571 cc_library_shared { 2572 name: "libfoo", 2573 srcs: [ 2574 "foo.c", 2575 "b.aidl", 2576 "a.proto", 2577 ], 2578 proto: { 2579 export_proto_headers: true, 2580 } 2581 } 2582 `) 2583 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 2584 checkIncludeDirs(t, ctx, foo, 2585 expectedIncludeDirs(` 2586 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto 2587 `), 2588 expectedSystemIncludeDirs(``), 2589 expectedGeneratedHeaders(` 2590 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h 2591 `), 2592 expectedOrderOnlyDeps(` 2593 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h 2594 `), 2595 ) 2596 }) 2597 2598 t.Run("ensure only sysprop headers are exported", func(t *testing.T) { 2599 ctx := testCc(t, genRuleModules+` 2600 cc_library_shared { 2601 name: "libfoo", 2602 srcs: [ 2603 "foo.c", 2604 "path/to/a.sysprop", 2605 "b.aidl", 2606 "a.proto", 2607 ], 2608 } 2609 `) 2610 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 2611 checkIncludeDirs(t, ctx, foo, 2612 expectedIncludeDirs(` 2613 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include 2614 `), 2615 expectedSystemIncludeDirs(``), 2616 expectedGeneratedHeaders(` 2617 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h 2618 `), 2619 expectedOrderOnlyDeps(` 2620 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h 2621 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h 2622 `), 2623 ) 2624 }) 2625} 2626 2627func TestIncludeDirectoryOrdering(t *testing.T) { 2628 t.Parallel() 2629 2630 expectedPlatformFlags := []string{ 2631 "-nostdlibinc", 2632 } 2633 2634 baseExpectedFlags := []string{ 2635 "${config.ArmThumbCflags}", 2636 "${config.ArmCflags}", 2637 "${config.CommonGlobalCflags}", 2638 "${config.DeviceGlobalCflags}", 2639 "${config.ExternalCflags}", 2640 "${config.ArmToolchainCflags}", 2641 "${config.ArmArmv7ANeonCflags}", 2642 "${config.ArmGenericCflags}", 2643 } 2644 2645 expectedTargetNDKFlags := []string{ 2646 "-target", 2647 "armv7a-linux-androideabi21", 2648 } 2649 2650 expectedTargetPlatformFlags := []string{ 2651 "-target", 2652 "armv7a-linux-androideabi10000", 2653 } 2654 2655 expectedIncludes := []string{ 2656 "external/foo/android_arm_export_include_dirs", 2657 "external/foo/lib32_export_include_dirs", 2658 "external/foo/arm_export_include_dirs", 2659 "external/foo/android_export_include_dirs", 2660 "external/foo/linux_export_include_dirs", 2661 "external/foo/export_include_dirs", 2662 "external/foo/android_arm_local_include_dirs", 2663 "external/foo/lib32_local_include_dirs", 2664 "external/foo/arm_local_include_dirs", 2665 "external/foo/android_local_include_dirs", 2666 "external/foo/linux_local_include_dirs", 2667 "external/foo/local_include_dirs", 2668 "external/foo", 2669 "external/foo/libheader1", 2670 "external/foo/libheader2", 2671 "external/foo/libwhole1", 2672 "external/foo/libwhole2", 2673 "external/foo/libstatic1", 2674 "external/foo/libstatic2", 2675 "external/foo/libshared1", 2676 "external/foo/libshared2", 2677 "external/foo/liblinux", 2678 "external/foo/libandroid", 2679 "external/foo/libarm", 2680 "external/foo/lib32", 2681 "external/foo/libandroid_arm", 2682 } 2683 2684 expectedNDKSTLIncludes := []string{ 2685 "defaults/cc/common/ndk_libc++_shared_include_dirs", 2686 } 2687 2688 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"} 2689 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"} 2690 2691 cflags := []string{"-Werror", "-std=candcpp"} 2692 cstd := []string{"-std=gnu17", "-std=conly"} 2693 cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"} 2694 2695 lastNDKFlags := []string{ 2696 "--sysroot", 2697 "out/soong/ndk/sysroot", 2698 } 2699 2700 lastPlatformIncludes := []string{ 2701 "${config.CommonGlobalIncludes}", 2702 } 2703 2704 testCases := []struct { 2705 name string 2706 src string 2707 expectedNDK []string 2708 expectedPlatform []string 2709 }{ 2710 { 2711 name: "c", 2712 src: "foo.c", 2713 expectedNDK: slices.Concat( 2714 baseExpectedFlags, 2715 expectedTargetNDKFlags, 2716 conly, 2717 expectedIncludes, 2718 expectedNDKSTLIncludes, 2719 cflags, 2720 cstd, 2721 lastNDKFlags, 2722 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}, 2723 ), 2724 expectedPlatform: slices.Concat( 2725 expectedPlatformFlags, 2726 baseExpectedFlags, 2727 expectedTargetPlatformFlags, 2728 conly, 2729 expectedIncludes, 2730 cflags, 2731 cstd, 2732 lastPlatformIncludes, 2733 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}, 2734 ), 2735 }, 2736 { 2737 name: "cc", 2738 src: "foo.cc", 2739 expectedNDK: slices.Concat( 2740 baseExpectedFlags, 2741 expectedTargetNDKFlags, 2742 cppOnly, 2743 expectedIncludes, 2744 expectedNDKSTLIncludes, 2745 cflags, 2746 cppstd, 2747 lastNDKFlags, 2748 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}, 2749 ), 2750 expectedPlatform: slices.Concat( 2751 expectedPlatformFlags, 2752 baseExpectedFlags, 2753 expectedTargetPlatformFlags, 2754 cppOnly, 2755 expectedIncludes, 2756 cflags, 2757 cppstd, 2758 lastPlatformIncludes, 2759 []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}, 2760 ), 2761 }, 2762 { 2763 name: "assemble", 2764 src: "foo.s", 2765 expectedNDK: slices.Concat( 2766 baseExpectedFlags, 2767 expectedTargetNDKFlags, 2768 []string{"${config.CommonGlobalAsflags}"}, 2769 expectedIncludes, 2770 expectedNDKSTLIncludes, 2771 lastNDKFlags, 2772 ), 2773 expectedPlatform: slices.Concat( 2774 expectedPlatformFlags, 2775 baseExpectedFlags, 2776 expectedTargetPlatformFlags, 2777 []string{"${config.CommonGlobalAsflags}"}, 2778 expectedIncludes, 2779 lastPlatformIncludes, 2780 ), 2781 }, 2782 } 2783 2784 for _, tc := range testCases { 2785 t.Run(tc.name, func(t *testing.T) { 2786 bp := fmt.Sprintf(` 2787 cc_library { 2788 name: "libfoo", 2789 srcs: ["%s"], 2790 cflags: ["-std=candcpp"], 2791 conlyflags: ["-std=conly"], 2792 cppflags: ["-std=cpp"], 2793 local_include_dirs: ["local_include_dirs"], 2794 export_include_dirs: ["export_include_dirs"], 2795 export_system_include_dirs: ["export_system_include_dirs"], 2796 static_libs: ["libstatic1", "libstatic2"], 2797 whole_static_libs: ["libwhole1", "libwhole2"], 2798 shared_libs: ["libshared1", "libshared2"], 2799 header_libs: ["libheader1", "libheader2"], 2800 target: { 2801 android: { 2802 shared_libs: ["libandroid"], 2803 local_include_dirs: ["android_local_include_dirs"], 2804 export_include_dirs: ["android_export_include_dirs"], 2805 }, 2806 android_arm: { 2807 shared_libs: ["libandroid_arm"], 2808 local_include_dirs: ["android_arm_local_include_dirs"], 2809 export_include_dirs: ["android_arm_export_include_dirs"], 2810 }, 2811 linux: { 2812 shared_libs: ["liblinux"], 2813 local_include_dirs: ["linux_local_include_dirs"], 2814 export_include_dirs: ["linux_export_include_dirs"], 2815 }, 2816 }, 2817 multilib: { 2818 lib32: { 2819 shared_libs: ["lib32"], 2820 local_include_dirs: ["lib32_local_include_dirs"], 2821 export_include_dirs: ["lib32_export_include_dirs"], 2822 }, 2823 }, 2824 arch: { 2825 arm: { 2826 shared_libs: ["libarm"], 2827 local_include_dirs: ["arm_local_include_dirs"], 2828 export_include_dirs: ["arm_export_include_dirs"], 2829 }, 2830 }, 2831 stl: "libc++", 2832 sdk_version: "minimum", 2833 } 2834 2835 cc_library_headers { 2836 name: "libheader1", 2837 export_include_dirs: ["libheader1"], 2838 sdk_version: "minimum", 2839 stl: "none", 2840 } 2841 2842 cc_library_headers { 2843 name: "libheader2", 2844 export_include_dirs: ["libheader2"], 2845 sdk_version: "minimum", 2846 stl: "none", 2847 } 2848 `, tc.src) 2849 2850 libs := []string{ 2851 "libstatic1", 2852 "libstatic2", 2853 "libwhole1", 2854 "libwhole2", 2855 "libshared1", 2856 "libshared2", 2857 "libandroid", 2858 "libandroid_arm", 2859 "liblinux", 2860 "lib32", 2861 "libarm", 2862 } 2863 2864 for _, lib := range libs { 2865 bp += fmt.Sprintf(` 2866 cc_library { 2867 name: "%s", 2868 export_include_dirs: ["%s"], 2869 sdk_version: "minimum", 2870 stl: "none", 2871 } 2872 `, lib, lib) 2873 } 2874 2875 runTest := func(t *testing.T, variant string, expected []string) { 2876 ctx := android.GroupFixturePreparers( 2877 PrepareForIntegrationTestWithCc, 2878 android.FixtureAddTextFile("external/foo/Android.bp", bp), 2879 ).RunTest(t) 2880 cflags := ctx.ModuleForTests("libfoo", variant).Output("obj/external/foo/foo.o").Args["cFlags"] 2881 2882 var includes []string 2883 flags := strings.Split(cflags, " ") 2884 for _, flag := range flags { 2885 if strings.HasPrefix(flag, "-I") { 2886 includes = append(includes, strings.TrimPrefix(flag, "-I")) 2887 } else if flag == "-isystem" { 2888 // skip isystem, include next 2889 } else if len(flag) > 0 { 2890 includes = append(includes, flag) 2891 } 2892 } 2893 2894 android.AssertArrayString(t, "includes", expected, includes) 2895 } 2896 2897 t.Run("platform", func(t *testing.T) { 2898 runTest(t, "android_arm_armv7-a-neon_static", tc.expectedPlatform) 2899 }) 2900 t.Run("ndk", func(t *testing.T) { 2901 runTest(t, "android_arm_armv7-a-neon_sdk_static", tc.expectedNDK) 2902 }) 2903 }) 2904 } 2905 2906} 2907 2908func TestAddnoOverride64GlobalCflags(t *testing.T) { 2909 t.Parallel() 2910 ctx := testCc(t, ` 2911 cc_library_shared { 2912 name: "libclient", 2913 srcs: ["foo.c"], 2914 shared_libs: ["libfoo#1"], 2915 } 2916 2917 cc_library_shared { 2918 name: "libfoo", 2919 srcs: ["foo.c"], 2920 shared_libs: ["libbar"], 2921 export_shared_lib_headers: ["libbar"], 2922 stubs: { 2923 symbol_file: "foo.map.txt", 2924 versions: ["1", "2", "3"], 2925 }, 2926 } 2927 2928 cc_library_shared { 2929 name: "libbar", 2930 export_include_dirs: ["include/libbar"], 2931 srcs: ["foo.c"], 2932 }`) 2933 2934 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 2935 2936 if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") { 2937 t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags) 2938 } 2939} 2940 2941func TestCcBuildBrokenClangProperty(t *testing.T) { 2942 t.Parallel() 2943 tests := []struct { 2944 name string 2945 clang bool 2946 BuildBrokenClangProperty bool 2947 err string 2948 }{ 2949 { 2950 name: "error when clang is set to false", 2951 clang: false, 2952 err: "is no longer supported", 2953 }, 2954 { 2955 name: "error when clang is set to true", 2956 clang: true, 2957 err: "property is deprecated, see Changes.md", 2958 }, 2959 { 2960 name: "no error when BuildBrokenClangProperty is explicitly set to true", 2961 clang: true, 2962 BuildBrokenClangProperty: true, 2963 }, 2964 } 2965 2966 for _, test := range tests { 2967 t.Run(test.name, func(t *testing.T) { 2968 bp := fmt.Sprintf(` 2969 cc_library { 2970 name: "foo", 2971 clang: %t, 2972 }`, test.clang) 2973 2974 if test.err == "" { 2975 android.GroupFixturePreparers( 2976 prepareForCcTest, 2977 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 2978 if test.BuildBrokenClangProperty { 2979 variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty 2980 } 2981 }), 2982 ).RunTestWithBp(t, bp) 2983 } else { 2984 prepareForCcTest. 2985 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)). 2986 RunTestWithBp(t, bp) 2987 } 2988 }) 2989 } 2990} 2991 2992func TestCcBuildBrokenClangAsFlags(t *testing.T) { 2993 t.Parallel() 2994 tests := []struct { 2995 name string 2996 clangAsFlags []string 2997 BuildBrokenClangAsFlags bool 2998 err string 2999 }{ 3000 { 3001 name: "error when clang_asflags is set", 3002 clangAsFlags: []string{"-a", "-b"}, 3003 err: "clang_asflags: property is deprecated", 3004 }, 3005 { 3006 name: "no error when BuildBrokenClangAsFlags is explicitly set to true", 3007 clangAsFlags: []string{"-a", "-b"}, 3008 BuildBrokenClangAsFlags: true, 3009 }, 3010 } 3011 3012 for _, test := range tests { 3013 t.Run(test.name, func(t *testing.T) { 3014 bp := fmt.Sprintf(` 3015 cc_library { 3016 name: "foo", 3017 clang_asflags: %s, 3018 }`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`) 3019 3020 if test.err == "" { 3021 android.GroupFixturePreparers( 3022 prepareForCcTest, 3023 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3024 if test.BuildBrokenClangAsFlags { 3025 variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags 3026 } 3027 }), 3028 ).RunTestWithBp(t, bp) 3029 } else { 3030 prepareForCcTest. 3031 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)). 3032 RunTestWithBp(t, bp) 3033 } 3034 }) 3035 } 3036} 3037 3038func TestCcBuildBrokenClangCFlags(t *testing.T) { 3039 t.Parallel() 3040 tests := []struct { 3041 name string 3042 clangCFlags []string 3043 BuildBrokenClangCFlags bool 3044 err string 3045 }{ 3046 { 3047 name: "error when clang_cflags is set", 3048 clangCFlags: []string{"-a", "-b"}, 3049 err: "clang_cflags: property is deprecated", 3050 }, 3051 { 3052 name: "no error when BuildBrokenClangCFlags is explicitly set to true", 3053 clangCFlags: []string{"-a", "-b"}, 3054 BuildBrokenClangCFlags: true, 3055 }, 3056 } 3057 3058 for _, test := range tests { 3059 t.Run(test.name, func(t *testing.T) { 3060 bp := fmt.Sprintf(` 3061 cc_library { 3062 name: "foo", 3063 clang_cflags: %s, 3064 }`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`) 3065 3066 if test.err == "" { 3067 android.GroupFixturePreparers( 3068 prepareForCcTest, 3069 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3070 if test.BuildBrokenClangCFlags { 3071 variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags 3072 } 3073 }), 3074 ).RunTestWithBp(t, bp) 3075 } else { 3076 prepareForCcTest. 3077 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)). 3078 RunTestWithBp(t, bp) 3079 } 3080 }) 3081 } 3082} 3083 3084func TestStrippedAllOutputFile(t *testing.T) { 3085 t.Parallel() 3086 bp := ` 3087 cc_library { 3088 name: "test_lib", 3089 srcs: ["test_lib.cpp"], 3090 dist: { 3091 targets: [ "dist_target" ], 3092 tag: "stripped_all", 3093 } 3094 } 3095 ` 3096 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 3097 ctx := testCcWithConfig(t, config) 3098 testingModule := ctx.ModuleForTests("test_lib", "android_arm_armv7-a-neon_shared") 3099 outputFile := testingModule.OutputFiles(ctx, t, "stripped_all") 3100 if !strings.HasSuffix(outputFile.Strings()[0], "/stripped_all/test_lib.so") { 3101 t.Errorf("Unexpected output file: %s", outputFile.Strings()[0]) 3102 return 3103 } 3104} 3105 3106func TestImageVariants(t *testing.T) { 3107 t.Parallel() 3108 3109 bp := ` 3110 cc_binary { 3111 name: "binfoo", 3112 srcs: ["binfoo.cc"], 3113 vendor_available: true, 3114 product_available: true, 3115 shared_libs: ["libbar"] 3116 } 3117 cc_library { 3118 name: "libbar", 3119 srcs: ["libbar.cc"], 3120 vendor_available: true, 3121 product_available: true, 3122 } 3123 ` 3124 3125 ctx := prepareForCcTest.RunTestWithBp(t, bp) 3126 3127 hasDep := func(m android.Module, wantDep android.Module) bool { 3128 t.Helper() 3129 var found bool 3130 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 3131 if dep == wantDep { 3132 found = true 3133 } 3134 }) 3135 return found 3136 } 3137 3138 testDepWithVariant := func(imageVariant string) { 3139 imageVariantStr := "" 3140 if imageVariant != "core" { 3141 imageVariantStr = "_" + imageVariant 3142 } 3143 binFooModule := ctx.ModuleForTests("binfoo", "android"+imageVariantStr+"_arm64_armv8-a").Module() 3144 libBarModule := ctx.ModuleForTests("libbar", "android"+imageVariantStr+"_arm64_armv8-a_shared").Module() 3145 android.AssertBoolEquals(t, "binfoo should have dependency on libbar with image variant "+imageVariant, true, hasDep(binFooModule, libBarModule)) 3146 } 3147 3148 testDepWithVariant("core") 3149 testDepWithVariant("vendor") 3150 testDepWithVariant("product") 3151} 3152 3153func TestVendorOrProductVariantUsesPlatformSdkVersionAsDefault(t *testing.T) { 3154 t.Parallel() 3155 3156 bp := ` 3157 cc_library { 3158 name: "libfoo", 3159 srcs: ["libfoo.cc"], 3160 vendor_available: true, 3161 product_available: true, 3162 } 3163 3164 cc_library { 3165 name: "libbar", 3166 srcs: ["libbar.cc"], 3167 vendor_available: true, 3168 product_available: true, 3169 min_sdk_version: "29", 3170 } 3171 ` 3172 3173 ctx := prepareForCcTest.RunTestWithBp(t, bp) 3174 testSdkVersionFlag := func(module, variant, version string) { 3175 flags := ctx.ModuleForTests(module, "android_"+variant+"_arm64_armv8-a_static").Rule("cc").Args["cFlags"] 3176 android.AssertStringDoesContain(t, "target SDK version", flags, "-target aarch64-linux-android"+version) 3177 } 3178 3179 testSdkVersionFlag("libfoo", "vendor", "30") 3180 testSdkVersionFlag("libfoo", "product", "30") 3181 // target SDK version can be set explicitly with min_sdk_version 3182 testSdkVersionFlag("libbar", "vendor", "29") 3183 testSdkVersionFlag("libbar", "product", "29") 3184} 3185 3186func TestClangVerify(t *testing.T) { 3187 t.Parallel() 3188 3189 ctx := testCc(t, ` 3190 cc_library { 3191 name: "lib_no_clang_verify", 3192 srcs: ["libnocv.cc"], 3193 } 3194 3195 cc_library { 3196 name: "lib_clang_verify", 3197 srcs: ["libcv.cc"], 3198 clang_verify: true, 3199 } 3200 `) 3201 3202 module := ctx.ModuleForTests("lib_no_clang_verify", "android_arm64_armv8-a_shared") 3203 3204 cFlags_no_cv := module.Rule("cc").Args["cFlags"] 3205 if strings.Contains(cFlags_no_cv, "-Xclang") || strings.Contains(cFlags_no_cv, "-verify") { 3206 t.Errorf("expected %q not in cflags, got %q", "-Xclang -verify", cFlags_no_cv) 3207 } 3208 3209 cFlags_cv := ctx.ModuleForTests("lib_clang_verify", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 3210 if strings.Contains(cFlags_cv, "-Xclang") && strings.Contains(cFlags_cv, "-verify") { 3211 t.Errorf("expected %q in cflags, got %q", "-Xclang -verify", cFlags_cv) 3212 } 3213} 3214 3215func TestCheckConflictingExplicitVersions(t *testing.T) { 3216 PrepareForIntegrationTestWithCc. 3217 ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern( 3218 `shared_libs: duplicate shared libraries with different explicit versions: "libbar" and "libbar#impl"`, 3219 )). 3220 RunTestWithBp(t, ` 3221 cc_library { 3222 name: "libfoo", 3223 shared_libs: ["libbar", "libbar#impl"], 3224 } 3225 3226 cc_library { 3227 name: "libbar", 3228 } 3229 `) 3230} 3231