1// Copyright (C) 2019 The Android Open Source Project 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 "path/filepath" 19 "testing" 20 21 "android/soong/android" 22 "android/soong/genrule" 23 "android/soong/snapshot" 24) 25 26func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { 27 RegisterPrebuiltBuildComponents(ctx) 28 RegisterCCBuildComponents(ctx) 29 RegisterBinaryBuildComponents(ctx) 30 RegisterLibraryBuildComponents(ctx) 31 RegisterLibraryHeadersBuildComponents(ctx) 32 33 ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) 34 ctx.RegisterModuleType("cc_object", ObjectFactory) 35 ctx.RegisterModuleType("cc_genrule", GenRuleFactory) 36 ctx.RegisterModuleType("ndk_prebuilt_shared_stl", NdkPrebuiltSharedStlFactory) 37 ctx.RegisterModuleType("ndk_prebuilt_static_stl", NdkPrebuiltStaticStlFactory) 38 ctx.RegisterModuleType("ndk_prebuilt_object", NdkPrebuiltObjectFactory) 39 ctx.RegisterModuleType("ndk_library", NdkLibraryFactory) 40} 41 42func GatherRequiredDepsForTest(oses ...android.OsType) string { 43 ret := commonDefaultModules() 44 45 supportLinuxBionic := false 46 for _, os := range oses { 47 if os == android.Windows { 48 ret += withWindowsModules() 49 } 50 if os == android.LinuxBionic { 51 supportLinuxBionic = true 52 ret += withLinuxBionic() 53 } 54 } 55 56 if !supportLinuxBionic { 57 ret += withoutLinuxBionic() 58 } 59 60 return ret 61} 62 63func commonDefaultModules() string { 64 return ` 65 cc_defaults { 66 name: "toolchain_libs_defaults", 67 vendor_available: true, 68 product_available: true, 69 recovery_available: true, 70 no_libcrt: true, 71 sdk_version: "minimum", 72 nocrt: true, 73 system_shared_libs: [], 74 stl: "none", 75 srcs: [""], 76 check_elf_files: false, 77 sanitize: { 78 never: true, 79 }, 80 } 81 82 cc_prebuilt_library_static { 83 name: "libcompiler_rt-extras", 84 defaults: ["toolchain_libs_defaults"], 85 vendor_ramdisk_available: true, 86 } 87 88 cc_prebuilt_library_static { 89 name: "libclang_rt.builtins", 90 defaults: ["toolchain_libs_defaults"], 91 host_supported: true, 92 vendor_available: true, 93 vendor_ramdisk_available: true, 94 native_bridge_supported: true, 95 } 96 97 cc_prebuilt_library_shared { 98 name: "libclang_rt.hwasan", 99 defaults: ["toolchain_libs_defaults"], 100 } 101 102 cc_prebuilt_library_static { 103 name: "libunwind", 104 defaults: [ 105 "linux_bionic_supported", 106 "toolchain_libs_defaults", 107 ], 108 vendor_ramdisk_available: true, 109 native_bridge_supported: true, 110 } 111 112 cc_prebuilt_library_static { 113 name: "libclang_rt.fuzzer", 114 defaults: [ 115 "linux_bionic_supported", 116 "toolchain_libs_defaults", 117 ], 118 } 119 120 // Needed for sanitizer 121 cc_prebuilt_library_shared { 122 name: "libclang_rt.ubsan_standalone", 123 defaults: ["toolchain_libs_defaults"], 124 } 125 126 cc_prebuilt_library_static { 127 name: "libclang_rt.ubsan_minimal", 128 defaults: ["toolchain_libs_defaults"], 129 } 130 131 cc_library { 132 name: "libc", 133 defaults: ["linux_bionic_supported"], 134 no_libcrt: true, 135 nocrt: true, 136 stl: "none", 137 system_shared_libs: [], 138 recovery_available: true, 139 stubs: { 140 versions: ["27", "28", "29"], 141 }, 142 llndk: { 143 symbol_file: "libc.map.txt", 144 }, 145 } 146 cc_library { 147 name: "libm", 148 defaults: ["linux_bionic_supported"], 149 no_libcrt: true, 150 nocrt: true, 151 stl: "none", 152 system_shared_libs: [], 153 recovery_available: true, 154 stubs: { 155 versions: ["27", "28", "29"], 156 }, 157 apex_available: [ 158 "//apex_available:platform", 159 "myapex" 160 ], 161 llndk: { 162 symbol_file: "libm.map.txt", 163 }, 164 } 165 166 // Coverage libraries 167 cc_library { 168 name: "libprofile-extras", 169 vendor_available: true, 170 vendor_ramdisk_available: true, 171 product_available: true, 172 recovery_available: true, 173 native_coverage: false, 174 system_shared_libs: [], 175 stl: "none", 176 notice: "custom_notice", 177 } 178 cc_library { 179 name: "libprofile-clang-extras", 180 vendor_available: true, 181 vendor_ramdisk_available: true, 182 product_available: true, 183 recovery_available: true, 184 native_coverage: false, 185 system_shared_libs: [], 186 stl: "none", 187 notice: "custom_notice", 188 } 189 cc_library { 190 name: "libprofile-extras_ndk", 191 vendor_available: true, 192 product_available: true, 193 native_coverage: false, 194 system_shared_libs: [], 195 stl: "none", 196 notice: "custom_notice", 197 sdk_version: "current", 198 } 199 cc_library { 200 name: "libprofile-clang-extras_ndk", 201 vendor_available: true, 202 product_available: true, 203 native_coverage: false, 204 system_shared_libs: [], 205 stl: "none", 206 notice: "custom_notice", 207 sdk_version: "current", 208 } 209 210 cc_library { 211 name: "libdl", 212 defaults: ["linux_bionic_supported"], 213 no_libcrt: true, 214 nocrt: true, 215 stl: "none", 216 system_shared_libs: [], 217 recovery_available: true, 218 stubs: { 219 versions: ["27", "28", "29"], 220 }, 221 apex_available: [ 222 "//apex_available:platform", 223 "myapex" 224 ], 225 llndk: { 226 symbol_file: "libdl.map.txt", 227 }, 228 } 229 cc_library { 230 name: "libft2", 231 no_libcrt: true, 232 nocrt: true, 233 system_shared_libs: [], 234 recovery_available: true, 235 llndk: { 236 symbol_file: "libft2.map.txt", 237 private: true, 238 } 239 } 240 cc_library { 241 name: "libc++_static", 242 no_libcrt: true, 243 nocrt: true, 244 system_shared_libs: [], 245 stl: "none", 246 vendor_available: true, 247 vendor_ramdisk_available: true, 248 product_available: true, 249 recovery_available: true, 250 host_supported: true, 251 min_sdk_version: "29", 252 apex_available: [ 253 "//apex_available:platform", 254 "//apex_available:anyapex", 255 ], 256 } 257 cc_library { 258 name: "libc++", 259 no_libcrt: true, 260 nocrt: true, 261 system_shared_libs: [], 262 stl: "none", 263 vendor_available: true, 264 product_available: true, 265 recovery_available: true, 266 host_supported: true, 267 min_sdk_version: "29", 268 vndk: { 269 enabled: true, 270 support_system_process: true, 271 }, 272 apex_available: [ 273 "//apex_available:platform", 274 "//apex_available:anyapex", 275 ], 276 } 277 cc_library { 278 name: "libc++demangle", 279 no_libcrt: true, 280 nocrt: true, 281 system_shared_libs: [], 282 stl: "none", 283 host_supported: false, 284 vendor_available: true, 285 vendor_ramdisk_available: true, 286 product_available: true, 287 recovery_available: true, 288 min_sdk_version: "29", 289 apex_available: [ 290 "//apex_available:platform", 291 "//apex_available:anyapex", 292 ], 293 } 294 295 cc_defaults { 296 name: "crt_defaults", 297 defaults: ["linux_bionic_supported"], 298 recovery_available: true, 299 vendor_available: true, 300 vendor_ramdisk_available: true, 301 product_available: true, 302 native_bridge_supported: true, 303 stl: "none", 304 min_sdk_version: "16", 305 crt: true, 306 system_shared_libs: [], 307 apex_available: [ 308 "//apex_available:platform", 309 "//apex_available:anyapex", 310 ], 311 } 312 313 cc_object { 314 name: "crtbegin_so", 315 defaults: ["crt_defaults"], 316 srcs: ["crtbegin_so.c"], 317 objs: ["crtbrand"], 318 } 319 320 cc_object { 321 name: "crtbegin_dynamic", 322 defaults: ["crt_defaults"], 323 srcs: ["crtbegin.c"], 324 objs: ["crtbrand"], 325 } 326 327 cc_object { 328 name: "crtbegin_static", 329 defaults: ["crt_defaults"], 330 srcs: ["crtbegin.c"], 331 objs: ["crtbrand"], 332 } 333 334 cc_object { 335 name: "crtend_so", 336 defaults: ["crt_defaults"], 337 srcs: ["crtend_so.c"], 338 objs: ["crtbrand"], 339 } 340 341 cc_object { 342 name: "crtend_android", 343 defaults: ["crt_defaults"], 344 srcs: ["crtend.c"], 345 objs: ["crtbrand"], 346 } 347 348 cc_object { 349 name: "crtbrand", 350 defaults: ["crt_defaults"], 351 srcs: ["crtbrand.c"], 352 } 353 354 cc_library { 355 name: "libprotobuf-cpp-lite", 356 } 357 358 cc_library { 359 name: "ndk_libunwind", 360 sdk_version: "minimum", 361 stl: "none", 362 system_shared_libs: [], 363 } 364 365 ndk_library { 366 name: "libc", 367 first_version: "minimum", 368 symbol_file: "libc.map.txt", 369 } 370 371 ndk_library { 372 name: "libm", 373 first_version: "minimum", 374 symbol_file: "libm.map.txt", 375 } 376 377 ndk_library { 378 name: "libdl", 379 first_version: "minimum", 380 symbol_file: "libdl.map.txt", 381 } 382 383 ndk_prebuilt_shared_stl { 384 name: "ndk_libc++_shared", 385 export_include_dirs: ["ndk_libc++_shared"], 386 } 387 388 ndk_prebuilt_static_stl { 389 name: "ndk_libandroid_support", 390 export_include_dirs: ["ndk_libandroid_support"], 391 } 392 393 cc_library_static { 394 name: "libgoogle-benchmark", 395 sdk_version: "current", 396 stl: "none", 397 system_shared_libs: [], 398 } 399 400 cc_library_static { 401 name: "note_memtag_heap_async", 402 } 403 404 cc_library_static { 405 name: "note_memtag_heap_sync", 406 } 407 408 cc_library { 409 name: "libc_musl", 410 host_supported: true, 411 no_libcrt: true, 412 nocrt: true, 413 system_shared_libs: [], 414 stl: "none", 415 } 416 ` 417} 418 419func withWindowsModules() string { 420 return ` 421 cc_prebuilt_library_static { 422 name: "libwinpthread", 423 host_supported: true, 424 enabled: false, 425 target: { 426 windows: { 427 enabled: true, 428 }, 429 }, 430 stl: "none", 431 srcs:[""], 432 } 433 ` 434} 435 436func withLinuxBionic() string { 437 return ` 438 cc_binary { 439 name: "linker", 440 defaults: ["linux_bionic_supported"], 441 recovery_available: true, 442 stl: "none", 443 nocrt: true, 444 static_executable: true, 445 native_coverage: false, 446 system_shared_libs: [], 447 } 448 449 cc_genrule { 450 name: "host_bionic_linker_script", 451 host_supported: true, 452 device_supported: false, 453 target: { 454 host: { 455 enabled: false, 456 }, 457 linux_bionic: { 458 enabled: true, 459 }, 460 }, 461 out: ["linker.script"], 462 } 463 464 cc_defaults { 465 name: "linux_bionic_supported", 466 host_supported: true, 467 target: { 468 host: { 469 enabled: false, 470 }, 471 linux_bionic: { 472 enabled: true, 473 }, 474 }, 475 } 476 ` 477} 478 479func withoutLinuxBionic() string { 480 return ` 481 cc_defaults { 482 name: "linux_bionic_supported", 483 } 484 ` 485} 486 487func GatherRequiredFilesForTest(fs map[string][]byte) { 488} 489 490// The directory in which cc linux bionic default modules will be defined. 491// 492// Placing them here ensures that their location does not conflict with default test modules 493// defined by other packages. 494const linuxBionicDefaultsPath = "defaults/cc/linux-bionic/Android.bp" 495 496// The directory in which the default cc common test modules will be defined. 497// 498// Placing them here ensures that their location does not conflict with default test modules 499// defined by other packages. 500const DefaultCcCommonTestModulesDir = "defaults/cc/common/" 501 502// Test fixture preparer that will register most cc build components. 503// 504// Singletons and mutators should only be added here if they are needed for a majority of cc 505// module types, otherwise they should be added under a separate preparer to allow them to be 506// selected only when needed to reduce test execution time. 507// 508// Module types do not have much of an overhead unless they are used so this should include as many 509// module types as possible. The exceptions are those module types that require mutators and/or 510// singletons in order to function in which case they should be kept together in a separate 511// preparer. 512var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers( 513 android.PrepareForTestWithAndroidBuildComponents, 514 android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest), 515 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 516 ctx.RegisterModuleType("cc_fuzz", FuzzFactory) 517 ctx.RegisterModuleType("cc_test", TestFactory) 518 ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) 519 ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) 520 521 RegisterVndkLibraryTxtTypes(ctx) 522 }), 523 524 // Additional files needed in tests that disallow non-existent source files. 525 // This includes files that are needed by all, or at least most, instances of a cc module type. 526 android.MockFS{ 527 // Needed for ndk_prebuilt_(shared|static)_stl. 528 "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs": nil, 529 }.AddToFixture(), 530) 531 532// Preparer that will define default cc modules, e.g. standard prebuilt modules. 533var PrepareForTestWithCcDefaultModules = android.GroupFixturePreparers( 534 PrepareForTestWithCcBuildComponents, 535 536 // Additional files needed in tests that disallow non-existent source. 537 android.MockFS{ 538 "defaults/cc/common/libc.map.txt": nil, 539 "defaults/cc/common/libdl.map.txt": nil, 540 "defaults/cc/common/libm.map.txt": nil, 541 "defaults/cc/common/ndk_libandroid_support": nil, 542 "defaults/cc/common/ndk_libc++_shared": nil, 543 "defaults/cc/common/crtbegin_so.c": nil, 544 "defaults/cc/common/crtbegin.c": nil, 545 "defaults/cc/common/crtend_so.c": nil, 546 "defaults/cc/common/crtend.c": nil, 547 "defaults/cc/common/crtbrand.c": nil, 548 }.AddToFixture(), 549 550 // Place the default cc test modules that are common to all platforms in a location that will not 551 // conflict with default test modules defined by other packages. 552 android.FixtureAddTextFile(DefaultCcCommonTestModulesDir+"Android.bp", commonDefaultModules()), 553 // Disable linux bionic by default. 554 android.FixtureAddTextFile(linuxBionicDefaultsPath, withoutLinuxBionic()), 555) 556 557// Prepare a fixture to use all cc module types, mutators and singletons fully. 558// 559// This should only be used by tests that want to run with as much of the build enabled as possible. 560var PrepareForIntegrationTestWithCc = android.GroupFixturePreparers( 561 android.PrepareForIntegrationTestWithAndroid, 562 genrule.PrepareForIntegrationTestWithGenrule, 563 PrepareForTestWithCcDefaultModules, 564) 565 566// The preparer to include if running a cc related test for windows. 567var PrepareForTestOnWindows = android.GroupFixturePreparers( 568 // Place the default cc test modules for windows platforms in a location that will not conflict 569 // with default test modules defined by other packages. 570 android.FixtureAddTextFile("defaults/cc/windows/Android.bp", withWindowsModules()), 571) 572 573// The preparer to include if running a cc related test for linux bionic. 574var PrepareForTestOnLinuxBionic = android.GroupFixturePreparers( 575 // Enable linux bionic 576 // 577 // Can be used after PrepareForTestWithCcDefaultModules to override its default behavior of 578 // disabling linux bionic, hence why this uses FixtureOverrideTextFile. 579 android.FixtureOverrideTextFile(linuxBionicDefaultsPath, withLinuxBionic()), 580) 581 582// This adds some additional modules and singletons which might negatively impact the performance 583// of tests so they are not included in the PrepareForIntegrationTestWithCc. 584var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers( 585 PrepareForIntegrationTestWithCc, 586 android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { 587 snapshot.VendorSnapshotImageSingleton.Init(ctx) 588 snapshot.RecoverySnapshotImageSingleton.Init(ctx) 589 RegisterVendorSnapshotModules(ctx) 590 RegisterRecoverySnapshotModules(ctx) 591 ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) 592 }), 593) 594 595// TestConfig is the legacy way of creating a test Config for testing cc modules. 596// 597// See testCc for an explanation as to how to stop using this deprecated method. 598// 599// deprecated 600func TestConfig(buildDir string, os android.OsType, env map[string]string, 601 bp string, fs map[string][]byte) android.Config { 602 603 // add some modules that are required by the compiler and/or linker 604 bp = bp + GatherRequiredDepsForTest(os) 605 606 mockFS := map[string][]byte{} 607 608 GatherRequiredFilesForTest(mockFS) 609 610 for k, v := range fs { 611 mockFS[k] = v 612 } 613 614 return android.TestArchConfig(buildDir, env, bp, mockFS) 615} 616 617// CreateTestContext is the legacy way of creating a TestContext for testing cc modules. 618// 619// See testCc for an explanation as to how to stop using this deprecated method. 620// 621// deprecated 622func CreateTestContext(config android.Config) *android.TestContext { 623 ctx := android.NewTestArchContext(config) 624 genrule.RegisterGenruleBuildComponents(ctx) 625 ctx.RegisterModuleType("cc_fuzz", FuzzFactory) 626 ctx.RegisterModuleType("cc_test", TestFactory) 627 ctx.RegisterModuleType("cc_test_library", TestLibraryFactory) 628 ctx.RegisterModuleType("filegroup", android.FileGroupFactory) 629 ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory) 630 631 snapshot.VendorSnapshotImageSingleton.Init(ctx) 632 snapshot.RecoverySnapshotImageSingleton.Init(ctx) 633 RegisterVendorSnapshotModules(ctx) 634 RegisterRecoverySnapshotModules(ctx) 635 ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) 636 RegisterVndkLibraryTxtTypes(ctx) 637 638 ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators) 639 android.RegisterPrebuiltMutators(ctx) 640 RegisterRequiredBuildComponentsForTest(ctx) 641 642 return ctx 643} 644 645func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) { 646 t.Helper() 647 mod := ctx.ModuleForTests(moduleName, variant) 648 outputFiles := mod.OutputFiles(t, "") 649 if len(outputFiles) != 1 { 650 t.Errorf("%q must have single output\n", moduleName) 651 return 652 } 653 snapshotPath := filepath.Join(subDir, snapshotFilename) 654 655 if include { 656 out := singleton.Output(snapshotPath) 657 if fake { 658 if out.Rule == nil { 659 t.Errorf("Missing rule for module %q output file %q", moduleName, outputFiles[0]) 660 } 661 } else { 662 if out.Input.String() != outputFiles[0].String() { 663 t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0]) 664 } 665 } 666 } else { 667 out := singleton.MaybeOutput(snapshotPath) 668 if out.Rule != nil { 669 t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0]) 670 } 671 } 672} 673 674func CheckSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) { 675 t.Helper() 676 checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, false) 677} 678 679func CheckSnapshotExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) { 680 t.Helper() 681 checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, false, false) 682} 683 684func CheckSnapshotRule(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) { 685 t.Helper() 686 checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true) 687} 688 689func AssertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) { 690 t.Helper() 691 m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface) 692 if m.ExcludeFromVendorSnapshot() != expected { 693 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected) 694 } 695} 696 697func GetOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) { 698 for _, moduleName := range moduleNames { 699 module := ctx.ModuleForTests(moduleName, variant).Module().(*Module) 700 output := module.outputFile.Path().RelativeToTop() 701 paths = append(paths, output) 702 } 703 return paths 704} 705 706func AssertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) { 707 t.Helper() 708 m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface) 709 if m.ExcludeFromRecoverySnapshot() != expected { 710 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected) 711 } 712} 713