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 "path/filepath" 21 "reflect" 22 "regexp" 23 "strings" 24 "testing" 25 26 "android/soong/android" 27) 28 29func TestMain(m *testing.M) { 30 os.Exit(m.Run()) 31} 32 33var prepareForCcTest = android.GroupFixturePreparers( 34 PrepareForTestWithCcIncludeVndk, 35 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 36 variables.DeviceVndkVersion = StringPtr("current") 37 variables.ProductVndkVersion = StringPtr("current") 38 variables.Platform_vndk_version = StringPtr("29") 39 }), 40) 41 42// testCcWithConfig runs tests using the prepareForCcTest 43// 44// See testCc for an explanation as to how to stop using this deprecated method. 45// 46// deprecated 47func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext { 48 t.Helper() 49 result := prepareForCcTest.RunTestWithConfig(t, config) 50 return result.TestContext 51} 52 53// testCc runs tests using the prepareForCcTest 54// 55// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much 56// easier to customize the test behavior. 57// 58// If it is necessary to customize the behavior of an existing test that uses this then please first 59// convert the test to using prepareForCcTest first and then in a following change add the 60// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify 61// that it did not change the test behavior unexpectedly. 62// 63// deprecated 64func testCc(t *testing.T, bp string) *android.TestContext { 65 t.Helper() 66 result := prepareForCcTest.RunTestWithBp(t, bp) 67 return result.TestContext 68} 69 70// testCcNoVndk runs tests using the prepareForCcTest 71// 72// See testCc for an explanation as to how to stop using this deprecated method. 73// 74// deprecated 75func testCcNoVndk(t *testing.T, bp string) *android.TestContext { 76 t.Helper() 77 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 78 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 79 80 return testCcWithConfig(t, config) 81} 82 83// testCcNoProductVndk runs tests using the prepareForCcTest 84// 85// See testCc for an explanation as to how to stop using this deprecated method. 86// 87// deprecated 88func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext { 89 t.Helper() 90 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 91 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 92 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 93 94 return testCcWithConfig(t, config) 95} 96 97// testCcErrorWithConfig runs tests using the prepareForCcTest 98// 99// See testCc for an explanation as to how to stop using this deprecated method. 100// 101// deprecated 102func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) { 103 t.Helper() 104 105 prepareForCcTest. 106 ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)). 107 RunTestWithConfig(t, config) 108} 109 110// testCcError runs tests using the prepareForCcTest 111// 112// See testCc for an explanation as to how to stop using this deprecated method. 113// 114// deprecated 115func testCcError(t *testing.T, pattern string, bp string) { 116 t.Helper() 117 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 118 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 119 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 120 testCcErrorWithConfig(t, pattern, config) 121 return 122} 123 124// testCcErrorProductVndk runs tests using the prepareForCcTest 125// 126// See testCc for an explanation as to how to stop using this deprecated method. 127// 128// deprecated 129func testCcErrorProductVndk(t *testing.T, pattern string, bp string) { 130 t.Helper() 131 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 132 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 133 config.TestProductVariables.ProductVndkVersion = StringPtr("current") 134 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 135 testCcErrorWithConfig(t, pattern, config) 136 return 137} 138 139const ( 140 coreVariant = "android_arm64_armv8-a_shared" 141 vendorVariant = "android_vendor.29_arm64_armv8-a_shared" 142 productVariant = "android_product.29_arm64_armv8-a_shared" 143 recoveryVariant = "android_recovery_arm64_armv8-a_shared" 144) 145 146// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by 147// running it in a fixture that requires all source files to exist. 148func TestPrepareForTestWithCcDefaultModules(t *testing.T) { 149 android.GroupFixturePreparers( 150 PrepareForTestWithCcDefaultModules, 151 android.PrepareForTestDisallowNonExistentPaths, 152 ).RunTest(t) 153} 154 155func TestVendorSrc(t *testing.T) { 156 ctx := testCc(t, ` 157 cc_library { 158 name: "libTest", 159 srcs: ["foo.c"], 160 no_libcrt: true, 161 nocrt: true, 162 system_shared_libs: [], 163 vendor_available: true, 164 target: { 165 vendor: { 166 srcs: ["bar.c"], 167 }, 168 }, 169 } 170 `) 171 172 ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld") 173 var objs []string 174 for _, o := range ld.Inputs { 175 objs = append(objs, o.Base()) 176 } 177 if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" { 178 t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs) 179 } 180} 181 182func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) { 183 mod := ctx.ModuleForTests(name, variant).Module().(*Module) 184 partitionDefined := false 185 checkPartition := func(specific bool, partition string) { 186 if specific { 187 if expected != partition && !partitionDefined { 188 // The variant is installed to the 'partition' 189 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition) 190 } 191 partitionDefined = true 192 } else { 193 // The variant is not installed to the 'partition' 194 if expected == partition { 195 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition) 196 } 197 } 198 } 199 socSpecific := func(m *Module) bool { 200 return m.SocSpecific() || m.socSpecificModuleContext() 201 } 202 deviceSpecific := func(m *Module) bool { 203 return m.DeviceSpecific() || m.deviceSpecificModuleContext() 204 } 205 productSpecific := func(m *Module) bool { 206 return m.ProductSpecific() || m.productSpecificModuleContext() 207 } 208 systemExtSpecific := func(m *Module) bool { 209 return m.SystemExtSpecific() 210 } 211 checkPartition(socSpecific(mod), "vendor") 212 checkPartition(deviceSpecific(mod), "odm") 213 checkPartition(productSpecific(mod), "product") 214 checkPartition(systemExtSpecific(mod), "system_ext") 215 if !partitionDefined && expected != "system" { 216 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+ 217 " but installed to system partition", variant, name, expected) 218 } 219} 220 221func TestInstallPartition(t *testing.T) { 222 t.Helper() 223 ctx := prepareForCcTest.RunTestWithBp(t, ` 224 cc_library { 225 name: "libsystem", 226 } 227 cc_library { 228 name: "libsystem_ext", 229 system_ext_specific: true, 230 } 231 cc_library { 232 name: "libproduct", 233 product_specific: true, 234 } 235 cc_library { 236 name: "libvendor", 237 vendor: true, 238 } 239 cc_library { 240 name: "libodm", 241 device_specific: true, 242 } 243 cc_library { 244 name: "liball_available", 245 vendor_available: true, 246 product_available: true, 247 } 248 cc_library { 249 name: "libsystem_ext_all_available", 250 system_ext_specific: true, 251 vendor_available: true, 252 product_available: true, 253 } 254 cc_library { 255 name: "liball_available_odm", 256 odm_available: true, 257 product_available: true, 258 } 259 cc_library { 260 name: "libproduct_vendoravailable", 261 product_specific: true, 262 vendor_available: true, 263 } 264 cc_library { 265 name: "libproduct_odmavailable", 266 product_specific: true, 267 odm_available: true, 268 } 269 `).TestContext 270 271 checkInstallPartition(t, ctx, "libsystem", coreVariant, "system") 272 checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext") 273 checkInstallPartition(t, ctx, "libproduct", productVariant, "product") 274 checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor") 275 checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm") 276 277 checkInstallPartition(t, ctx, "liball_available", coreVariant, "system") 278 checkInstallPartition(t, ctx, "liball_available", productVariant, "product") 279 checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor") 280 281 checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext") 282 checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product") 283 checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor") 284 285 checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system") 286 checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product") 287 checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm") 288 289 checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product") 290 checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor") 291 292 checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product") 293 checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm") 294} 295 296func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string, 297 isVndkSp bool, extends string, variant string) { 298 299 t.Helper() 300 301 mod := ctx.ModuleForTests(name, variant).Module().(*Module) 302 303 // Check library properties. 304 lib, ok := mod.compiler.(*libraryDecorator) 305 if !ok { 306 t.Errorf("%q must have libraryDecorator", name) 307 } else if lib.baseInstaller.subDir != subDir { 308 t.Errorf("%q must use %q as subdir but it is using %q", name, subDir, 309 lib.baseInstaller.subDir) 310 } 311 312 // Check VNDK properties. 313 if mod.vndkdep == nil { 314 t.Fatalf("%q must have `vndkdep`", name) 315 } 316 if !mod.IsVndk() { 317 t.Errorf("%q IsVndk() must equal to true", name) 318 } 319 if mod.IsVndkSp() != isVndkSp { 320 t.Errorf("%q IsVndkSp() must equal to %t", name, isVndkSp) 321 } 322 323 // Check VNDK extension properties. 324 isVndkExt := extends != "" 325 if mod.IsVndkExt() != isVndkExt { 326 t.Errorf("%q IsVndkExt() must equal to %t", name, isVndkExt) 327 } 328 329 if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends { 330 t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends) 331 } 332} 333 334func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) { 335 t.Helper() 336 content := android.ContentFromFileRuleForTests(t, params) 337 actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' }) 338 assertArrayString(t, actual, expected) 339} 340 341func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) { 342 t.Helper() 343 vndkSnapshot := ctx.SingletonForTests("vndk-snapshot") 344 checkWriteFileOutput(t, vndkSnapshot.Output(output), expected) 345} 346 347func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) { 348 t.Helper() 349 got := ctx.ModuleForTests(module, "android_common").Module().(*vndkLibrariesTxt).fileNames 350 assertArrayString(t, got, expected) 351} 352 353func TestVndk(t *testing.T) { 354 bp := ` 355 cc_library { 356 name: "libvndk", 357 vendor_available: true, 358 vndk: { 359 enabled: true, 360 }, 361 nocrt: true, 362 } 363 364 cc_library { 365 name: "libvndk_private", 366 vendor_available: true, 367 vndk: { 368 enabled: true, 369 private: true, 370 }, 371 nocrt: true, 372 stem: "libvndk-private", 373 } 374 375 cc_library { 376 name: "libvndk_product", 377 vendor_available: true, 378 product_available: true, 379 vndk: { 380 enabled: true, 381 }, 382 nocrt: true, 383 target: { 384 vendor: { 385 cflags: ["-DTEST"], 386 }, 387 product: { 388 cflags: ["-DTEST"], 389 }, 390 }, 391 } 392 393 cc_library { 394 name: "libvndk_sp", 395 vendor_available: true, 396 vndk: { 397 enabled: true, 398 support_system_process: true, 399 }, 400 nocrt: true, 401 suffix: "-x", 402 } 403 404 cc_library { 405 name: "libvndk_sp_private", 406 vendor_available: true, 407 vndk: { 408 enabled: true, 409 support_system_process: true, 410 private: true, 411 }, 412 nocrt: true, 413 target: { 414 vendor: { 415 suffix: "-x", 416 }, 417 }, 418 } 419 420 cc_library { 421 name: "libvndk_sp_product_private", 422 vendor_available: true, 423 product_available: true, 424 vndk: { 425 enabled: true, 426 support_system_process: true, 427 private: true, 428 }, 429 nocrt: true, 430 target: { 431 vendor: { 432 suffix: "-x", 433 }, 434 product: { 435 suffix: "-x", 436 }, 437 }, 438 } 439 440 cc_library { 441 name: "libllndk", 442 llndk: { 443 symbol_file: "libllndk.map.txt", 444 export_llndk_headers: ["libllndk_headers"], 445 } 446 } 447 448 cc_library { 449 name: "libclang_rt.hwasan-llndk", 450 llndk: { 451 symbol_file: "libclang_rt.hwasan.map.txt", 452 } 453 } 454 455 cc_library_headers { 456 name: "libllndk_headers", 457 llndk: { 458 llndk_headers: true, 459 }, 460 export_include_dirs: ["include"], 461 } 462 463 llndk_libraries_txt { 464 name: "llndk.libraries.txt", 465 } 466 vndkcore_libraries_txt { 467 name: "vndkcore.libraries.txt", 468 } 469 vndksp_libraries_txt { 470 name: "vndksp.libraries.txt", 471 } 472 vndkprivate_libraries_txt { 473 name: "vndkprivate.libraries.txt", 474 } 475 vndkproduct_libraries_txt { 476 name: "vndkproduct.libraries.txt", 477 } 478 vndkcorevariant_libraries_txt { 479 name: "vndkcorevariant.libraries.txt", 480 insert_vndk_version: false, 481 } 482 ` 483 484 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 485 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 486 config.TestProductVariables.ProductVndkVersion = StringPtr("current") 487 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 488 489 ctx := testCcWithConfig(t, config) 490 491 // subdir == "" because VNDK libs are not supposed to be installed separately. 492 // They are installed as part of VNDK APEX instead. 493 checkVndkModule(t, ctx, "libvndk", "", false, "", vendorVariant) 494 checkVndkModule(t, ctx, "libvndk_private", "", false, "", vendorVariant) 495 checkVndkModule(t, ctx, "libvndk_product", "", false, "", vendorVariant) 496 checkVndkModule(t, ctx, "libvndk_sp", "", true, "", vendorVariant) 497 checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", vendorVariant) 498 checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", vendorVariant) 499 500 checkVndkModule(t, ctx, "libvndk_product", "", false, "", productVariant) 501 checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", productVariant) 502 503 // Check VNDK snapshot output. 504 snapshotDir := "vndk-snapshot" 505 snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64") 506 507 vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s", 508 "arm64", "armv8-a")) 509 vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s", 510 "arm", "armv7-a-neon")) 511 512 vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core") 513 vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp") 514 llndkLibPath := filepath.Join(vndkLibPath, "shared", "llndk-stub") 515 516 vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core") 517 vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp") 518 llndkLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "llndk-stub") 519 520 variant := "android_vendor.29_arm64_armv8-a_shared" 521 variant2nd := "android_vendor.29_arm_armv7-a-neon_shared" 522 523 snapshotSingleton := ctx.SingletonForTests("vndk-snapshot") 524 525 CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant) 526 CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd) 527 CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant) 528 CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd) 529 CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant) 530 CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd) 531 CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLibPath, variant) 532 CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLib2ndPath, variant2nd) 533 534 snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs") 535 CheckSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "android_common") 536 CheckSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "android_common") 537 CheckSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "android_common") 538 CheckSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "android_common") 539 CheckSnapshot(t, ctx, snapshotSingleton, "vndkproduct.libraries.txt", "vndkproduct.libraries.txt", snapshotConfigsPath, "android_common") 540 541 checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ 542 "LLNDK: libc.so", 543 "LLNDK: libdl.so", 544 "LLNDK: libft2.so", 545 "LLNDK: libllndk.so", 546 "LLNDK: libm.so", 547 "VNDK-SP: libc++.so", 548 "VNDK-SP: libvndk_sp-x.so", 549 "VNDK-SP: libvndk_sp_private-x.so", 550 "VNDK-SP: libvndk_sp_product_private-x.so", 551 "VNDK-core: libvndk-private.so", 552 "VNDK-core: libvndk.so", 553 "VNDK-core: libvndk_product.so", 554 "VNDK-private: libft2.so", 555 "VNDK-private: libvndk-private.so", 556 "VNDK-private: libvndk_sp_private-x.so", 557 "VNDK-private: libvndk_sp_product_private-x.so", 558 "VNDK-product: libc++.so", 559 "VNDK-product: libvndk_product.so", 560 "VNDK-product: libvndk_sp_product_private-x.so", 561 }) 562 checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libclang_rt.hwasan-llndk.so", "libdl.so", "libft2.so", "libllndk.so", "libm.so"}) 563 checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so", "libvndk_product.so"}) 564 checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"}) 565 checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"}) 566 checkVndkLibrariesOutput(t, ctx, "vndkproduct.libraries.txt", []string{"libc++.so", "libvndk_product.so", "libvndk_sp_product_private-x.so"}) 567 checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil) 568} 569 570func TestVndkWithHostSupported(t *testing.T) { 571 ctx := testCc(t, ` 572 cc_library { 573 name: "libvndk_host_supported", 574 vendor_available: true, 575 product_available: true, 576 vndk: { 577 enabled: true, 578 }, 579 host_supported: true, 580 } 581 582 cc_library { 583 name: "libvndk_host_supported_but_disabled_on_device", 584 vendor_available: true, 585 product_available: true, 586 vndk: { 587 enabled: true, 588 }, 589 host_supported: true, 590 enabled: false, 591 target: { 592 host: { 593 enabled: true, 594 } 595 } 596 } 597 598 vndkcore_libraries_txt { 599 name: "vndkcore.libraries.txt", 600 } 601 `) 602 603 checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk_host_supported.so"}) 604} 605 606func TestVndkLibrariesTxtAndroidMk(t *testing.T) { 607 bp := ` 608 llndk_libraries_txt { 609 name: "llndk.libraries.txt", 610 insert_vndk_version: true, 611 }` 612 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 613 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 614 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 615 ctx := testCcWithConfig(t, config) 616 617 module := ctx.ModuleForTests("llndk.libraries.txt", "android_common") 618 entries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0] 619 assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.29.txt"}) 620} 621 622func TestVndkUsingCoreVariant(t *testing.T) { 623 bp := ` 624 cc_library { 625 name: "libvndk", 626 vendor_available: true, 627 product_available: true, 628 vndk: { 629 enabled: true, 630 }, 631 nocrt: true, 632 } 633 634 cc_library { 635 name: "libvndk_sp", 636 vendor_available: true, 637 product_available: true, 638 vndk: { 639 enabled: true, 640 support_system_process: true, 641 }, 642 nocrt: true, 643 } 644 645 cc_library { 646 name: "libvndk2", 647 vendor_available: true, 648 product_available: true, 649 vndk: { 650 enabled: true, 651 private: true, 652 }, 653 nocrt: true, 654 } 655 656 vndkcorevariant_libraries_txt { 657 name: "vndkcorevariant.libraries.txt", 658 insert_vndk_version: false, 659 } 660 ` 661 662 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 663 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 664 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 665 config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true) 666 667 setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"}) 668 669 ctx := testCcWithConfig(t, config) 670 671 checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"}) 672} 673 674func TestDataLibs(t *testing.T) { 675 bp := ` 676 cc_test_library { 677 name: "test_lib", 678 srcs: ["test_lib.cpp"], 679 gtest: false, 680 } 681 682 cc_test { 683 name: "main_test", 684 data_libs: ["test_lib"], 685 gtest: false, 686 } 687 ` 688 689 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 690 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 691 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 692 config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true) 693 694 ctx := testCcWithConfig(t, config) 695 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module() 696 testBinary := module.(*Module).linker.(*testBinary) 697 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") 698 if err != nil { 699 t.Errorf("Expected cc_test to produce output files, error: %s", err) 700 return 701 } 702 if len(outputFiles) != 1 { 703 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles) 704 return 705 } 706 if len(testBinary.dataPaths()) != 1 { 707 t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths()) 708 return 709 } 710 711 outputPath := outputFiles[0].String() 712 testBinaryPath := testBinary.dataPaths()[0].SrcPath.String() 713 714 if !strings.HasSuffix(outputPath, "/main_test") { 715 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) 716 return 717 } 718 if !strings.HasSuffix(testBinaryPath, "/test_lib.so") { 719 t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath) 720 return 721 } 722} 723 724func TestDataLibsRelativeInstallPath(t *testing.T) { 725 bp := ` 726 cc_test_library { 727 name: "test_lib", 728 srcs: ["test_lib.cpp"], 729 relative_install_path: "foo/bar/baz", 730 gtest: false, 731 } 732 733 cc_binary { 734 name: "test_bin", 735 relative_install_path: "foo/bar/baz", 736 compile_multilib: "both", 737 } 738 739 cc_test { 740 name: "main_test", 741 data_libs: ["test_lib"], 742 data_bins: ["test_bin"], 743 gtest: false, 744 } 745 ` 746 747 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 748 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 749 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 750 config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true) 751 752 ctx := testCcWithConfig(t, config) 753 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module() 754 testBinary := module.(*Module).linker.(*testBinary) 755 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") 756 if err != nil { 757 t.Fatalf("Expected cc_test to produce output files, error: %s", err) 758 } 759 if len(outputFiles) != 1 { 760 t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles) 761 } 762 if len(testBinary.dataPaths()) != 2 { 763 t.Fatalf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths()) 764 } 765 766 outputPath := outputFiles[0].String() 767 768 if !strings.HasSuffix(outputPath, "/main_test") { 769 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) 770 } 771 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] 772 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") { 773 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+ 774 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0]) 775 } 776 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") { 777 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+ 778 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1]) 779 } 780} 781 782func TestTestBinaryTestSuites(t *testing.T) { 783 bp := ` 784 cc_test { 785 name: "main_test", 786 srcs: ["main_test.cpp"], 787 test_suites: [ 788 "suite_1", 789 "suite_2", 790 ], 791 gtest: false, 792 } 793 ` 794 795 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext 796 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module() 797 798 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] 799 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"] 800 if len(compatEntries) != 2 { 801 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries)) 802 } 803 if compatEntries[0] != "suite_1" { 804 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+ 805 " but was '%s'", compatEntries[0]) 806 } 807 if compatEntries[1] != "suite_2" { 808 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+ 809 " but was '%s'", compatEntries[1]) 810 } 811} 812 813func TestTestLibraryTestSuites(t *testing.T) { 814 bp := ` 815 cc_test_library { 816 name: "main_test_lib", 817 srcs: ["main_test_lib.cpp"], 818 test_suites: [ 819 "suite_1", 820 "suite_2", 821 ], 822 gtest: false, 823 } 824 ` 825 826 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext 827 module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module() 828 829 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] 830 compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"] 831 if len(compatEntries) != 2 { 832 t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries)) 833 } 834 if compatEntries[0] != "suite_1" { 835 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+ 836 " but was '%s'", compatEntries[0]) 837 } 838 if compatEntries[1] != "suite_2" { 839 t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+ 840 " but was '%s'", compatEntries[1]) 841 } 842} 843 844func TestVndkWhenVndkVersionIsNotSet(t *testing.T) { 845 ctx := testCcNoVndk(t, ` 846 cc_library { 847 name: "libvndk", 848 vendor_available: true, 849 product_available: true, 850 vndk: { 851 enabled: true, 852 }, 853 nocrt: true, 854 } 855 cc_library { 856 name: "libvndk-private", 857 vendor_available: true, 858 product_available: true, 859 vndk: { 860 enabled: true, 861 private: true, 862 }, 863 nocrt: true, 864 } 865 866 cc_library { 867 name: "libllndk", 868 llndk: { 869 symbol_file: "libllndk.map.txt", 870 export_llndk_headers: ["libllndk_headers"], 871 } 872 } 873 874 cc_library_headers { 875 name: "libllndk_headers", 876 llndk: { 877 symbol_file: "libllndk.map.txt", 878 }, 879 export_include_dirs: ["include"], 880 } 881 `) 882 883 checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ 884 "LLNDK: libc.so", 885 "LLNDK: libdl.so", 886 "LLNDK: libft2.so", 887 "LLNDK: libllndk.so", 888 "LLNDK: libm.so", 889 "VNDK-SP: libc++.so", 890 "VNDK-core: libvndk-private.so", 891 "VNDK-core: libvndk.so", 892 "VNDK-private: libft2.so", 893 "VNDK-private: libvndk-private.so", 894 "VNDK-product: libc++.so", 895 "VNDK-product: libvndk-private.so", 896 "VNDK-product: libvndk.so", 897 }) 898} 899 900func TestVndkModuleError(t *testing.T) { 901 // Check the error message for vendor_available and product_available properties. 902 testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", ` 903 cc_library { 904 name: "libvndk", 905 vndk: { 906 enabled: true, 907 }, 908 nocrt: true, 909 } 910 `) 911 912 testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", ` 913 cc_library { 914 name: "libvndk", 915 product_available: true, 916 vndk: { 917 enabled: true, 918 }, 919 nocrt: true, 920 } 921 `) 922 923 testCcErrorProductVndk(t, "product properties must have the same values with the vendor properties for VNDK modules", ` 924 cc_library { 925 name: "libvndkprop", 926 vendor_available: true, 927 product_available: true, 928 vndk: { 929 enabled: true, 930 }, 931 nocrt: true, 932 target: { 933 vendor: { 934 cflags: ["-DTEST",], 935 }, 936 }, 937 } 938 `) 939} 940 941func TestVndkDepError(t *testing.T) { 942 // Check whether an error is emitted when a VNDK lib depends on a system lib. 943 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 944 cc_library { 945 name: "libvndk", 946 vendor_available: true, 947 product_available: true, 948 vndk: { 949 enabled: true, 950 }, 951 shared_libs: ["libfwk"], // Cause error 952 nocrt: true, 953 } 954 955 cc_library { 956 name: "libfwk", 957 nocrt: true, 958 } 959 `) 960 961 // Check whether an error is emitted when a VNDK lib depends on a vendor lib. 962 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 963 cc_library { 964 name: "libvndk", 965 vendor_available: true, 966 product_available: true, 967 vndk: { 968 enabled: true, 969 }, 970 shared_libs: ["libvendor"], // Cause error 971 nocrt: true, 972 } 973 974 cc_library { 975 name: "libvendor", 976 vendor: true, 977 nocrt: true, 978 } 979 `) 980 981 // Check whether an error is emitted when a VNDK-SP lib depends on a system lib. 982 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 983 cc_library { 984 name: "libvndk_sp", 985 vendor_available: true, 986 product_available: true, 987 vndk: { 988 enabled: true, 989 support_system_process: true, 990 }, 991 shared_libs: ["libfwk"], // Cause error 992 nocrt: true, 993 } 994 995 cc_library { 996 name: "libfwk", 997 nocrt: true, 998 } 999 `) 1000 1001 // Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib. 1002 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 1003 cc_library { 1004 name: "libvndk_sp", 1005 vendor_available: true, 1006 product_available: true, 1007 vndk: { 1008 enabled: true, 1009 support_system_process: true, 1010 }, 1011 shared_libs: ["libvendor"], // Cause error 1012 nocrt: true, 1013 } 1014 1015 cc_library { 1016 name: "libvendor", 1017 vendor: true, 1018 nocrt: true, 1019 } 1020 `) 1021 1022 // Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib. 1023 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1024 cc_library { 1025 name: "libvndk_sp", 1026 vendor_available: true, 1027 product_available: true, 1028 vndk: { 1029 enabled: true, 1030 support_system_process: true, 1031 }, 1032 shared_libs: ["libvndk"], // Cause error 1033 nocrt: true, 1034 } 1035 1036 cc_library { 1037 name: "libvndk", 1038 vendor_available: true, 1039 product_available: true, 1040 vndk: { 1041 enabled: true, 1042 }, 1043 nocrt: true, 1044 } 1045 `) 1046 1047 // Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib. 1048 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1049 cc_library { 1050 name: "libvndk", 1051 vendor_available: true, 1052 product_available: true, 1053 vndk: { 1054 enabled: true, 1055 }, 1056 shared_libs: ["libnonvndk"], 1057 nocrt: true, 1058 } 1059 1060 cc_library { 1061 name: "libnonvndk", 1062 vendor_available: true, 1063 nocrt: true, 1064 } 1065 `) 1066 1067 // Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib. 1068 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1069 cc_library { 1070 name: "libvndkprivate", 1071 vendor_available: true, 1072 product_available: true, 1073 vndk: { 1074 enabled: true, 1075 private: true, 1076 }, 1077 shared_libs: ["libnonvndk"], 1078 nocrt: true, 1079 } 1080 1081 cc_library { 1082 name: "libnonvndk", 1083 vendor_available: true, 1084 nocrt: true, 1085 } 1086 `) 1087 1088 // Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib. 1089 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1090 cc_library { 1091 name: "libvndksp", 1092 vendor_available: true, 1093 product_available: true, 1094 vndk: { 1095 enabled: true, 1096 support_system_process: true, 1097 }, 1098 shared_libs: ["libnonvndk"], 1099 nocrt: true, 1100 } 1101 1102 cc_library { 1103 name: "libnonvndk", 1104 vendor_available: true, 1105 nocrt: true, 1106 } 1107 `) 1108 1109 // Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib. 1110 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1111 cc_library { 1112 name: "libvndkspprivate", 1113 vendor_available: true, 1114 product_available: true, 1115 vndk: { 1116 enabled: true, 1117 support_system_process: true, 1118 private: true, 1119 }, 1120 shared_libs: ["libnonvndk"], 1121 nocrt: true, 1122 } 1123 1124 cc_library { 1125 name: "libnonvndk", 1126 vendor_available: true, 1127 nocrt: true, 1128 } 1129 `) 1130} 1131 1132func TestDoubleLoadbleDep(t *testing.T) { 1133 // okay to link : LLNDK -> double_loadable VNDK 1134 testCc(t, ` 1135 cc_library { 1136 name: "libllndk", 1137 shared_libs: ["libdoubleloadable"], 1138 llndk: { 1139 symbol_file: "libllndk.map.txt", 1140 } 1141 } 1142 1143 cc_library { 1144 name: "libdoubleloadable", 1145 vendor_available: true, 1146 product_available: true, 1147 vndk: { 1148 enabled: true, 1149 }, 1150 double_loadable: true, 1151 } 1152 `) 1153 // okay to link : LLNDK -> VNDK-SP 1154 testCc(t, ` 1155 cc_library { 1156 name: "libllndk", 1157 shared_libs: ["libvndksp"], 1158 llndk: { 1159 symbol_file: "libllndk.map.txt", 1160 } 1161 } 1162 1163 cc_library { 1164 name: "libvndksp", 1165 vendor_available: true, 1166 product_available: true, 1167 vndk: { 1168 enabled: true, 1169 support_system_process: true, 1170 }, 1171 } 1172 `) 1173 // okay to link : double_loadable -> double_loadable 1174 testCc(t, ` 1175 cc_library { 1176 name: "libdoubleloadable1", 1177 shared_libs: ["libdoubleloadable2"], 1178 vendor_available: true, 1179 double_loadable: true, 1180 } 1181 1182 cc_library { 1183 name: "libdoubleloadable2", 1184 vendor_available: true, 1185 double_loadable: true, 1186 } 1187 `) 1188 // okay to link : double_loadable VNDK -> double_loadable VNDK private 1189 testCc(t, ` 1190 cc_library { 1191 name: "libdoubleloadable", 1192 vendor_available: true, 1193 product_available: true, 1194 vndk: { 1195 enabled: true, 1196 }, 1197 double_loadable: true, 1198 shared_libs: ["libnondoubleloadable"], 1199 } 1200 1201 cc_library { 1202 name: "libnondoubleloadable", 1203 vendor_available: true, 1204 product_available: true, 1205 vndk: { 1206 enabled: true, 1207 private: true, 1208 }, 1209 double_loadable: true, 1210 } 1211 `) 1212 // okay to link : LLNDK -> core-only -> vendor_available & double_loadable 1213 testCc(t, ` 1214 cc_library { 1215 name: "libllndk", 1216 shared_libs: ["libcoreonly"], 1217 llndk: { 1218 symbol_file: "libllndk.map.txt", 1219 } 1220 } 1221 1222 cc_library { 1223 name: "libcoreonly", 1224 shared_libs: ["libvendoravailable"], 1225 } 1226 1227 // indirect dependency of LLNDK 1228 cc_library { 1229 name: "libvendoravailable", 1230 vendor_available: true, 1231 double_loadable: true, 1232 } 1233 `) 1234} 1235 1236func TestDoubleLoadableDepError(t *testing.T) { 1237 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib. 1238 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` 1239 cc_library { 1240 name: "libllndk", 1241 shared_libs: ["libnondoubleloadable"], 1242 llndk: { 1243 symbol_file: "libllndk.map.txt", 1244 } 1245 } 1246 1247 cc_library { 1248 name: "libnondoubleloadable", 1249 vendor_available: true, 1250 product_available: true, 1251 vndk: { 1252 enabled: true, 1253 }, 1254 } 1255 `) 1256 1257 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib. 1258 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` 1259 cc_library { 1260 name: "libllndk", 1261 no_libcrt: true, 1262 shared_libs: ["libnondoubleloadable"], 1263 llndk: { 1264 symbol_file: "libllndk.map.txt", 1265 } 1266 } 1267 1268 cc_library { 1269 name: "libnondoubleloadable", 1270 vendor_available: true, 1271 } 1272 `) 1273 1274 // Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly. 1275 testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", ` 1276 cc_library { 1277 name: "libllndk", 1278 shared_libs: ["libcoreonly"], 1279 llndk: { 1280 symbol_file: "libllndk.map.txt", 1281 } 1282 } 1283 1284 cc_library { 1285 name: "libcoreonly", 1286 shared_libs: ["libvendoravailable"], 1287 } 1288 1289 // indirect dependency of LLNDK 1290 cc_library { 1291 name: "libvendoravailable", 1292 vendor_available: true, 1293 } 1294 `) 1295 1296 // The error is not from 'client' but from 'libllndk' 1297 testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", ` 1298 cc_library { 1299 name: "client", 1300 vendor_available: true, 1301 double_loadable: true, 1302 shared_libs: ["libllndk"], 1303 } 1304 cc_library { 1305 name: "libllndk", 1306 shared_libs: ["libnondoubleloadable"], 1307 llndk: { 1308 symbol_file: "libllndk.map.txt", 1309 } 1310 } 1311 cc_library { 1312 name: "libnondoubleloadable", 1313 vendor_available: true, 1314 } 1315 `) 1316} 1317 1318func TestCheckVndkMembershipBeforeDoubleLoadable(t *testing.T) { 1319 testCcError(t, "module \"libvndksp\" variant .*: .*: VNDK-SP must only depend on VNDK-SP", ` 1320 cc_library { 1321 name: "libvndksp", 1322 shared_libs: ["libanothervndksp"], 1323 vendor_available: true, 1324 product_available: true, 1325 vndk: { 1326 enabled: true, 1327 support_system_process: true, 1328 } 1329 } 1330 1331 cc_library { 1332 name: "libllndk", 1333 shared_libs: ["libanothervndksp"], 1334 } 1335 1336 cc_library { 1337 name: "libanothervndksp", 1338 vendor_available: true, 1339 } 1340 `) 1341} 1342 1343func TestVndkExt(t *testing.T) { 1344 // This test checks the VNDK-Ext properties. 1345 bp := ` 1346 cc_library { 1347 name: "libvndk", 1348 vendor_available: true, 1349 product_available: true, 1350 vndk: { 1351 enabled: true, 1352 }, 1353 nocrt: true, 1354 } 1355 cc_library { 1356 name: "libvndk2", 1357 vendor_available: true, 1358 product_available: true, 1359 vndk: { 1360 enabled: true, 1361 }, 1362 target: { 1363 vendor: { 1364 suffix: "-suffix", 1365 }, 1366 product: { 1367 suffix: "-suffix", 1368 }, 1369 }, 1370 nocrt: true, 1371 } 1372 1373 cc_library { 1374 name: "libvndk_ext", 1375 vendor: true, 1376 vndk: { 1377 enabled: true, 1378 extends: "libvndk", 1379 }, 1380 nocrt: true, 1381 } 1382 1383 cc_library { 1384 name: "libvndk2_ext", 1385 vendor: true, 1386 vndk: { 1387 enabled: true, 1388 extends: "libvndk2", 1389 }, 1390 nocrt: true, 1391 } 1392 1393 cc_library { 1394 name: "libvndk_ext_product", 1395 product_specific: true, 1396 vndk: { 1397 enabled: true, 1398 extends: "libvndk", 1399 }, 1400 nocrt: true, 1401 } 1402 1403 cc_library { 1404 name: "libvndk2_ext_product", 1405 product_specific: true, 1406 vndk: { 1407 enabled: true, 1408 extends: "libvndk2", 1409 }, 1410 nocrt: true, 1411 } 1412 ` 1413 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 1414 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 1415 config.TestProductVariables.ProductVndkVersion = StringPtr("current") 1416 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1417 1418 ctx := testCcWithConfig(t, config) 1419 1420 checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk", vendorVariant) 1421 checkVndkModule(t, ctx, "libvndk_ext_product", "vndk", false, "libvndk", productVariant) 1422 1423 mod_vendor := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module) 1424 assertString(t, mod_vendor.outputFile.Path().Base(), "libvndk2-suffix.so") 1425 1426 mod_product := ctx.ModuleForTests("libvndk2_ext_product", productVariant).Module().(*Module) 1427 assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so") 1428} 1429 1430func TestVndkExtWithoutBoardVndkVersion(t *testing.T) { 1431 // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set. 1432 ctx := testCcNoVndk(t, ` 1433 cc_library { 1434 name: "libvndk", 1435 vendor_available: true, 1436 product_available: true, 1437 vndk: { 1438 enabled: true, 1439 }, 1440 nocrt: true, 1441 } 1442 1443 cc_library { 1444 name: "libvndk_ext", 1445 vendor: true, 1446 vndk: { 1447 enabled: true, 1448 extends: "libvndk", 1449 }, 1450 nocrt: true, 1451 } 1452 `) 1453 1454 // Ensures that the core variant of "libvndk_ext" can be found. 1455 mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module) 1456 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" { 1457 t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends) 1458 } 1459} 1460 1461func TestVndkExtWithoutProductVndkVersion(t *testing.T) { 1462 // This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set. 1463 ctx := testCcNoProductVndk(t, ` 1464 cc_library { 1465 name: "libvndk", 1466 vendor_available: true, 1467 product_available: true, 1468 vndk: { 1469 enabled: true, 1470 }, 1471 nocrt: true, 1472 } 1473 1474 cc_library { 1475 name: "libvndk_ext_product", 1476 product_specific: true, 1477 vndk: { 1478 enabled: true, 1479 extends: "libvndk", 1480 }, 1481 nocrt: true, 1482 } 1483 `) 1484 1485 // Ensures that the core variant of "libvndk_ext_product" can be found. 1486 mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module) 1487 if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" { 1488 t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends) 1489 } 1490} 1491 1492func TestVndkExtError(t *testing.T) { 1493 // This test ensures an error is emitted in ill-formed vndk-ext definition. 1494 testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", ` 1495 cc_library { 1496 name: "libvndk", 1497 vendor_available: true, 1498 product_available: true, 1499 vndk: { 1500 enabled: true, 1501 }, 1502 nocrt: true, 1503 } 1504 1505 cc_library { 1506 name: "libvndk_ext", 1507 vndk: { 1508 enabled: true, 1509 extends: "libvndk", 1510 }, 1511 nocrt: true, 1512 } 1513 `) 1514 1515 testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", ` 1516 cc_library { 1517 name: "libvndk", 1518 vendor_available: true, 1519 product_available: true, 1520 vndk: { 1521 enabled: true, 1522 }, 1523 nocrt: true, 1524 } 1525 1526 cc_library { 1527 name: "libvndk_ext", 1528 vendor: true, 1529 vndk: { 1530 enabled: true, 1531 }, 1532 nocrt: true, 1533 } 1534 `) 1535 1536 testCcErrorProductVndk(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", ` 1537 cc_library { 1538 name: "libvndk", 1539 vendor_available: true, 1540 product_available: true, 1541 vndk: { 1542 enabled: true, 1543 }, 1544 nocrt: true, 1545 } 1546 1547 cc_library { 1548 name: "libvndk_ext_product", 1549 product_specific: true, 1550 vndk: { 1551 enabled: true, 1552 }, 1553 nocrt: true, 1554 } 1555 `) 1556 1557 testCcErrorProductVndk(t, "must not set at the same time as `vndk: {extends: \"\\.\\.\\.\"}`", ` 1558 cc_library { 1559 name: "libvndk", 1560 vendor_available: true, 1561 product_available: true, 1562 vndk: { 1563 enabled: true, 1564 }, 1565 nocrt: true, 1566 } 1567 1568 cc_library { 1569 name: "libvndk_ext_product", 1570 product_specific: true, 1571 vendor_available: true, 1572 product_available: true, 1573 vndk: { 1574 enabled: true, 1575 extends: "libvndk", 1576 }, 1577 nocrt: true, 1578 } 1579 `) 1580} 1581 1582func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) { 1583 // This test ensures an error is emitted for inconsistent support_system_process. 1584 testCcError(t, "module \".*\" with mismatched support_system_process", ` 1585 cc_library { 1586 name: "libvndk", 1587 vendor_available: true, 1588 product_available: true, 1589 vndk: { 1590 enabled: true, 1591 }, 1592 nocrt: true, 1593 } 1594 1595 cc_library { 1596 name: "libvndk_sp_ext", 1597 vendor: true, 1598 vndk: { 1599 enabled: true, 1600 extends: "libvndk", 1601 support_system_process: true, 1602 }, 1603 nocrt: true, 1604 } 1605 `) 1606 1607 testCcError(t, "module \".*\" with mismatched support_system_process", ` 1608 cc_library { 1609 name: "libvndk_sp", 1610 vendor_available: true, 1611 product_available: true, 1612 vndk: { 1613 enabled: true, 1614 support_system_process: true, 1615 }, 1616 nocrt: true, 1617 } 1618 1619 cc_library { 1620 name: "libvndk_ext", 1621 vendor: true, 1622 vndk: { 1623 enabled: true, 1624 extends: "libvndk_sp", 1625 }, 1626 nocrt: true, 1627 } 1628 `) 1629} 1630 1631func TestVndkExtVendorAvailableFalseError(t *testing.T) { 1632 // This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library 1633 // with `private: true`. 1634 testCcError(t, "`extends` refers module \".*\" which has `private: true`", ` 1635 cc_library { 1636 name: "libvndk", 1637 vendor_available: true, 1638 product_available: true, 1639 vndk: { 1640 enabled: true, 1641 private: true, 1642 }, 1643 nocrt: true, 1644 } 1645 1646 cc_library { 1647 name: "libvndk_ext", 1648 vendor: true, 1649 vndk: { 1650 enabled: true, 1651 extends: "libvndk", 1652 }, 1653 nocrt: true, 1654 } 1655 `) 1656 1657 testCcErrorProductVndk(t, "`extends` refers module \".*\" which has `private: true`", ` 1658 cc_library { 1659 name: "libvndk", 1660 vendor_available: true, 1661 product_available: true, 1662 vndk: { 1663 enabled: true, 1664 private: true, 1665 }, 1666 nocrt: true, 1667 } 1668 1669 cc_library { 1670 name: "libvndk_ext_product", 1671 product_specific: true, 1672 vndk: { 1673 enabled: true, 1674 extends: "libvndk", 1675 }, 1676 nocrt: true, 1677 } 1678 `) 1679} 1680 1681func TestVendorModuleUseVndkExt(t *testing.T) { 1682 // This test ensures a vendor module can depend on a VNDK-Ext library. 1683 testCc(t, ` 1684 cc_library { 1685 name: "libvndk", 1686 vendor_available: true, 1687 product_available: true, 1688 vndk: { 1689 enabled: true, 1690 }, 1691 nocrt: true, 1692 } 1693 1694 cc_library { 1695 name: "libvndk_ext", 1696 vendor: true, 1697 vndk: { 1698 enabled: true, 1699 extends: "libvndk", 1700 }, 1701 nocrt: true, 1702 } 1703 1704 cc_library { 1705 name: "libvndk_sp", 1706 vendor_available: true, 1707 product_available: true, 1708 vndk: { 1709 enabled: true, 1710 support_system_process: true, 1711 }, 1712 nocrt: true, 1713 } 1714 1715 cc_library { 1716 name: "libvndk_sp_ext", 1717 vendor: true, 1718 vndk: { 1719 enabled: true, 1720 extends: "libvndk_sp", 1721 support_system_process: true, 1722 }, 1723 nocrt: true, 1724 } 1725 1726 cc_library { 1727 name: "libvendor", 1728 vendor: true, 1729 shared_libs: ["libvndk_ext", "libvndk_sp_ext"], 1730 nocrt: true, 1731 } 1732 `) 1733} 1734 1735func TestVndkExtUseVendorLib(t *testing.T) { 1736 // This test ensures a VNDK-Ext library can depend on a vendor library. 1737 testCc(t, ` 1738 cc_library { 1739 name: "libvndk", 1740 vendor_available: true, 1741 product_available: true, 1742 vndk: { 1743 enabled: true, 1744 }, 1745 nocrt: true, 1746 } 1747 1748 cc_library { 1749 name: "libvndk_ext", 1750 vendor: true, 1751 vndk: { 1752 enabled: true, 1753 extends: "libvndk", 1754 }, 1755 shared_libs: ["libvendor"], 1756 nocrt: true, 1757 } 1758 1759 cc_library { 1760 name: "libvendor", 1761 vendor: true, 1762 nocrt: true, 1763 } 1764 `) 1765 1766 // This test ensures a VNDK-SP-Ext library can depend on a vendor library. 1767 testCc(t, ` 1768 cc_library { 1769 name: "libvndk_sp", 1770 vendor_available: true, 1771 product_available: true, 1772 vndk: { 1773 enabled: true, 1774 support_system_process: true, 1775 }, 1776 nocrt: true, 1777 } 1778 1779 cc_library { 1780 name: "libvndk_sp_ext", 1781 vendor: true, 1782 vndk: { 1783 enabled: true, 1784 extends: "libvndk_sp", 1785 support_system_process: true, 1786 }, 1787 shared_libs: ["libvendor"], // Cause an error 1788 nocrt: true, 1789 } 1790 1791 cc_library { 1792 name: "libvendor", 1793 vendor: true, 1794 nocrt: true, 1795 } 1796 `) 1797} 1798 1799func TestProductVndkExtDependency(t *testing.T) { 1800 bp := ` 1801 cc_library { 1802 name: "libvndk", 1803 vendor_available: true, 1804 product_available: true, 1805 vndk: { 1806 enabled: true, 1807 }, 1808 nocrt: true, 1809 } 1810 1811 cc_library { 1812 name: "libvndk_ext_product", 1813 product_specific: true, 1814 vndk: { 1815 enabled: true, 1816 extends: "libvndk", 1817 }, 1818 shared_libs: ["libproduct_for_vndklibs"], 1819 nocrt: true, 1820 } 1821 1822 cc_library { 1823 name: "libvndk_sp", 1824 vendor_available: true, 1825 product_available: true, 1826 vndk: { 1827 enabled: true, 1828 support_system_process: true, 1829 }, 1830 nocrt: true, 1831 } 1832 1833 cc_library { 1834 name: "libvndk_sp_ext_product", 1835 product_specific: true, 1836 vndk: { 1837 enabled: true, 1838 extends: "libvndk_sp", 1839 support_system_process: true, 1840 }, 1841 shared_libs: ["libproduct_for_vndklibs"], 1842 nocrt: true, 1843 } 1844 1845 cc_library { 1846 name: "libproduct", 1847 product_specific: true, 1848 shared_libs: ["libvndk_ext_product", "libvndk_sp_ext_product"], 1849 nocrt: true, 1850 } 1851 1852 cc_library { 1853 name: "libproduct_for_vndklibs", 1854 product_specific: true, 1855 nocrt: true, 1856 } 1857 ` 1858 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 1859 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 1860 config.TestProductVariables.ProductVndkVersion = StringPtr("current") 1861 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 1862 1863 testCcWithConfig(t, config) 1864} 1865 1866func TestVndkSpExtUseVndkError(t *testing.T) { 1867 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK 1868 // library. 1869 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1870 cc_library { 1871 name: "libvndk", 1872 vendor_available: true, 1873 product_available: true, 1874 vndk: { 1875 enabled: true, 1876 }, 1877 nocrt: true, 1878 } 1879 1880 cc_library { 1881 name: "libvndk_sp", 1882 vendor_available: true, 1883 product_available: true, 1884 vndk: { 1885 enabled: true, 1886 support_system_process: true, 1887 }, 1888 nocrt: true, 1889 } 1890 1891 cc_library { 1892 name: "libvndk_sp_ext", 1893 vendor: true, 1894 vndk: { 1895 enabled: true, 1896 extends: "libvndk_sp", 1897 support_system_process: true, 1898 }, 1899 shared_libs: ["libvndk"], // Cause an error 1900 nocrt: true, 1901 } 1902 `) 1903 1904 // This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext 1905 // library. 1906 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1907 cc_library { 1908 name: "libvndk", 1909 vendor_available: true, 1910 product_available: true, 1911 vndk: { 1912 enabled: true, 1913 }, 1914 nocrt: true, 1915 } 1916 1917 cc_library { 1918 name: "libvndk_ext", 1919 vendor: true, 1920 vndk: { 1921 enabled: true, 1922 extends: "libvndk", 1923 }, 1924 nocrt: true, 1925 } 1926 1927 cc_library { 1928 name: "libvndk_sp", 1929 vendor_available: true, 1930 product_available: true, 1931 vndk: { 1932 enabled: true, 1933 support_system_process: true, 1934 }, 1935 nocrt: true, 1936 } 1937 1938 cc_library { 1939 name: "libvndk_sp_ext", 1940 vendor: true, 1941 vndk: { 1942 enabled: true, 1943 extends: "libvndk_sp", 1944 support_system_process: true, 1945 }, 1946 shared_libs: ["libvndk_ext"], // Cause an error 1947 nocrt: true, 1948 } 1949 `) 1950} 1951 1952func TestVndkUseVndkExtError(t *testing.T) { 1953 // This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a 1954 // VNDK-Ext/VNDK-SP-Ext library. 1955 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 1956 cc_library { 1957 name: "libvndk", 1958 vendor_available: true, 1959 product_available: true, 1960 vndk: { 1961 enabled: true, 1962 }, 1963 nocrt: true, 1964 } 1965 1966 cc_library { 1967 name: "libvndk_ext", 1968 vendor: true, 1969 vndk: { 1970 enabled: true, 1971 extends: "libvndk", 1972 }, 1973 nocrt: true, 1974 } 1975 1976 cc_library { 1977 name: "libvndk2", 1978 vendor_available: true, 1979 product_available: true, 1980 vndk: { 1981 enabled: true, 1982 }, 1983 shared_libs: ["libvndk_ext"], 1984 nocrt: true, 1985 } 1986 `) 1987 1988 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 1989 cc_library { 1990 name: "libvndk", 1991 vendor_available: true, 1992 product_available: true, 1993 vndk: { 1994 enabled: true, 1995 }, 1996 nocrt: true, 1997 } 1998 1999 cc_library { 2000 name: "libvndk_ext", 2001 vendor: true, 2002 vndk: { 2003 enabled: true, 2004 extends: "libvndk", 2005 }, 2006 nocrt: true, 2007 } 2008 2009 cc_library { 2010 name: "libvndk2", 2011 vendor_available: true, 2012 vndk: { 2013 enabled: true, 2014 }, 2015 target: { 2016 vendor: { 2017 shared_libs: ["libvndk_ext"], 2018 }, 2019 }, 2020 nocrt: true, 2021 } 2022 `) 2023 2024 testCcError(t, "dependency \".*\" of \".*\" missing variant", ` 2025 cc_library { 2026 name: "libvndk_sp", 2027 vendor_available: true, 2028 product_available: true, 2029 vndk: { 2030 enabled: true, 2031 support_system_process: true, 2032 }, 2033 nocrt: true, 2034 } 2035 2036 cc_library { 2037 name: "libvndk_sp_ext", 2038 vendor: true, 2039 vndk: { 2040 enabled: true, 2041 extends: "libvndk_sp", 2042 support_system_process: true, 2043 }, 2044 nocrt: true, 2045 } 2046 2047 cc_library { 2048 name: "libvndk_sp_2", 2049 vendor_available: true, 2050 product_available: true, 2051 vndk: { 2052 enabled: true, 2053 support_system_process: true, 2054 }, 2055 shared_libs: ["libvndk_sp_ext"], 2056 nocrt: true, 2057 } 2058 `) 2059 2060 testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", ` 2061 cc_library { 2062 name: "libvndk_sp", 2063 vendor_available: true, 2064 product_available: true, 2065 vndk: { 2066 enabled: true, 2067 }, 2068 nocrt: true, 2069 } 2070 2071 cc_library { 2072 name: "libvndk_sp_ext", 2073 vendor: true, 2074 vndk: { 2075 enabled: true, 2076 extends: "libvndk_sp", 2077 }, 2078 nocrt: true, 2079 } 2080 2081 cc_library { 2082 name: "libvndk_sp2", 2083 vendor_available: true, 2084 vndk: { 2085 enabled: true, 2086 }, 2087 target: { 2088 vendor: { 2089 shared_libs: ["libvndk_sp_ext"], 2090 }, 2091 }, 2092 nocrt: true, 2093 } 2094 `) 2095} 2096 2097func TestEnforceProductVndkVersion(t *testing.T) { 2098 bp := ` 2099 cc_library { 2100 name: "libllndk", 2101 llndk: { 2102 symbol_file: "libllndk.map.txt", 2103 } 2104 } 2105 cc_library { 2106 name: "libvndk", 2107 vendor_available: true, 2108 product_available: true, 2109 vndk: { 2110 enabled: true, 2111 }, 2112 nocrt: true, 2113 } 2114 cc_library { 2115 name: "libvndk_sp", 2116 vendor_available: true, 2117 product_available: true, 2118 vndk: { 2119 enabled: true, 2120 support_system_process: true, 2121 }, 2122 nocrt: true, 2123 } 2124 cc_library { 2125 name: "libva", 2126 vendor_available: true, 2127 nocrt: true, 2128 } 2129 cc_library { 2130 name: "libpa", 2131 product_available: true, 2132 nocrt: true, 2133 } 2134 cc_library { 2135 name: "libboth_available", 2136 vendor_available: true, 2137 product_available: true, 2138 nocrt: true, 2139 srcs: ["foo.c"], 2140 target: { 2141 vendor: { 2142 suffix: "-vendor", 2143 }, 2144 product: { 2145 suffix: "-product", 2146 }, 2147 } 2148 } 2149 cc_library { 2150 name: "libproduct_va", 2151 product_specific: true, 2152 vendor_available: true, 2153 nocrt: true, 2154 } 2155 cc_library { 2156 name: "libprod", 2157 product_specific: true, 2158 shared_libs: [ 2159 "libllndk", 2160 "libvndk", 2161 "libvndk_sp", 2162 "libpa", 2163 "libboth_available", 2164 "libproduct_va", 2165 ], 2166 nocrt: true, 2167 } 2168 cc_library { 2169 name: "libvendor", 2170 vendor: true, 2171 shared_libs: [ 2172 "libllndk", 2173 "libvndk", 2174 "libvndk_sp", 2175 "libva", 2176 "libboth_available", 2177 "libproduct_va", 2178 ], 2179 nocrt: true, 2180 } 2181 ` 2182 2183 ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext 2184 2185 checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant) 2186 checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant) 2187 2188 mod_vendor := ctx.ModuleForTests("libboth_available", vendorVariant).Module().(*Module) 2189 assertString(t, mod_vendor.outputFile.Path().Base(), "libboth_available-vendor.so") 2190 2191 mod_product := ctx.ModuleForTests("libboth_available", productVariant).Module().(*Module) 2192 assertString(t, mod_product.outputFile.Path().Base(), "libboth_available-product.so") 2193 2194 ensureStringContains := func(t *testing.T, str string, substr string) { 2195 t.Helper() 2196 if !strings.Contains(str, substr) { 2197 t.Errorf("%q is not found in %v", substr, str) 2198 } 2199 } 2200 ensureStringNotContains := func(t *testing.T, str string, substr string) { 2201 t.Helper() 2202 if strings.Contains(str, substr) { 2203 t.Errorf("%q is found in %v", substr, str) 2204 } 2205 } 2206 2207 // _static variant is used since _shared reuses *.o from the static variant 2208 vendor_static := ctx.ModuleForTests("libboth_available", strings.Replace(vendorVariant, "_shared", "_static", 1)) 2209 product_static := ctx.ModuleForTests("libboth_available", strings.Replace(productVariant, "_shared", "_static", 1)) 2210 2211 vendor_cflags := vendor_static.Rule("cc").Args["cFlags"] 2212 ensureStringContains(t, vendor_cflags, "-D__ANDROID_VNDK__") 2213 ensureStringContains(t, vendor_cflags, "-D__ANDROID_VENDOR__") 2214 ensureStringNotContains(t, vendor_cflags, "-D__ANDROID_PRODUCT__") 2215 2216 product_cflags := product_static.Rule("cc").Args["cFlags"] 2217 ensureStringContains(t, product_cflags, "-D__ANDROID_VNDK__") 2218 ensureStringContains(t, product_cflags, "-D__ANDROID_PRODUCT__") 2219 ensureStringNotContains(t, product_cflags, "-D__ANDROID_VENDOR__") 2220} 2221 2222func TestEnforceProductVndkVersionErrors(t *testing.T) { 2223 testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", ` 2224 cc_library { 2225 name: "libprod", 2226 product_specific: true, 2227 shared_libs: [ 2228 "libvendor", 2229 ], 2230 nocrt: true, 2231 } 2232 cc_library { 2233 name: "libvendor", 2234 vendor: true, 2235 nocrt: true, 2236 } 2237 `) 2238 testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", ` 2239 cc_library { 2240 name: "libprod", 2241 product_specific: true, 2242 shared_libs: [ 2243 "libsystem", 2244 ], 2245 nocrt: true, 2246 } 2247 cc_library { 2248 name: "libsystem", 2249 nocrt: true, 2250 } 2251 `) 2252 testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", ` 2253 cc_library { 2254 name: "libprod", 2255 product_specific: true, 2256 shared_libs: [ 2257 "libva", 2258 ], 2259 nocrt: true, 2260 } 2261 cc_library { 2262 name: "libva", 2263 vendor_available: true, 2264 nocrt: true, 2265 } 2266 `) 2267 testCcErrorProductVndk(t, "non-VNDK module should not link to \".*\" which has `private: true`", ` 2268 cc_library { 2269 name: "libprod", 2270 product_specific: true, 2271 shared_libs: [ 2272 "libvndk_private", 2273 ], 2274 nocrt: true, 2275 } 2276 cc_library { 2277 name: "libvndk_private", 2278 vendor_available: true, 2279 product_available: true, 2280 vndk: { 2281 enabled: true, 2282 private: true, 2283 }, 2284 nocrt: true, 2285 } 2286 `) 2287 testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", ` 2288 cc_library { 2289 name: "libprod", 2290 product_specific: true, 2291 shared_libs: [ 2292 "libsystem_ext", 2293 ], 2294 nocrt: true, 2295 } 2296 cc_library { 2297 name: "libsystem_ext", 2298 system_ext_specific: true, 2299 nocrt: true, 2300 } 2301 `) 2302 testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", ` 2303 cc_library { 2304 name: "libsystem", 2305 shared_libs: [ 2306 "libproduct_va", 2307 ], 2308 nocrt: true, 2309 } 2310 cc_library { 2311 name: "libproduct_va", 2312 product_specific: true, 2313 vendor_available: true, 2314 nocrt: true, 2315 } 2316 `) 2317} 2318 2319func TestMakeLinkType(t *testing.T) { 2320 bp := ` 2321 cc_library { 2322 name: "libvndk", 2323 vendor_available: true, 2324 product_available: true, 2325 vndk: { 2326 enabled: true, 2327 }, 2328 } 2329 cc_library { 2330 name: "libvndksp", 2331 vendor_available: true, 2332 product_available: true, 2333 vndk: { 2334 enabled: true, 2335 support_system_process: true, 2336 }, 2337 } 2338 cc_library { 2339 name: "libvndkprivate", 2340 vendor_available: true, 2341 product_available: true, 2342 vndk: { 2343 enabled: true, 2344 private: true, 2345 }, 2346 } 2347 cc_library { 2348 name: "libvendor", 2349 vendor: true, 2350 } 2351 cc_library { 2352 name: "libvndkext", 2353 vendor: true, 2354 vndk: { 2355 enabled: true, 2356 extends: "libvndk", 2357 }, 2358 } 2359 vndk_prebuilt_shared { 2360 name: "prevndk", 2361 version: "27", 2362 target_arch: "arm", 2363 binder32bit: true, 2364 vendor_available: true, 2365 product_available: true, 2366 vndk: { 2367 enabled: true, 2368 }, 2369 arch: { 2370 arm: { 2371 srcs: ["liba.so"], 2372 }, 2373 }, 2374 } 2375 cc_library { 2376 name: "libllndk", 2377 llndk: { 2378 symbol_file: "libllndk.map.txt", 2379 } 2380 } 2381 cc_library { 2382 name: "libllndkprivate", 2383 llndk: { 2384 symbol_file: "libllndkprivate.map.txt", 2385 private: true, 2386 } 2387 } 2388 2389 llndk_libraries_txt { 2390 name: "llndk.libraries.txt", 2391 } 2392 vndkcore_libraries_txt { 2393 name: "vndkcore.libraries.txt", 2394 } 2395 vndksp_libraries_txt { 2396 name: "vndksp.libraries.txt", 2397 } 2398 vndkprivate_libraries_txt { 2399 name: "vndkprivate.libraries.txt", 2400 } 2401 vndkcorevariant_libraries_txt { 2402 name: "vndkcorevariant.libraries.txt", 2403 insert_vndk_version: false, 2404 } 2405 ` 2406 2407 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 2408 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 2409 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 2410 // native:vndk 2411 ctx := testCcWithConfig(t, config) 2412 2413 checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", 2414 []string{"libvndk.so", "libvndkprivate.so"}) 2415 checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", 2416 []string{"libc++.so", "libvndksp.so"}) 2417 checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", 2418 []string{"libc.so", "libdl.so", "libft2.so", "libllndk.so", "libllndkprivate.so", "libm.so"}) 2419 checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", 2420 []string{"libft2.so", "libllndkprivate.so", "libvndkprivate.so"}) 2421 2422 vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared" 2423 2424 tests := []struct { 2425 variant string 2426 name string 2427 expected string 2428 }{ 2429 {vendorVariant, "libvndk", "native:vndk"}, 2430 {vendorVariant, "libvndksp", "native:vndk"}, 2431 {vendorVariant, "libvndkprivate", "native:vndk_private"}, 2432 {vendorVariant, "libvendor", "native:vendor"}, 2433 {vendorVariant, "libvndkext", "native:vendor"}, 2434 {vendorVariant, "libllndk", "native:vndk"}, 2435 {vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"}, 2436 {coreVariant, "libvndk", "native:platform"}, 2437 {coreVariant, "libvndkprivate", "native:platform"}, 2438 {coreVariant, "libllndk", "native:platform"}, 2439 } 2440 for _, test := range tests { 2441 t.Run(test.name, func(t *testing.T) { 2442 module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module) 2443 assertString(t, module.makeLinkType, test.expected) 2444 }) 2445 } 2446} 2447 2448var staticLinkDepOrderTestCases = []struct { 2449 // This is a string representation of a map[moduleName][]moduleDependency . 2450 // It models the dependencies declared in an Android.bp file. 2451 inStatic string 2452 2453 // This is a string representation of a map[moduleName][]moduleDependency . 2454 // It models the dependencies declared in an Android.bp file. 2455 inShared string 2456 2457 // allOrdered is a string representation of a map[moduleName][]moduleDependency . 2458 // The keys of allOrdered specify which modules we would like to check. 2459 // The values of allOrdered specify the expected result (of the transitive closure of all 2460 // dependencies) for each module to test 2461 allOrdered string 2462 2463 // outOrdered is a string representation of a map[moduleName][]moduleDependency . 2464 // The keys of outOrdered specify which modules we would like to check. 2465 // The values of outOrdered specify the expected result (of the ordered linker command line) 2466 // for each module to test. 2467 outOrdered string 2468}{ 2469 // Simple tests 2470 { 2471 inStatic: "", 2472 outOrdered: "", 2473 }, 2474 { 2475 inStatic: "a:", 2476 outOrdered: "a:", 2477 }, 2478 { 2479 inStatic: "a:b; b:", 2480 outOrdered: "a:b; b:", 2481 }, 2482 // Tests of reordering 2483 { 2484 // diamond example 2485 inStatic: "a:d,b,c; b:d; c:d; d:", 2486 outOrdered: "a:b,c,d; b:d; c:d; d:", 2487 }, 2488 { 2489 // somewhat real example 2490 inStatic: "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b", 2491 outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b", 2492 }, 2493 { 2494 // multiple reorderings 2495 inStatic: "a:b,c,d,e; d:b; e:c", 2496 outOrdered: "a:d,b,e,c; d:b; e:c", 2497 }, 2498 { 2499 // should reorder without adding new transitive dependencies 2500 inStatic: "bin:lib2,lib1; lib1:lib2,liboptional", 2501 allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional", 2502 outOrdered: "bin:lib1,lib2; lib1:lib2,liboptional", 2503 }, 2504 { 2505 // multiple levels of dependencies 2506 inStatic: "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d", 2507 allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d", 2508 outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d", 2509 }, 2510 // shared dependencies 2511 { 2512 // Note that this test doesn't recurse, to minimize the amount of logic it tests. 2513 // So, we don't actually have to check that a shared dependency of c will change the order 2514 // of a library that depends statically on b and on c. We only need to check that if c has 2515 // a shared dependency on b, that that shows up in allOrdered. 2516 inShared: "c:b", 2517 allOrdered: "c:b", 2518 outOrdered: "c:", 2519 }, 2520 { 2521 // This test doesn't actually include any shared dependencies but it's a reminder of what 2522 // the second phase of the above test would look like 2523 inStatic: "a:b,c; c:b", 2524 allOrdered: "a:c,b; c:b", 2525 outOrdered: "a:c,b; c:b", 2526 }, 2527 // tiebreakers for when two modules specifying different orderings and there is no dependency 2528 // to dictate an order 2529 { 2530 // if the tie is between two modules at the end of a's deps, then a's order wins 2531 inStatic: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d", 2532 outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d", 2533 }, 2534 { 2535 // if the tie is between two modules at the start of a's deps, then c's order is used 2536 inStatic: "a1:d,e,b1,c1; b1:d,e; c1:e,d; a2:d,e,b2,c2; b2:d,e; c2:d,e", 2537 outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d; a2:b2,c2,d,e; b2:d,e; c2:d,e", 2538 }, 2539 // Tests involving duplicate dependencies 2540 { 2541 // simple duplicate 2542 inStatic: "a:b,c,c,b", 2543 outOrdered: "a:c,b", 2544 }, 2545 { 2546 // duplicates with reordering 2547 inStatic: "a:b,c,d,c; c:b", 2548 outOrdered: "a:d,c,b", 2549 }, 2550 // Tests to confirm the nonexistence of infinite loops. 2551 // These cases should never happen, so as long as the test terminates and the 2552 // result is deterministic then that should be fine. 2553 { 2554 inStatic: "a:a", 2555 outOrdered: "a:a", 2556 }, 2557 { 2558 inStatic: "a:b; b:c; c:a", 2559 allOrdered: "a:b,c; b:c,a; c:a,b", 2560 outOrdered: "a:b; b:c; c:a", 2561 }, 2562 { 2563 inStatic: "a:b,c; b:c,a; c:a,b", 2564 allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a", 2565 outOrdered: "a:c,b; b:a,c; c:b,a", 2566 }, 2567} 2568 2569// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}]) 2570func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) { 2571 // convert from "a:b,c; d:e" to "a:b,c;d:e" 2572 strippedText := strings.Replace(text, " ", "", -1) 2573 if len(strippedText) < 1 { 2574 return []android.Path{}, make(map[android.Path][]android.Path, 0) 2575 } 2576 allDeps = make(map[android.Path][]android.Path, 0) 2577 2578 // convert from "a:b,c;d:e" to ["a:b,c", "d:e"] 2579 moduleTexts := strings.Split(strippedText, ";") 2580 2581 outputForModuleName := func(moduleName string) android.Path { 2582 return android.PathForTesting(moduleName) 2583 } 2584 2585 for _, moduleText := range moduleTexts { 2586 // convert from "a:b,c" to ["a", "b,c"] 2587 components := strings.Split(moduleText, ":") 2588 if len(components) != 2 { 2589 panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1)) 2590 } 2591 moduleName := components[0] 2592 moduleOutput := outputForModuleName(moduleName) 2593 modulesInOrder = append(modulesInOrder, moduleOutput) 2594 2595 depString := components[1] 2596 // convert from "b,c" to ["b", "c"] 2597 depNames := strings.Split(depString, ",") 2598 if len(depString) < 1 { 2599 depNames = []string{} 2600 } 2601 var deps []android.Path 2602 for _, depName := range depNames { 2603 deps = append(deps, outputForModuleName(depName)) 2604 } 2605 allDeps[moduleOutput] = deps 2606 } 2607 return modulesInOrder, allDeps 2608} 2609 2610func TestStaticLibDepReordering(t *testing.T) { 2611 ctx := testCc(t, ` 2612 cc_library { 2613 name: "a", 2614 static_libs: ["b", "c", "d"], 2615 stl: "none", 2616 } 2617 cc_library { 2618 name: "b", 2619 stl: "none", 2620 } 2621 cc_library { 2622 name: "c", 2623 static_libs: ["b"], 2624 stl: "none", 2625 } 2626 cc_library { 2627 name: "d", 2628 stl: "none", 2629 } 2630 2631 `) 2632 2633 variant := "android_arm64_armv8-a_static" 2634 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) 2635 actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo). 2636 TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop() 2637 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"}) 2638 2639 if !reflect.DeepEqual(actual, expected) { 2640 t.Errorf("staticDeps orderings were not propagated correctly"+ 2641 "\nactual: %v"+ 2642 "\nexpected: %v", 2643 actual, 2644 expected, 2645 ) 2646 } 2647} 2648 2649func TestStaticLibDepReorderingWithShared(t *testing.T) { 2650 ctx := testCc(t, ` 2651 cc_library { 2652 name: "a", 2653 static_libs: ["b", "c"], 2654 stl: "none", 2655 } 2656 cc_library { 2657 name: "b", 2658 stl: "none", 2659 } 2660 cc_library { 2661 name: "c", 2662 shared_libs: ["b"], 2663 stl: "none", 2664 } 2665 2666 `) 2667 2668 variant := "android_arm64_armv8-a_static" 2669 moduleA := ctx.ModuleForTests("a", variant).Module().(*Module) 2670 actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo). 2671 TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop() 2672 expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"}) 2673 2674 if !reflect.DeepEqual(actual, expected) { 2675 t.Errorf("staticDeps orderings did not account for shared libs"+ 2676 "\nactual: %v"+ 2677 "\nexpected: %v", 2678 actual, 2679 expected, 2680 ) 2681 } 2682} 2683 2684func checkEquals(t *testing.T, message string, expected, actual interface{}) { 2685 t.Helper() 2686 if !reflect.DeepEqual(actual, expected) { 2687 t.Errorf(message+ 2688 "\nactual: %v"+ 2689 "\nexpected: %v", 2690 actual, 2691 expected, 2692 ) 2693 } 2694} 2695 2696func TestLlndkLibrary(t *testing.T) { 2697 result := prepareForCcTest.RunTestWithBp(t, ` 2698 cc_library { 2699 name: "libllndk", 2700 stubs: { versions: ["1", "2"] }, 2701 llndk: { 2702 symbol_file: "libllndk.map.txt", 2703 }, 2704 export_include_dirs: ["include"], 2705 } 2706 2707 cc_prebuilt_library_shared { 2708 name: "libllndkprebuilt", 2709 stubs: { versions: ["1", "2"] }, 2710 llndk: { 2711 symbol_file: "libllndkprebuilt.map.txt", 2712 }, 2713 } 2714 2715 cc_library { 2716 name: "libllndk_with_external_headers", 2717 stubs: { versions: ["1", "2"] }, 2718 llndk: { 2719 symbol_file: "libllndk.map.txt", 2720 export_llndk_headers: ["libexternal_llndk_headers"], 2721 }, 2722 header_libs: ["libexternal_headers"], 2723 export_header_lib_headers: ["libexternal_headers"], 2724 } 2725 cc_library_headers { 2726 name: "libexternal_headers", 2727 export_include_dirs: ["include"], 2728 vendor_available: true, 2729 } 2730 cc_library_headers { 2731 name: "libexternal_llndk_headers", 2732 export_include_dirs: ["include_llndk"], 2733 llndk: { 2734 symbol_file: "libllndk.map.txt", 2735 }, 2736 vendor_available: true, 2737 } 2738 2739 cc_library { 2740 name: "libllndk_with_override_headers", 2741 stubs: { versions: ["1", "2"] }, 2742 llndk: { 2743 symbol_file: "libllndk.map.txt", 2744 override_export_include_dirs: ["include_llndk"], 2745 }, 2746 export_include_dirs: ["include"], 2747 } 2748 `) 2749 actual := result.ModuleVariantsForTests("libllndk") 2750 for i := 0; i < len(actual); i++ { 2751 if !strings.HasPrefix(actual[i], "android_vendor.29_") { 2752 actual = append(actual[:i], actual[i+1:]...) 2753 i-- 2754 } 2755 } 2756 expected := []string{ 2757 "android_vendor.29_arm64_armv8-a_shared_current", 2758 "android_vendor.29_arm64_armv8-a_shared", 2759 "android_vendor.29_arm_armv7-a-neon_shared_current", 2760 "android_vendor.29_arm_armv7-a-neon_shared", 2761 } 2762 android.AssertArrayString(t, "variants for llndk stubs", expected, actual) 2763 2764 params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub") 2765 android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"]) 2766 2767 checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) { 2768 t.Helper() 2769 m := result.ModuleForTests(module, variant).Module() 2770 f := result.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo) 2771 android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]", 2772 expectedDirs, f.IncludeDirs) 2773 } 2774 2775 checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include") 2776 checkExportedIncludeDirs("libllndk", "android_vendor.29_arm64_armv8-a_shared", "include") 2777 checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include") 2778 checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk") 2779 checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include") 2780 checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk") 2781} 2782 2783func TestLlndkHeaders(t *testing.T) { 2784 ctx := testCc(t, ` 2785 cc_library_headers { 2786 name: "libllndk_headers", 2787 export_include_dirs: ["my_include"], 2788 llndk: { 2789 llndk_headers: true, 2790 }, 2791 } 2792 cc_library { 2793 name: "libllndk", 2794 llndk: { 2795 symbol_file: "libllndk.map.txt", 2796 export_llndk_headers: ["libllndk_headers"], 2797 } 2798 } 2799 2800 cc_library { 2801 name: "libvendor", 2802 shared_libs: ["libllndk"], 2803 vendor: true, 2804 srcs: ["foo.c"], 2805 no_libcrt: true, 2806 nocrt: true, 2807 } 2808 `) 2809 2810 // _static variant is used since _shared reuses *.o from the static variant 2811 cc := ctx.ModuleForTests("libvendor", "android_vendor.29_arm_armv7-a-neon_static").Rule("cc") 2812 cflags := cc.Args["cFlags"] 2813 if !strings.Contains(cflags, "-Imy_include") { 2814 t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags) 2815 } 2816} 2817 2818func checkRuntimeLibs(t *testing.T, expected []string, module *Module) { 2819 actual := module.Properties.AndroidMkRuntimeLibs 2820 if !reflect.DeepEqual(actual, expected) { 2821 t.Errorf("incorrect runtime_libs for shared libs"+ 2822 "\nactual: %v"+ 2823 "\nexpected: %v", 2824 actual, 2825 expected, 2826 ) 2827 } 2828} 2829 2830const runtimeLibAndroidBp = ` 2831 cc_library { 2832 name: "liball_available", 2833 vendor_available: true, 2834 product_available: true, 2835 no_libcrt : true, 2836 nocrt : true, 2837 system_shared_libs : [], 2838 } 2839 cc_library { 2840 name: "libvendor_available1", 2841 vendor_available: true, 2842 runtime_libs: ["liball_available"], 2843 no_libcrt : true, 2844 nocrt : true, 2845 system_shared_libs : [], 2846 } 2847 cc_library { 2848 name: "libvendor_available2", 2849 vendor_available: true, 2850 runtime_libs: ["liball_available"], 2851 target: { 2852 vendor: { 2853 exclude_runtime_libs: ["liball_available"], 2854 } 2855 }, 2856 no_libcrt : true, 2857 nocrt : true, 2858 system_shared_libs : [], 2859 } 2860 cc_library { 2861 name: "libproduct_vendor", 2862 product_specific: true, 2863 vendor_available: true, 2864 no_libcrt : true, 2865 nocrt : true, 2866 system_shared_libs : [], 2867 } 2868 cc_library { 2869 name: "libcore", 2870 runtime_libs: ["liball_available"], 2871 no_libcrt : true, 2872 nocrt : true, 2873 system_shared_libs : [], 2874 } 2875 cc_library { 2876 name: "libvendor1", 2877 vendor: true, 2878 no_libcrt : true, 2879 nocrt : true, 2880 system_shared_libs : [], 2881 } 2882 cc_library { 2883 name: "libvendor2", 2884 vendor: true, 2885 runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"], 2886 no_libcrt : true, 2887 nocrt : true, 2888 system_shared_libs : [], 2889 } 2890 cc_library { 2891 name: "libproduct_available1", 2892 product_available: true, 2893 runtime_libs: ["liball_available"], 2894 no_libcrt : true, 2895 nocrt : true, 2896 system_shared_libs : [], 2897 } 2898 cc_library { 2899 name: "libproduct1", 2900 product_specific: true, 2901 no_libcrt : true, 2902 nocrt : true, 2903 system_shared_libs : [], 2904 } 2905 cc_library { 2906 name: "libproduct2", 2907 product_specific: true, 2908 runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"], 2909 no_libcrt : true, 2910 nocrt : true, 2911 system_shared_libs : [], 2912 } 2913` 2914 2915func TestRuntimeLibs(t *testing.T) { 2916 ctx := testCc(t, runtimeLibAndroidBp) 2917 2918 // runtime_libs for core variants use the module names without suffixes. 2919 variant := "android_arm64_armv8-a_shared" 2920 2921 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module) 2922 checkRuntimeLibs(t, []string{"liball_available"}, module) 2923 2924 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module) 2925 checkRuntimeLibs(t, []string{"liball_available"}, module) 2926 2927 module = ctx.ModuleForTests("libcore", variant).Module().(*Module) 2928 checkRuntimeLibs(t, []string{"liball_available"}, module) 2929 2930 // runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core 2931 // and vendor variants. 2932 variant = "android_vendor.29_arm64_armv8-a_shared" 2933 2934 module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module) 2935 checkRuntimeLibs(t, []string{"liball_available.vendor"}, module) 2936 2937 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module) 2938 checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module) 2939 2940 // runtime_libs for product variants have '.product' suffixes if the modules have both core 2941 // and product variants. 2942 variant = "android_product.29_arm64_armv8-a_shared" 2943 2944 module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module) 2945 checkRuntimeLibs(t, []string{"liball_available.product"}, module) 2946 2947 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module) 2948 checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module) 2949} 2950 2951func TestExcludeRuntimeLibs(t *testing.T) { 2952 ctx := testCc(t, runtimeLibAndroidBp) 2953 2954 variant := "android_arm64_armv8-a_shared" 2955 module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module) 2956 checkRuntimeLibs(t, []string{"liball_available"}, module) 2957 2958 variant = "android_vendor.29_arm64_armv8-a_shared" 2959 module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module) 2960 checkRuntimeLibs(t, nil, module) 2961} 2962 2963func TestRuntimeLibsNoVndk(t *testing.T) { 2964 ctx := testCcNoVndk(t, runtimeLibAndroidBp) 2965 2966 // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is. 2967 2968 variant := "android_arm64_armv8-a_shared" 2969 2970 module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module) 2971 checkRuntimeLibs(t, []string{"liball_available"}, module) 2972 2973 module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module) 2974 checkRuntimeLibs(t, []string{"liball_available", "libvendor1", "libproduct_vendor"}, module) 2975 2976 module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module) 2977 checkRuntimeLibs(t, []string{"liball_available", "libproduct1", "libproduct_vendor"}, module) 2978} 2979 2980func checkStaticLibs(t *testing.T, expected []string, module *Module) { 2981 t.Helper() 2982 actual := module.Properties.AndroidMkStaticLibs 2983 if !reflect.DeepEqual(actual, expected) { 2984 t.Errorf("incorrect static_libs"+ 2985 "\nactual: %v"+ 2986 "\nexpected: %v", 2987 actual, 2988 expected, 2989 ) 2990 } 2991} 2992 2993const staticLibAndroidBp = ` 2994 cc_library { 2995 name: "lib1", 2996 } 2997 cc_library { 2998 name: "lib2", 2999 static_libs: ["lib1"], 3000 } 3001` 3002 3003func TestStaticLibDepExport(t *testing.T) { 3004 ctx := testCc(t, staticLibAndroidBp) 3005 3006 // Check the shared version of lib2. 3007 variant := "android_arm64_armv8-a_shared" 3008 module := ctx.ModuleForTests("lib2", variant).Module().(*Module) 3009 checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module) 3010 3011 // Check the static version of lib2. 3012 variant = "android_arm64_armv8-a_static" 3013 module = ctx.ModuleForTests("lib2", variant).Module().(*Module) 3014 // libc++_static is linked additionally. 3015 checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module) 3016} 3017 3018var compilerFlagsTestCases = []struct { 3019 in string 3020 out bool 3021}{ 3022 { 3023 in: "a", 3024 out: false, 3025 }, 3026 { 3027 in: "-a", 3028 out: true, 3029 }, 3030 { 3031 in: "-Ipath/to/something", 3032 out: false, 3033 }, 3034 { 3035 in: "-isystempath/to/something", 3036 out: false, 3037 }, 3038 { 3039 in: "--coverage", 3040 out: false, 3041 }, 3042 { 3043 in: "-include a/b", 3044 out: true, 3045 }, 3046 { 3047 in: "-include a/b c/d", 3048 out: false, 3049 }, 3050 { 3051 in: "-DMACRO", 3052 out: true, 3053 }, 3054 { 3055 in: "-DMAC RO", 3056 out: false, 3057 }, 3058 { 3059 in: "-a -b", 3060 out: false, 3061 }, 3062 { 3063 in: "-DMACRO=definition", 3064 out: true, 3065 }, 3066 { 3067 in: "-DMACRO=defi nition", 3068 out: true, // TODO(jiyong): this should be false 3069 }, 3070 { 3071 in: "-DMACRO(x)=x + 1", 3072 out: true, 3073 }, 3074 { 3075 in: "-DMACRO=\"defi nition\"", 3076 out: true, 3077 }, 3078} 3079 3080type mockContext struct { 3081 BaseModuleContext 3082 result bool 3083} 3084 3085func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) { 3086 // CheckBadCompilerFlags calls this function when the flag should be rejected 3087 ctx.result = false 3088} 3089 3090func TestCompilerFlags(t *testing.T) { 3091 for _, testCase := range compilerFlagsTestCases { 3092 ctx := &mockContext{result: true} 3093 CheckBadCompilerFlags(ctx, "", []string{testCase.in}) 3094 if ctx.result != testCase.out { 3095 t.Errorf("incorrect output:") 3096 t.Errorf(" input: %#v", testCase.in) 3097 t.Errorf(" expected: %#v", testCase.out) 3098 t.Errorf(" got: %#v", ctx.result) 3099 } 3100 } 3101} 3102 3103func TestRecovery(t *testing.T) { 3104 ctx := testCc(t, ` 3105 cc_library_shared { 3106 name: "librecovery", 3107 recovery: true, 3108 } 3109 cc_library_shared { 3110 name: "librecovery32", 3111 recovery: true, 3112 compile_multilib:"32", 3113 } 3114 cc_library_shared { 3115 name: "libHalInRecovery", 3116 recovery_available: true, 3117 vendor: true, 3118 } 3119 `) 3120 3121 variants := ctx.ModuleVariantsForTests("librecovery") 3122 const arm64 = "android_recovery_arm64_armv8-a_shared" 3123 if len(variants) != 1 || !android.InList(arm64, variants) { 3124 t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants) 3125 } 3126 3127 variants = ctx.ModuleVariantsForTests("librecovery32") 3128 if android.InList(arm64, variants) { 3129 t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64) 3130 } 3131 3132 recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module) 3133 if !recoveryModule.Platform() { 3134 t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product") 3135 } 3136} 3137 3138func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) { 3139 bp := ` 3140 cc_prebuilt_test_library_shared { 3141 name: "test_lib", 3142 relative_install_path: "foo/bar/baz", 3143 srcs: ["srcpath/dontusethispath/baz.so"], 3144 } 3145 3146 cc_test { 3147 name: "main_test", 3148 data_libs: ["test_lib"], 3149 gtest: false, 3150 } 3151 ` 3152 3153 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 3154 config.TestProductVariables.DeviceVndkVersion = StringPtr("current") 3155 config.TestProductVariables.Platform_vndk_version = StringPtr("29") 3156 config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true) 3157 3158 ctx := testCcWithConfig(t, config) 3159 module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module() 3160 testBinary := module.(*Module).linker.(*testBinary) 3161 outputFiles, err := module.(android.OutputFileProducer).OutputFiles("") 3162 if err != nil { 3163 t.Fatalf("Expected cc_test to produce output files, error: %s", err) 3164 } 3165 if len(outputFiles) != 1 { 3166 t.Errorf("expected exactly one output file. output files: [%s]", outputFiles) 3167 } 3168 if len(testBinary.dataPaths()) != 1 { 3169 t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths()) 3170 } 3171 3172 outputPath := outputFiles[0].String() 3173 3174 if !strings.HasSuffix(outputPath, "/main_test") { 3175 t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath) 3176 } 3177 entries := android.AndroidMkEntriesForTest(t, ctx, module)[0] 3178 if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") { 3179 t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+ 3180 " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0]) 3181 } 3182} 3183 3184func TestVersionedStubs(t *testing.T) { 3185 ctx := testCc(t, ` 3186 cc_library_shared { 3187 name: "libFoo", 3188 srcs: ["foo.c"], 3189 stubs: { 3190 symbol_file: "foo.map.txt", 3191 versions: ["1", "2", "3"], 3192 }, 3193 } 3194 3195 cc_library_shared { 3196 name: "libBar", 3197 srcs: ["bar.c"], 3198 shared_libs: ["libFoo#1"], 3199 }`) 3200 3201 variants := ctx.ModuleVariantsForTests("libFoo") 3202 expectedVariants := []string{ 3203 "android_arm64_armv8-a_shared", 3204 "android_arm64_armv8-a_shared_1", 3205 "android_arm64_armv8-a_shared_2", 3206 "android_arm64_armv8-a_shared_3", 3207 "android_arm64_armv8-a_shared_current", 3208 "android_arm_armv7-a-neon_shared", 3209 "android_arm_armv7-a-neon_shared_1", 3210 "android_arm_armv7-a-neon_shared_2", 3211 "android_arm_armv7-a-neon_shared_3", 3212 "android_arm_armv7-a-neon_shared_current", 3213 } 3214 variantsMismatch := false 3215 if len(variants) != len(expectedVariants) { 3216 variantsMismatch = true 3217 } else { 3218 for _, v := range expectedVariants { 3219 if !inList(v, variants) { 3220 variantsMismatch = false 3221 } 3222 } 3223 } 3224 if variantsMismatch { 3225 t.Errorf("variants of libFoo expected:\n") 3226 for _, v := range expectedVariants { 3227 t.Errorf("%q\n", v) 3228 } 3229 t.Errorf(", but got:\n") 3230 for _, v := range variants { 3231 t.Errorf("%q\n", v) 3232 } 3233 } 3234 3235 libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld") 3236 libFlags := libBarLinkRule.Args["libFlags"] 3237 libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so" 3238 if !strings.Contains(libFlags, libFoo1StubPath) { 3239 t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags) 3240 } 3241 3242 libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc") 3243 cFlags := libBarCompileRule.Args["cFlags"] 3244 libFoo1VersioningMacro := "-D__LIBFOO_API__=1" 3245 if !strings.Contains(cFlags, libFoo1VersioningMacro) { 3246 t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags) 3247 } 3248} 3249 3250func TestVersioningMacro(t *testing.T) { 3251 for _, tc := range []struct{ moduleName, expected string }{ 3252 {"libc", "__LIBC_API__"}, 3253 {"libfoo", "__LIBFOO_API__"}, 3254 {"libfoo@1", "__LIBFOO_1_API__"}, 3255 {"libfoo-v1", "__LIBFOO_V1_API__"}, 3256 {"libfoo.v1", "__LIBFOO_V1_API__"}, 3257 } { 3258 checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName)) 3259 } 3260} 3261 3262func TestStaticExecutable(t *testing.T) { 3263 ctx := testCc(t, ` 3264 cc_binary { 3265 name: "static_test", 3266 srcs: ["foo.c", "baz.o"], 3267 static_executable: true, 3268 }`) 3269 3270 variant := "android_arm64_armv8-a" 3271 binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld") 3272 libFlags := binModuleRule.Args["libFlags"] 3273 systemStaticLibs := []string{"libc.a", "libm.a"} 3274 for _, lib := range systemStaticLibs { 3275 if !strings.Contains(libFlags, lib) { 3276 t.Errorf("Static lib %q was not found in %q", lib, libFlags) 3277 } 3278 } 3279 systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"} 3280 for _, lib := range systemSharedLibs { 3281 if strings.Contains(libFlags, lib) { 3282 t.Errorf("Shared lib %q was found in %q", lib, libFlags) 3283 } 3284 } 3285} 3286 3287func TestStaticDepsOrderWithStubs(t *testing.T) { 3288 ctx := testCc(t, ` 3289 cc_binary { 3290 name: "mybin", 3291 srcs: ["foo.c"], 3292 static_libs: ["libfooC", "libfooB"], 3293 static_executable: true, 3294 stl: "none", 3295 } 3296 3297 cc_library { 3298 name: "libfooB", 3299 srcs: ["foo.c"], 3300 shared_libs: ["libfooC"], 3301 stl: "none", 3302 } 3303 3304 cc_library { 3305 name: "libfooC", 3306 srcs: ["foo.c"], 3307 stl: "none", 3308 stubs: { 3309 versions: ["1"], 3310 }, 3311 }`) 3312 3313 mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld") 3314 actual := mybin.Implicits[:2] 3315 expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"}) 3316 3317 if !reflect.DeepEqual(actual, expected) { 3318 t.Errorf("staticDeps orderings were not propagated correctly"+ 3319 "\nactual: %v"+ 3320 "\nexpected: %v", 3321 actual, 3322 expected, 3323 ) 3324 } 3325} 3326 3327func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) { 3328 testCcError(t, `module "libA" .* depends on disabled module "libB"`, ` 3329 cc_library { 3330 name: "libA", 3331 srcs: ["foo.c"], 3332 shared_libs: ["libB"], 3333 stl: "none", 3334 } 3335 3336 cc_library { 3337 name: "libB", 3338 srcs: ["foo.c"], 3339 enabled: false, 3340 stl: "none", 3341 } 3342 `) 3343} 3344 3345// Simple smoke test for the cc_fuzz target that ensures the rule compiles 3346// correctly. 3347func TestFuzzTarget(t *testing.T) { 3348 ctx := testCc(t, ` 3349 cc_fuzz { 3350 name: "fuzz_smoke_test", 3351 srcs: ["foo.c"], 3352 }`) 3353 3354 variant := "android_arm64_armv8-a_fuzzer" 3355 ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc") 3356} 3357 3358func TestAidl(t *testing.T) { 3359} 3360 3361func assertString(t *testing.T, got, expected string) { 3362 t.Helper() 3363 if got != expected { 3364 t.Errorf("expected %q got %q", expected, got) 3365 } 3366} 3367 3368func assertArrayString(t *testing.T, got, expected []string) { 3369 t.Helper() 3370 if len(got) != len(expected) { 3371 t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got) 3372 return 3373 } 3374 for i := range got { 3375 if got[i] != expected[i] { 3376 t.Errorf("expected %d-th %q (%q) got %q (%q)", 3377 i, expected[i], expected, got[i], got) 3378 return 3379 } 3380 } 3381} 3382 3383func assertMapKeys(t *testing.T, m map[string]string, expected []string) { 3384 t.Helper() 3385 assertArrayString(t, android.SortedStringKeys(m), expected) 3386} 3387 3388func TestDefaults(t *testing.T) { 3389 ctx := testCc(t, ` 3390 cc_defaults { 3391 name: "defaults", 3392 srcs: ["foo.c"], 3393 static: { 3394 srcs: ["bar.c"], 3395 }, 3396 shared: { 3397 srcs: ["baz.c"], 3398 }, 3399 bazel_module: { 3400 bp2build_available: true, 3401 }, 3402 } 3403 3404 cc_library_static { 3405 name: "libstatic", 3406 defaults: ["defaults"], 3407 } 3408 3409 cc_library_shared { 3410 name: "libshared", 3411 defaults: ["defaults"], 3412 } 3413 3414 cc_library { 3415 name: "libboth", 3416 defaults: ["defaults"], 3417 } 3418 3419 cc_binary { 3420 name: "binary", 3421 defaults: ["defaults"], 3422 }`) 3423 3424 pathsToBase := func(paths android.Paths) []string { 3425 var ret []string 3426 for _, p := range paths { 3427 ret = append(ret, p.Base()) 3428 } 3429 return ret 3430 } 3431 3432 shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld") 3433 if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) { 3434 t.Errorf("libshared ld rule wanted %q, got %q", w, g) 3435 } 3436 bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld") 3437 if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) { 3438 t.Errorf("libboth ld rule wanted %q, got %q", w, g) 3439 } 3440 binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld") 3441 if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) { 3442 t.Errorf("binary ld rule wanted %q, got %q", w, g) 3443 } 3444 3445 static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar") 3446 if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) { 3447 t.Errorf("libstatic ar rule wanted %q, got %q", w, g) 3448 } 3449 bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar") 3450 if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) { 3451 t.Errorf("libboth ar rule wanted %q, got %q", w, g) 3452 } 3453} 3454 3455func TestProductVariableDefaults(t *testing.T) { 3456 bp := ` 3457 cc_defaults { 3458 name: "libfoo_defaults", 3459 srcs: ["foo.c"], 3460 cppflags: ["-DFOO"], 3461 product_variables: { 3462 debuggable: { 3463 cppflags: ["-DBAR"], 3464 }, 3465 }, 3466 } 3467 3468 cc_library { 3469 name: "libfoo", 3470 defaults: ["libfoo_defaults"], 3471 } 3472 ` 3473 3474 result := android.GroupFixturePreparers( 3475 prepareForCcTest, 3476 android.PrepareForTestWithVariables, 3477 3478 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 3479 variables.Debuggable = BoolPtr(true) 3480 }), 3481 ).RunTestWithBp(t, bp) 3482 3483 libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module) 3484 android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR") 3485} 3486 3487func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) { 3488 t.Parallel() 3489 bp := ` 3490 cc_library_static { 3491 name: "libfoo", 3492 srcs: ["foo.c"], 3493 whole_static_libs: ["libbar"], 3494 } 3495 3496 cc_library_static { 3497 name: "libbar", 3498 whole_static_libs: ["libmissing"], 3499 } 3500 ` 3501 3502 result := android.GroupFixturePreparers( 3503 prepareForCcTest, 3504 android.PrepareForTestWithAllowMissingDependencies, 3505 ).RunTestWithBp(t, bp) 3506 3507 libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a") 3508 android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule) 3509 3510 android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing") 3511 3512 libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a") 3513 android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String()) 3514} 3515 3516func TestInstallSharedLibs(t *testing.T) { 3517 bp := ` 3518 cc_binary { 3519 name: "bin", 3520 host_supported: true, 3521 shared_libs: ["libshared"], 3522 runtime_libs: ["libruntime"], 3523 srcs: [":gen"], 3524 } 3525 3526 cc_library_shared { 3527 name: "libshared", 3528 host_supported: true, 3529 shared_libs: ["libtransitive"], 3530 } 3531 3532 cc_library_shared { 3533 name: "libtransitive", 3534 host_supported: true, 3535 } 3536 3537 cc_library_shared { 3538 name: "libruntime", 3539 host_supported: true, 3540 } 3541 3542 cc_binary_host { 3543 name: "tool", 3544 srcs: ["foo.cpp"], 3545 } 3546 3547 genrule { 3548 name: "gen", 3549 tools: ["tool"], 3550 out: ["gen.cpp"], 3551 cmd: "$(location tool) $(out)", 3552 } 3553 ` 3554 3555 config := TestConfig(t.TempDir(), android.Android, nil, bp, nil) 3556 ctx := testCcWithConfig(t, config) 3557 3558 hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install") 3559 hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install") 3560 hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install") 3561 hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install") 3562 hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install") 3563 3564 if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) { 3565 t.Errorf("expected host bin dependency %q, got %q", w, g) 3566 } 3567 3568 if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) { 3569 t.Errorf("expected host bin dependency %q, got %q", w, g) 3570 } 3571 3572 if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) { 3573 t.Errorf("expected host bin dependency %q, got %q", w, g) 3574 } 3575 3576 if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) { 3577 t.Errorf("expected host bin dependency %q, got %q", w, g) 3578 } 3579 3580 if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) { 3581 t.Errorf("expected no host bin dependency %q, got %q", w, g) 3582 } 3583 3584 deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install") 3585 deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install") 3586 deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install") 3587 deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install") 3588 3589 if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) { 3590 t.Errorf("expected device bin dependency %q, got %q", w, g) 3591 } 3592 3593 if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) { 3594 t.Errorf("expected device bin dependency %q, got %q", w, g) 3595 } 3596 3597 if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) { 3598 t.Errorf("expected device bin dependency %q, got %q", w, g) 3599 } 3600 3601 if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) { 3602 t.Errorf("expected device bin dependency %q, got %q", w, g) 3603 } 3604 3605 if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) { 3606 t.Errorf("expected no device bin dependency %q, got %q", w, g) 3607 } 3608 3609} 3610 3611func TestStubsLibReexportsHeaders(t *testing.T) { 3612 ctx := testCc(t, ` 3613 cc_library_shared { 3614 name: "libclient", 3615 srcs: ["foo.c"], 3616 shared_libs: ["libfoo#1"], 3617 } 3618 3619 cc_library_shared { 3620 name: "libfoo", 3621 srcs: ["foo.c"], 3622 shared_libs: ["libbar"], 3623 export_shared_lib_headers: ["libbar"], 3624 stubs: { 3625 symbol_file: "foo.map.txt", 3626 versions: ["1", "2", "3"], 3627 }, 3628 } 3629 3630 cc_library_shared { 3631 name: "libbar", 3632 export_include_dirs: ["include/libbar"], 3633 srcs: ["foo.c"], 3634 }`) 3635 3636 cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 3637 3638 if !strings.Contains(cFlags, "-Iinclude/libbar") { 3639 t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags) 3640 } 3641} 3642 3643func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) { 3644 ctx := testCc(t, ` 3645 cc_library { 3646 name: "libfoo", 3647 srcs: ["a/Foo.aidl"], 3648 aidl: { flags: ["-Werror"], }, 3649 } 3650 `) 3651 3652 libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") 3653 manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto")) 3654 aidlCommand := manifest.Commands[0].GetCommand() 3655 expectedAidlFlag := "-Werror" 3656 if !strings.Contains(aidlCommand, expectedAidlFlag) { 3657 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 3658 } 3659} 3660 3661func TestAidlFlagsWithMinSdkVersion(t *testing.T) { 3662 for _, tc := range []struct { 3663 name string 3664 sdkVersion string 3665 variant string 3666 expected string 3667 }{ 3668 { 3669 name: "default is current", 3670 sdkVersion: "", 3671 variant: "android_arm64_armv8-a_static", 3672 expected: "platform_apis", 3673 }, 3674 { 3675 name: "use sdk_version", 3676 sdkVersion: `sdk_version: "29"`, 3677 variant: "android_arm64_armv8-a_static", 3678 expected: "platform_apis", 3679 }, 3680 { 3681 name: "use sdk_version(sdk variant)", 3682 sdkVersion: `sdk_version: "29"`, 3683 variant: "android_arm64_armv8-a_sdk_static", 3684 expected: "29", 3685 }, 3686 { 3687 name: "use min_sdk_version", 3688 sdkVersion: `min_sdk_version: "29"`, 3689 variant: "android_arm64_armv8-a_static", 3690 expected: "29", 3691 }, 3692 } { 3693 t.Run(tc.name, func(t *testing.T) { 3694 ctx := testCc(t, ` 3695 cc_library { 3696 name: "libfoo", 3697 stl: "none", 3698 srcs: ["a/Foo.aidl"], 3699 `+tc.sdkVersion+` 3700 } 3701 `) 3702 libfoo := ctx.ModuleForTests("libfoo", tc.variant) 3703 manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto")) 3704 aidlCommand := manifest.Commands[0].GetCommand() 3705 expectedAidlFlag := "--min_sdk_version=" + tc.expected 3706 if !strings.Contains(aidlCommand, expectedAidlFlag) { 3707 t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag) 3708 } 3709 }) 3710 } 3711} 3712 3713func TestMinSdkVersionInClangTriple(t *testing.T) { 3714 ctx := testCc(t, ` 3715 cc_library_shared { 3716 name: "libfoo", 3717 srcs: ["foo.c"], 3718 min_sdk_version: "29", 3719 }`) 3720 3721 cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] 3722 android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29") 3723} 3724 3725func TestIncludeDirsExporting(t *testing.T) { 3726 3727 // Trim spaces from the beginning, end and immediately after any newline characters. Leaves 3728 // embedded newline characters alone. 3729 trimIndentingSpaces := func(s string) string { 3730 return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1")) 3731 } 3732 3733 checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) { 3734 t.Helper() 3735 expected = trimIndentingSpaces(expected) 3736 actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n")) 3737 if expected != actual { 3738 t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual) 3739 } 3740 } 3741 3742 type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo) 3743 3744 checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) { 3745 t.Helper() 3746 exported := ctx.ModuleProvider(module, FlagExporterInfoProvider).(FlagExporterInfo) 3747 name := module.Name() 3748 3749 for _, checker := range checkers { 3750 checker(t, name, exported) 3751 } 3752 } 3753 3754 expectedIncludeDirs := func(expectedPaths string) exportedChecker { 3755 return func(t *testing.T, name string, exported FlagExporterInfo) { 3756 t.Helper() 3757 checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs) 3758 } 3759 } 3760 3761 expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker { 3762 return func(t *testing.T, name string, exported FlagExporterInfo) { 3763 t.Helper() 3764 checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs) 3765 } 3766 } 3767 3768 expectedGeneratedHeaders := func(expectedPaths string) exportedChecker { 3769 return func(t *testing.T, name string, exported FlagExporterInfo) { 3770 t.Helper() 3771 checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders) 3772 } 3773 } 3774 3775 expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker { 3776 return func(t *testing.T, name string, exported FlagExporterInfo) { 3777 t.Helper() 3778 checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps) 3779 } 3780 } 3781 3782 genRuleModules := ` 3783 genrule { 3784 name: "genrule_foo", 3785 cmd: "generate-foo", 3786 out: [ 3787 "generated_headers/foo/generated_header.h", 3788 ], 3789 export_include_dirs: [ 3790 "generated_headers", 3791 ], 3792 } 3793 3794 genrule { 3795 name: "genrule_bar", 3796 cmd: "generate-bar", 3797 out: [ 3798 "generated_headers/bar/generated_header.h", 3799 ], 3800 export_include_dirs: [ 3801 "generated_headers", 3802 ], 3803 } 3804 ` 3805 3806 t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) { 3807 ctx := testCc(t, genRuleModules+` 3808 cc_library { 3809 name: "libfoo", 3810 srcs: ["foo.c"], 3811 export_include_dirs: ["foo/standard"], 3812 export_system_include_dirs: ["foo/system"], 3813 generated_headers: ["genrule_foo"], 3814 export_generated_headers: ["genrule_foo"], 3815 } 3816 3817 cc_library { 3818 name: "libbar", 3819 srcs: ["bar.c"], 3820 shared_libs: ["libfoo"], 3821 export_include_dirs: ["bar/standard"], 3822 export_system_include_dirs: ["bar/system"], 3823 generated_headers: ["genrule_bar"], 3824 export_generated_headers: ["genrule_bar"], 3825 } 3826 `) 3827 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 3828 checkIncludeDirs(t, ctx, foo, 3829 expectedIncludeDirs(` 3830 foo/standard 3831 .intermediates/genrule_foo/gen/generated_headers 3832 `), 3833 expectedSystemIncludeDirs(`foo/system`), 3834 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 3835 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 3836 ) 3837 3838 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module() 3839 checkIncludeDirs(t, ctx, bar, 3840 expectedIncludeDirs(` 3841 bar/standard 3842 .intermediates/genrule_bar/gen/generated_headers 3843 `), 3844 expectedSystemIncludeDirs(`bar/system`), 3845 expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`), 3846 expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`), 3847 ) 3848 }) 3849 3850 t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) { 3851 ctx := testCc(t, genRuleModules+` 3852 cc_library { 3853 name: "libfoo", 3854 srcs: ["foo.c"], 3855 export_include_dirs: ["foo/standard"], 3856 export_system_include_dirs: ["foo/system"], 3857 generated_headers: ["genrule_foo"], 3858 export_generated_headers: ["genrule_foo"], 3859 } 3860 3861 cc_library { 3862 name: "libbar", 3863 srcs: ["bar.c"], 3864 whole_static_libs: ["libfoo"], 3865 export_include_dirs: ["bar/standard"], 3866 export_system_include_dirs: ["bar/system"], 3867 generated_headers: ["genrule_bar"], 3868 export_generated_headers: ["genrule_bar"], 3869 } 3870 `) 3871 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 3872 checkIncludeDirs(t, ctx, foo, 3873 expectedIncludeDirs(` 3874 foo/standard 3875 .intermediates/genrule_foo/gen/generated_headers 3876 `), 3877 expectedSystemIncludeDirs(`foo/system`), 3878 expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 3879 expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`), 3880 ) 3881 3882 bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module() 3883 checkIncludeDirs(t, ctx, bar, 3884 expectedIncludeDirs(` 3885 bar/standard 3886 foo/standard 3887 .intermediates/genrule_foo/gen/generated_headers 3888 .intermediates/genrule_bar/gen/generated_headers 3889 `), 3890 expectedSystemIncludeDirs(` 3891 bar/system 3892 foo/system 3893 `), 3894 expectedGeneratedHeaders(` 3895 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h 3896 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h 3897 `), 3898 expectedOrderOnlyDeps(` 3899 .intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h 3900 .intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h 3901 `), 3902 ) 3903 }) 3904 3905 t.Run("ensure only aidl headers are exported", func(t *testing.T) { 3906 ctx := testCc(t, genRuleModules+` 3907 cc_library_shared { 3908 name: "libfoo", 3909 srcs: [ 3910 "foo.c", 3911 "b.aidl", 3912 "a.proto", 3913 ], 3914 aidl: { 3915 export_aidl_headers: true, 3916 } 3917 } 3918 `) 3919 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 3920 checkIncludeDirs(t, ctx, foo, 3921 expectedIncludeDirs(` 3922 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl 3923 `), 3924 expectedSystemIncludeDirs(``), 3925 expectedGeneratedHeaders(` 3926 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h 3927 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h 3928 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h 3929 `), 3930 expectedOrderOnlyDeps(` 3931 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h 3932 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h 3933 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h 3934 `), 3935 ) 3936 }) 3937 3938 t.Run("ensure only proto headers are exported", func(t *testing.T) { 3939 ctx := testCc(t, genRuleModules+` 3940 cc_library_shared { 3941 name: "libfoo", 3942 srcs: [ 3943 "foo.c", 3944 "b.aidl", 3945 "a.proto", 3946 ], 3947 proto: { 3948 export_proto_headers: true, 3949 } 3950 } 3951 `) 3952 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 3953 checkIncludeDirs(t, ctx, foo, 3954 expectedIncludeDirs(` 3955 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto 3956 `), 3957 expectedSystemIncludeDirs(``), 3958 expectedGeneratedHeaders(` 3959 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h 3960 `), 3961 expectedOrderOnlyDeps(` 3962 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h 3963 `), 3964 ) 3965 }) 3966 3967 t.Run("ensure only sysprop headers are exported", func(t *testing.T) { 3968 ctx := testCc(t, genRuleModules+` 3969 cc_library_shared { 3970 name: "libfoo", 3971 srcs: [ 3972 "foo.c", 3973 "a.sysprop", 3974 "b.aidl", 3975 "a.proto", 3976 ], 3977 } 3978 `) 3979 foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() 3980 checkIncludeDirs(t, ctx, foo, 3981 expectedIncludeDirs(` 3982 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include 3983 `), 3984 expectedSystemIncludeDirs(``), 3985 expectedGeneratedHeaders(` 3986 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h 3987 `), 3988 expectedOrderOnlyDeps(` 3989 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h 3990 .intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/a.sysprop.h 3991 `), 3992 ) 3993 }) 3994} 3995 3996func TestIncludeDirectoryOrdering(t *testing.T) { 3997 baseExpectedFlags := []string{ 3998 "${config.ArmThumbCflags}", 3999 "${config.ArmCflags}", 4000 "${config.CommonGlobalCflags}", 4001 "${config.DeviceGlobalCflags}", 4002 "${config.ExternalCflags}", 4003 "${config.ArmToolchainCflags}", 4004 "${config.ArmArmv7ANeonCflags}", 4005 "${config.ArmGenericCflags}", 4006 "-target", 4007 "armv7a-linux-androideabi20", 4008 } 4009 4010 expectedIncludes := []string{ 4011 "external/foo/android_arm_export_include_dirs", 4012 "external/foo/lib32_export_include_dirs", 4013 "external/foo/arm_export_include_dirs", 4014 "external/foo/android_export_include_dirs", 4015 "external/foo/linux_export_include_dirs", 4016 "external/foo/export_include_dirs", 4017 "external/foo/android_arm_local_include_dirs", 4018 "external/foo/lib32_local_include_dirs", 4019 "external/foo/arm_local_include_dirs", 4020 "external/foo/android_local_include_dirs", 4021 "external/foo/linux_local_include_dirs", 4022 "external/foo/local_include_dirs", 4023 "external/foo", 4024 "external/foo/libheader1", 4025 "external/foo/libheader2", 4026 "external/foo/libwhole1", 4027 "external/foo/libwhole2", 4028 "external/foo/libstatic1", 4029 "external/foo/libstatic2", 4030 "external/foo/libshared1", 4031 "external/foo/libshared2", 4032 "external/foo/liblinux", 4033 "external/foo/libandroid", 4034 "external/foo/libarm", 4035 "external/foo/lib32", 4036 "external/foo/libandroid_arm", 4037 "defaults/cc/common/ndk_libc++_shared", 4038 "defaults/cc/common/ndk_libandroid_support", 4039 } 4040 4041 conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"} 4042 cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"} 4043 4044 cflags := []string{"-Wall", "-Werror", "-std=candcpp"} 4045 cstd := []string{"-std=gnu99", "-std=conly"} 4046 cppstd := []string{"-std=gnu++17", "-std=cpp", "-fno-rtti"} 4047 4048 lastIncludes := []string{ 4049 "out/soong/ndk/sysroot/usr/include", 4050 "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi", 4051 } 4052 4053 combineSlices := func(slices ...[]string) []string { 4054 var ret []string 4055 for _, s := range slices { 4056 ret = append(ret, s...) 4057 } 4058 return ret 4059 } 4060 4061 testCases := []struct { 4062 name string 4063 src string 4064 expected []string 4065 }{ 4066 { 4067 name: "c", 4068 src: "foo.c", 4069 expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}), 4070 }, 4071 { 4072 name: "cc", 4073 src: "foo.cc", 4074 expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}), 4075 }, 4076 { 4077 name: "assemble", 4078 src: "foo.s", 4079 expected: combineSlices(baseExpectedFlags, []string{"-D__ASSEMBLY__"}, expectedIncludes, lastIncludes), 4080 }, 4081 } 4082 4083 for _, tc := range testCases { 4084 t.Run(tc.name, func(t *testing.T) { 4085 bp := fmt.Sprintf(` 4086 cc_library { 4087 name: "libfoo", 4088 srcs: ["%s"], 4089 cflags: ["-std=candcpp"], 4090 conlyflags: ["-std=conly"], 4091 cppflags: ["-std=cpp"], 4092 local_include_dirs: ["local_include_dirs"], 4093 export_include_dirs: ["export_include_dirs"], 4094 export_system_include_dirs: ["export_system_include_dirs"], 4095 static_libs: ["libstatic1", "libstatic2"], 4096 whole_static_libs: ["libwhole1", "libwhole2"], 4097 shared_libs: ["libshared1", "libshared2"], 4098 header_libs: ["libheader1", "libheader2"], 4099 target: { 4100 android: { 4101 shared_libs: ["libandroid"], 4102 local_include_dirs: ["android_local_include_dirs"], 4103 export_include_dirs: ["android_export_include_dirs"], 4104 }, 4105 android_arm: { 4106 shared_libs: ["libandroid_arm"], 4107 local_include_dirs: ["android_arm_local_include_dirs"], 4108 export_include_dirs: ["android_arm_export_include_dirs"], 4109 }, 4110 linux: { 4111 shared_libs: ["liblinux"], 4112 local_include_dirs: ["linux_local_include_dirs"], 4113 export_include_dirs: ["linux_export_include_dirs"], 4114 }, 4115 }, 4116 multilib: { 4117 lib32: { 4118 shared_libs: ["lib32"], 4119 local_include_dirs: ["lib32_local_include_dirs"], 4120 export_include_dirs: ["lib32_export_include_dirs"], 4121 }, 4122 }, 4123 arch: { 4124 arm: { 4125 shared_libs: ["libarm"], 4126 local_include_dirs: ["arm_local_include_dirs"], 4127 export_include_dirs: ["arm_export_include_dirs"], 4128 }, 4129 }, 4130 stl: "libc++", 4131 sdk_version: "20", 4132 } 4133 4134 cc_library_headers { 4135 name: "libheader1", 4136 export_include_dirs: ["libheader1"], 4137 sdk_version: "20", 4138 stl: "none", 4139 } 4140 4141 cc_library_headers { 4142 name: "libheader2", 4143 export_include_dirs: ["libheader2"], 4144 sdk_version: "20", 4145 stl: "none", 4146 } 4147 `, tc.src) 4148 4149 libs := []string{ 4150 "libstatic1", 4151 "libstatic2", 4152 "libwhole1", 4153 "libwhole2", 4154 "libshared1", 4155 "libshared2", 4156 "libandroid", 4157 "libandroid_arm", 4158 "liblinux", 4159 "lib32", 4160 "libarm", 4161 } 4162 4163 for _, lib := range libs { 4164 bp += fmt.Sprintf(` 4165 cc_library { 4166 name: "%s", 4167 export_include_dirs: ["%s"], 4168 sdk_version: "20", 4169 stl: "none", 4170 } 4171 `, lib, lib) 4172 } 4173 4174 ctx := android.GroupFixturePreparers( 4175 PrepareForIntegrationTestWithCc, 4176 android.FixtureAddTextFile("external/foo/Android.bp", bp), 4177 ).RunTest(t) 4178 // Use the arm variant instead of the arm64 variant so that it gets headers from 4179 // ndk_libandroid_support to test LateStaticLibs. 4180 cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"] 4181 4182 var includes []string 4183 flags := strings.Split(cflags, " ") 4184 for _, flag := range flags { 4185 if strings.HasPrefix(flag, "-I") { 4186 includes = append(includes, strings.TrimPrefix(flag, "-I")) 4187 } else if flag == "-isystem" { 4188 // skip isystem, include next 4189 } else if len(flag) > 0 { 4190 includes = append(includes, flag) 4191 } 4192 } 4193 4194 android.AssertArrayString(t, "includes", tc.expected, includes) 4195 }) 4196 } 4197 4198} 4199