1// Copyright 2019 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 "runtime" 20 "testing" 21 22 "android/soong/android" 23 "github.com/google/blueprint" 24) 25 26var prepareForPrebuiltTest = android.GroupFixturePreparers( 27 prepareForCcTest, 28 android.PrepareForTestWithAndroidMk, 29) 30 31func testPrebuilt(t *testing.T, bp string, fs android.MockFS, handlers ...android.FixturePreparer) *android.TestContext { 32 t.Helper() 33 result := android.GroupFixturePreparers( 34 prepareForPrebuiltTest, 35 fs.AddToFixture(), 36 android.GroupFixturePreparers(handlers...), 37 ).RunTestWithBp(t, bp) 38 39 return result.TestContext 40} 41 42type configCustomizer func(config android.Config) 43 44func TestPrebuilt(t *testing.T) { 45 bp := ` 46 cc_library { 47 name: "liba", 48 } 49 50 cc_prebuilt_library_shared { 51 name: "liba", 52 srcs: ["liba.so"], 53 } 54 55 cc_library { 56 name: "libb", 57 } 58 59 cc_prebuilt_library_static { 60 name: "libb", 61 srcs: ["libb.a"], 62 } 63 64 cc_library_shared { 65 name: "libd", 66 } 67 68 cc_prebuilt_library_shared { 69 name: "libd", 70 srcs: ["libd.so"], 71 } 72 73 cc_library_static { 74 name: "libe", 75 } 76 77 cc_prebuilt_library_static { 78 name: "libe", 79 srcs: ["libe.a"], 80 } 81 82 cc_library { 83 name: "libf", 84 } 85 86 cc_prebuilt_library { 87 name: "libf", 88 static: { 89 srcs: ["libf.a"], 90 }, 91 shared: { 92 srcs: ["libf.so"], 93 }, 94 } 95 96 cc_object { 97 name: "crtx", 98 } 99 100 cc_prebuilt_object { 101 name: "crtx", 102 srcs: ["crtx.o"], 103 } 104 ` 105 106 ctx := testPrebuilt(t, bp, map[string][]byte{ 107 "liba.so": nil, 108 "libb.a": nil, 109 "libd.so": nil, 110 "libe.a": nil, 111 "libf.a": nil, 112 "libf.so": nil, 113 "crtx.o": nil, 114 }) 115 116 // Verify that all the modules exist and that their dependencies were connected correctly 117 liba := ctx.ModuleForTests("liba", "android_arm64_armv8-a_shared").Module() 118 libb := ctx.ModuleForTests("libb", "android_arm64_armv8-a_static").Module() 119 libd := ctx.ModuleForTests("libd", "android_arm64_armv8-a_shared").Module() 120 libe := ctx.ModuleForTests("libe", "android_arm64_armv8-a_static").Module() 121 libfStatic := ctx.ModuleForTests("libf", "android_arm64_armv8-a_static").Module() 122 libfShared := ctx.ModuleForTests("libf", "android_arm64_armv8-a_shared").Module() 123 crtx := ctx.ModuleForTests("crtx", "android_arm64_armv8-a").Module() 124 125 prebuiltLiba := ctx.ModuleForTests("prebuilt_liba", "android_arm64_armv8-a_shared").Module() 126 prebuiltLibb := ctx.ModuleForTests("prebuilt_libb", "android_arm64_armv8-a_static").Module() 127 prebuiltLibd := ctx.ModuleForTests("prebuilt_libd", "android_arm64_armv8-a_shared").Module() 128 prebuiltLibe := ctx.ModuleForTests("prebuilt_libe", "android_arm64_armv8-a_static").Module() 129 prebuiltLibfStatic := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_static").Module() 130 prebuiltLibfShared := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_shared").Module() 131 prebuiltCrtx := ctx.ModuleForTests("prebuilt_crtx", "android_arm64_armv8-a").Module() 132 133 hasDep := func(m android.Module, wantDep android.Module) bool { 134 t.Helper() 135 var found bool 136 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 137 if dep == wantDep { 138 found = true 139 } 140 }) 141 return found 142 } 143 144 if !hasDep(liba, prebuiltLiba) { 145 t.Errorf("liba missing dependency on prebuilt_liba") 146 } 147 148 if !hasDep(libb, prebuiltLibb) { 149 t.Errorf("libb missing dependency on prebuilt_libb") 150 } 151 152 if !hasDep(libd, prebuiltLibd) { 153 t.Errorf("libd missing dependency on prebuilt_libd") 154 } 155 156 if !hasDep(libe, prebuiltLibe) { 157 t.Errorf("libe missing dependency on prebuilt_libe") 158 } 159 160 if !hasDep(libfStatic, prebuiltLibfStatic) { 161 t.Errorf("libf static missing dependency on prebuilt_libf") 162 } 163 164 if !hasDep(libfShared, prebuiltLibfShared) { 165 t.Errorf("libf shared missing dependency on prebuilt_libf") 166 } 167 168 if !hasDep(crtx, prebuiltCrtx) { 169 t.Errorf("crtx missing dependency on prebuilt_crtx") 170 } 171 172 entries := android.AndroidMkEntriesForTest(t, ctx, prebuiltLiba)[0] 173 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_prebuilt_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 174 entries = android.AndroidMkEntriesForTest(t, ctx, prebuiltLibb)[0] 175 android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_prebuilt_library_static", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) 176} 177 178func TestPrebuiltLibraryShared(t *testing.T) { 179 ctx := testPrebuilt(t, ` 180 cc_prebuilt_library_shared { 181 name: "libtest", 182 srcs: ["libf.so"], 183 strip: { 184 none: true, 185 }, 186 } 187 `, map[string][]byte{ 188 "libf.so": nil, 189 }) 190 191 shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module) 192 assertString(t, shared.OutputFile().Path().Base(), "libtest.so") 193} 194 195func TestPrebuiltLibraryStatic(t *testing.T) { 196 ctx := testPrebuilt(t, ` 197 cc_prebuilt_library_static { 198 name: "libtest", 199 srcs: ["libf.a"], 200 } 201 `, map[string][]byte{ 202 "libf.a": nil, 203 }) 204 205 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module) 206 assertString(t, static.OutputFile().Path().Base(), "libf.a") 207} 208 209func TestPrebuiltLibrary(t *testing.T) { 210 ctx := testPrebuilt(t, ` 211 cc_prebuilt_library { 212 name: "libtest", 213 static: { 214 srcs: ["libf.a"], 215 }, 216 shared: { 217 srcs: ["libf.so"], 218 }, 219 strip: { 220 none: true, 221 }, 222 } 223 `, map[string][]byte{ 224 "libf.a": nil, 225 "libf.so": nil, 226 }) 227 228 shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module) 229 assertString(t, shared.OutputFile().Path().Base(), "libtest.so") 230 231 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module) 232 assertString(t, static.OutputFile().Path().Base(), "libf.a") 233} 234 235func TestPrebuiltLibraryStem(t *testing.T) { 236 ctx := testPrebuilt(t, ` 237 cc_prebuilt_library { 238 name: "libfoo", 239 stem: "libbar", 240 static: { 241 srcs: ["libfoo.a"], 242 }, 243 shared: { 244 srcs: ["libfoo.so"], 245 }, 246 strip: { 247 none: true, 248 }, 249 } 250 `, map[string][]byte{ 251 "libfoo.a": nil, 252 "libfoo.so": nil, 253 }) 254 255 static := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module) 256 assertString(t, static.OutputFile().Path().Base(), "libfoo.a") 257 258 shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module) 259 assertString(t, shared.OutputFile().Path().Base(), "libbar.so") 260} 261 262func TestPrebuiltLibrarySharedStem(t *testing.T) { 263 ctx := testPrebuilt(t, ` 264 cc_prebuilt_library_shared { 265 name: "libfoo", 266 stem: "libbar", 267 srcs: ["libfoo.so"], 268 strip: { 269 none: true, 270 }, 271 } 272 `, map[string][]byte{ 273 "libfoo.so": nil, 274 }) 275 276 shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module) 277 assertString(t, shared.OutputFile().Path().Base(), "libbar.so") 278} 279 280func TestPrebuiltSymlinkedHostBinary(t *testing.T) { 281 if runtime.GOOS != "linux" { 282 t.Skipf("Skipping host prebuilt testing that is only supported on linux not %s", runtime.GOOS) 283 } 284 285 ctx := testPrebuilt(t, ` 286 cc_prebuilt_library_shared { 287 name: "libfoo", 288 device_supported: false, 289 host_supported: true, 290 target: { 291 linux_glibc_x86_64: { 292 srcs: ["linux_glibc_x86_64/lib64/libfoo.so"], 293 }, 294 }, 295 } 296 297 cc_prebuilt_binary { 298 name: "foo", 299 device_supported: false, 300 host_supported: true, 301 shared_libs: ["libfoo"], 302 target: { 303 linux_glibc_x86_64: { 304 srcs: ["linux_glibc_x86_64/bin/foo"], 305 }, 306 }, 307 } 308 `, map[string][]byte{ 309 "libfoo.so": nil, 310 "foo": nil, 311 }) 312 313 fooRule := ctx.ModuleForTests("foo", "linux_glibc_x86_64").Rule("Symlink") 314 assertString(t, fooRule.Output.String(), "out/soong/.intermediates/foo/linux_glibc_x86_64/foo") 315 assertString(t, fooRule.Args["fromPath"], "$$PWD/linux_glibc_x86_64/bin/foo") 316 317 var libfooDep android.Path 318 for _, dep := range fooRule.Implicits { 319 if dep.Base() == "libfoo.so" { 320 libfooDep = dep 321 break 322 } 323 } 324 assertString(t, libfooDep.String(), "out/soong/.intermediates/libfoo/linux_glibc_x86_64_shared/libfoo.so") 325} 326 327func TestPrebuiltLibrarySanitized(t *testing.T) { 328 bp := `cc_prebuilt_library { 329 name: "libtest", 330 static: { 331 sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, }, 332 }, 333 shared: { 334 sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, }, 335 }, 336 } 337 cc_prebuilt_library_static { 338 name: "libtest_static", 339 sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, }, 340 } 341 cc_prebuilt_library_shared { 342 name: "libtest_shared", 343 sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, }, 344 }` 345 346 fs := map[string][]byte{ 347 "libf.a": nil, 348 "libf.hwasan.a": nil, 349 "libf.so": nil, 350 "hwasan/libf.so": nil, 351 } 352 353 // Without SANITIZE_TARGET. 354 ctx := testPrebuilt(t, bp, fs) 355 356 shared_rule := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip") 357 assertString(t, shared_rule.Input.String(), "libf.so") 358 359 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module) 360 assertString(t, static.OutputFile().Path().Base(), "libf.a") 361 362 shared_rule2 := ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip") 363 assertString(t, shared_rule2.Input.String(), "libf.so") 364 365 static2 := ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static").Module().(*Module) 366 assertString(t, static2.OutputFile().Path().Base(), "libf.a") 367 368 // With SANITIZE_TARGET=hwaddress 369 ctx = testPrebuilt(t, bp, fs, 370 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 371 variables.SanitizeDevice = []string{"hwaddress"} 372 }), 373 ) 374 375 shared_rule = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip") 376 assertString(t, shared_rule.Input.String(), "hwasan/libf.so") 377 378 static = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module) 379 assertString(t, static.OutputFile().Path().Base(), "libf.hwasan.a") 380 381 shared_rule2 = ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip") 382 assertString(t, shared_rule2.Input.String(), "hwasan/libf.so") 383 384 static2 = ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module) 385 assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a") 386} 387 388func TestPrebuiltStubNoinstall(t *testing.T) { 389 testFunc := func(t *testing.T, expectLibfooOnSystemLib bool, fs android.MockFS) { 390 result := android.GroupFixturePreparers( 391 prepareForPrebuiltTest, 392 android.PrepareForTestWithMakevars, 393 android.FixtureMergeMockFs(fs), 394 ).RunTest(t) 395 396 ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld") 397 android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared/libfoo.so") 398 399 installRules := result.InstallMakeRulesForTesting(t) 400 var installedlibRule *android.InstallMakeRule 401 for i, rule := range installRules { 402 if rule.Target == "out/target/product/test_device/system/lib/installedlib.so" { 403 if installedlibRule != nil { 404 t.Errorf("Duplicate install rules for %s", rule.Target) 405 } 406 installedlibRule = &installRules[i] 407 } 408 } 409 if installedlibRule == nil { 410 t.Errorf("No install rule found for installedlib") 411 return 412 } 413 414 if expectLibfooOnSystemLib { 415 android.AssertStringListContains(t, 416 "installedlib doesn't have install dependency on libfoo impl", 417 installedlibRule.OrderOnlyDeps, 418 "out/target/product/test_device/system/lib/libfoo.so") 419 } else { 420 android.AssertStringListDoesNotContain(t, 421 "installedlib has install dependency on libfoo stub", 422 installedlibRule.Deps, 423 "out/target/product/test_device/system/lib/libfoo.so") 424 android.AssertStringListDoesNotContain(t, 425 "installedlib has order-only install dependency on libfoo stub", 426 installedlibRule.OrderOnlyDeps, 427 "out/target/product/test_device/system/lib/libfoo.so") 428 } 429 } 430 431 prebuiltLibfooBp := []byte(` 432 cc_prebuilt_library { 433 name: "libfoo", 434 prefer: true, 435 srcs: ["libfoo.so"], 436 stubs: { 437 versions: ["1"], 438 }, 439 } 440 `) 441 442 installedlibBp := []byte(` 443 cc_library { 444 name: "installedlib", 445 shared_libs: ["libfoo"], 446 } 447 `) 448 449 t.Run("prebuilt stub (without source): no install", func(t *testing.T) { 450 testFunc( 451 t, 452 /*expectLibfooOnSystemLib=*/ false, 453 android.MockFS{ 454 "prebuilts/module_sdk/art/current/Android.bp": prebuiltLibfooBp, 455 "Android.bp": installedlibBp, 456 }, 457 ) 458 }) 459 460 disabledSourceLibfooBp := []byte(` 461 cc_library { 462 name: "libfoo", 463 enabled: false, 464 stubs: { 465 versions: ["1"], 466 }, 467 } 468 `) 469 470 t.Run("prebuilt stub (with disabled source): no install", func(t *testing.T) { 471 testFunc( 472 t, 473 /*expectLibfooOnSystemLib=*/ false, 474 android.MockFS{ 475 "prebuilts/module_sdk/art/current/Android.bp": prebuiltLibfooBp, 476 "impl/Android.bp": disabledSourceLibfooBp, 477 "Android.bp": installedlibBp, 478 }, 479 ) 480 }) 481 482 t.Run("prebuilt impl (with `stubs` property set): install", func(t *testing.T) { 483 testFunc( 484 t, 485 /*expectLibfooOnSystemLib=*/ true, 486 android.MockFS{ 487 "impl/Android.bp": prebuiltLibfooBp, 488 "Android.bp": installedlibBp, 489 }, 490 ) 491 }) 492} 493 494func TestPrebuiltBinaryNoSrcsNoError(t *testing.T) { 495 const bp = ` 496cc_prebuilt_binary { 497 name: "bintest", 498 srcs: [], 499}` 500 ctx := testPrebuilt(t, bp, map[string][]byte{}) 501 mod := ctx.ModuleForTests("bintest", "android_arm64_armv8-a").Module().(*Module) 502 android.AssertBoolEquals(t, `expected no srcs to yield no output file`, false, mod.OutputFile().Valid()) 503} 504 505func TestPrebuiltBinaryMultipleSrcs(t *testing.T) { 506 const bp = ` 507cc_prebuilt_binary { 508 name: "bintest", 509 srcs: ["foo", "bar"], 510}` 511 testCcError(t, `Android.bp:4:6: module "bintest" variant "android_arm64_armv8-a": srcs: multiple prebuilt source files`, bp) 512} 513 514func TestMultiplePrebuilts(t *testing.T) { 515 bp := ` 516 // an rdep 517 cc_library { 518 name: "libfoo", 519 shared_libs: ["libbar"], 520 } 521 522 // multiple variations of dep 523 // source 524 cc_library { 525 name: "libbar", 526 } 527 // prebuilt "v1" 528 cc_prebuilt_library_shared { 529 name: "libbar", 530 srcs: ["libbar.so"], 531 } 532 // prebuilt "v2" 533 cc_prebuilt_library_shared { 534 name: "libbar.v2", 535 stem: "libbar", 536 source_module_name: "libbar", 537 srcs: ["libbar.so"], 538 } 539 540 // selectors 541 apex_contributions { 542 name: "myapex_contributions", 543 contents: ["%v"], 544 } 545 all_apex_contributions {name: "all_apex_contributions"} 546 ` 547 hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { 548 t.Helper() 549 var found bool 550 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 551 if dep == wantDep { 552 found = true 553 } 554 }) 555 return found 556 } 557 558 testCases := []struct { 559 desc string 560 selectedDependencyName string 561 expectedDependencyName string 562 }{ 563 { 564 desc: "Source library is selected using apex_contributions", 565 selectedDependencyName: "libbar", 566 expectedDependencyName: "libbar", 567 }, 568 { 569 desc: "Prebuilt library v1 is selected using apex_contributions", 570 selectedDependencyName: "prebuilt_libbar", 571 expectedDependencyName: "prebuilt_libbar", 572 }, 573 { 574 desc: "Prebuilt library v2 is selected using apex_contributions", 575 selectedDependencyName: "prebuilt_libbar.v2", 576 expectedDependencyName: "prebuilt_libbar.v2", 577 }, 578 } 579 580 for _, tc := range testCases { 581 preparer := android.GroupFixturePreparers( 582 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 583 android.RegisterApexContributionsBuildComponents(ctx) 584 }), 585 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 586 variables.BuildFlags = map[string]string{ 587 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", 588 } 589 }), 590 ) 591 ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{ 592 "libbar.so": nil, 593 "crtx.o": nil, 594 }, preparer) 595 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 596 expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() 597 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency)) 598 // check that LOCAL_SHARED_LIBRARIES contains libbar and not libbar.v<N> 599 entries := android.AndroidMkEntriesForTest(t, ctx, libfoo)[0] 600 android.AssertStringListContains(t, "Version should not be present in LOCAL_SHARED_LIBRARIES", entries.EntryMap["LOCAL_SHARED_LIBRARIES"], "libbar") 601 602 // check installation rules 603 // the selected soong module should be exported to make 604 libbar := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() 605 android.AssertBoolEquals(t, fmt.Sprintf("dependency %s should be exported to make\n", expectedDependency), true, !libbar.IsHideFromMake()) 606 607 // check LOCAL_MODULE of the selected module name 608 // the prebuilt should have the same LOCAL_MODULE when exported to make 609 entries = android.AndroidMkEntriesForTest(t, ctx, libbar)[0] 610 android.AssertStringEquals(t, "unexpected LOCAL_MODULE", "libbar", entries.EntryMap["LOCAL_MODULE"][0]) 611 } 612} 613 614// Setting prefer on multiple prebuilts is an error, unless one of them is also listed in apex_contributions 615func TestMultiplePrebuiltsPreferredUsingLegacyFlags(t *testing.T) { 616 bp := ` 617 // an rdep 618 cc_library { 619 name: "libfoo", 620 shared_libs: ["libbar"], 621 } 622 623 // multiple variations of dep 624 // source 625 cc_library { 626 name: "libbar", 627 } 628 // prebuilt "v1" 629 cc_prebuilt_library_shared { 630 name: "libbar", 631 srcs: ["libbar.so"], 632 prefer: true, 633 } 634 // prebuilt "v2" 635 cc_prebuilt_library_shared { 636 name: "libbar.v2", 637 stem: "libbar", 638 source_module_name: "libbar", 639 srcs: ["libbar.so"], 640 prefer: true, 641 } 642 643 // selectors 644 apex_contributions { 645 name: "myapex_contributions", 646 contents: [%v], 647 } 648 all_apex_contributions {name: "all_apex_contributions"} 649 ` 650 hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { 651 t.Helper() 652 var found bool 653 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 654 if dep == wantDep { 655 found = true 656 } 657 }) 658 return found 659 } 660 661 testCases := []struct { 662 desc string 663 selectedDependencyName string 664 expectedDependencyName string 665 expectedErr string 666 }{ 667 { 668 desc: "Multiple prebuilts have prefer: true", 669 expectedErr: "Multiple prebuilt modules prebuilt_libbar and prebuilt_libbar.v2 have been marked as preferred for this source module", 670 }, 671 { 672 desc: "Multiple prebuilts have prefer: true. The prebuilt listed in apex_contributions wins.", 673 selectedDependencyName: `"prebuilt_libbar"`, 674 expectedDependencyName: "prebuilt_libbar", 675 }, 676 } 677 678 for _, tc := range testCases { 679 preparer := android.GroupFixturePreparers( 680 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 681 android.RegisterApexContributionsBuildComponents(ctx) 682 }), 683 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 684 variables.BuildFlags = map[string]string{ 685 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", 686 } 687 }), 688 ) 689 if tc.expectedErr != "" { 690 preparer = preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(tc.expectedErr)) 691 } 692 693 ctx := testPrebuilt(t, fmt.Sprintf(bp, tc.selectedDependencyName), map[string][]byte{ 694 "libbar.so": nil, 695 "crtx.o": nil, 696 }, preparer) 697 if tc.expectedErr != "" { 698 return // the fixture will assert that the excepted err has been raised 699 } 700 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 701 expectedDependency := ctx.ModuleForTests(tc.expectedDependencyName, "android_arm64_armv8-a_shared").Module() 702 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from %s to %s\n", libfoo.Name(), tc.expectedDependencyName), true, hasDep(ctx, libfoo, expectedDependency)) 703 } 704} 705 706// If module sdk cannot provide a cc module variant (e.g. static), then the module variant from source should be used 707func TestMissingVariantInModuleSdk(t *testing.T) { 708 bp := ` 709 // an rdep 710 cc_library { 711 name: "libfoo", 712 static_libs: ["libbar"], 713 } 714 715 // source 716 cc_library { 717 name: "libbar", 718 } 719 // prebuilt 720 // libbar only exists as a shared library 721 cc_prebuilt_library_shared { 722 name: "libbar", 723 srcs: ["libbar.so"], 724 } 725 // selectors 726 apex_contributions { 727 name: "myapex_contributions", 728 contents: ["prebuilt_libbar"], 729 } 730 all_apex_contributions {name: "all_apex_contributions"} 731 ` 732 hasDep := func(ctx *android.TestContext, m android.Module, wantDep android.Module) bool { 733 t.Helper() 734 var found bool 735 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 736 if dep == wantDep { 737 found = true 738 } 739 }) 740 return found 741 } 742 743 preparer := android.GroupFixturePreparers( 744 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 745 android.RegisterApexContributionsBuildComponents(ctx) 746 }), 747 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 748 variables.BuildFlags = map[string]string{ 749 "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "myapex_contributions", 750 } 751 }), 752 ) 753 ctx := testPrebuilt(t, bp, map[string][]byte{ 754 "libbar.so": nil, 755 "crtx.o": nil, 756 }, preparer) 757 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 758 sourceLibBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_static").Module() 759 // Even though the prebuilt is listed in apex_contributions, the prebuilt does not have a static variant. 760 // Therefore source of libbar should be used. 761 android.AssertBoolEquals(t, fmt.Sprintf("expected dependency from libfoo to source libbar"), true, hasDep(ctx, libfoo, sourceLibBar)) 762} 763