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