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