1// Copyright 2019 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package sh 16 17import ( 18 "fmt" 19 "path/filepath" 20 "strings" 21 22 "github.com/google/blueprint" 23 "github.com/google/blueprint/proptools" 24 25 "android/soong/android" 26 "android/soong/cc" 27 "android/soong/tradefed" 28) 29 30// sh_binary is for shell scripts (and batch files) that are installed as 31// executable files into .../bin/ 32// 33// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary 34// instead. 35 36var pctx = android.NewPackageContext("android/soong/sh") 37 38func init() { 39 pctx.Import("android/soong/android") 40 41 registerShBuildComponents(android.InitRegistrationContext) 42} 43 44type ShBinaryInfo struct { 45 SubDir string 46 OutputFile android.Path 47 Symlinks []string 48} 49 50var ShBinaryInfoProvider = blueprint.NewProvider[ShBinaryInfo]() 51 52func registerShBuildComponents(ctx android.RegistrationContext) { 53 ctx.RegisterModuleType("sh_binary", ShBinaryFactory) 54 ctx.RegisterModuleType("sh_binary_host", ShBinaryHostFactory) 55 ctx.RegisterModuleType("sh_test", ShTestFactory) 56 ctx.RegisterModuleType("sh_test_host", ShTestHostFactory) 57 ctx.RegisterModuleType("sh_defaults", ShDefaultsFactory) 58} 59 60// Test fixture preparer that will register most sh build components. 61// 62// Singletons and mutators should only be added here if they are needed for a majority of sh 63// module types, otherwise they should be added under a separate preparer to allow them to be 64// selected only when needed to reduce test execution time. 65// 66// Module types do not have much of an overhead unless they are used so this should include as many 67// module types as possible. The exceptions are those module types that require mutators and/or 68// singletons in order to function in which case they should be kept together in a separate 69// preparer. 70var PrepareForTestWithShBuildComponents = android.GroupFixturePreparers( 71 android.FixtureRegisterWithContext(registerShBuildComponents), 72) 73 74type shBinaryProperties struct { 75 // Source file of this prebuilt. 76 Src *string `android:"path,arch_variant"` 77 78 // optional subdirectory under which this file is installed into 79 Sub_dir *string `android:"arch_variant"` 80 81 // optional name for the installed file. If unspecified, name of the module is used as the file name 82 Filename *string `android:"arch_variant"` 83 84 // when set to true, and filename property is not set, the name for the installed file 85 // is the same as the file name of the source file. 86 Filename_from_src *bool `android:"arch_variant"` 87 88 // Whether this module is directly installable to one of the partitions. Default: true. 89 Installable *bool 90 91 // install symlinks to the binary 92 Symlinks []string `android:"arch_variant"` 93 94 // Make this module available when building for ramdisk. 95 // On device without a dedicated recovery partition, the module is only 96 // available after switching root into 97 // /first_stage_ramdisk. To expose the module before switching root, install 98 // the recovery variant instead. 99 Ramdisk_available *bool 100 101 // Make this module available when building for vendor ramdisk. 102 // On device without a dedicated recovery partition, the module is only 103 // available after switching root into 104 // /first_stage_ramdisk. To expose the module before switching root, install 105 // the recovery variant instead. 106 Vendor_ramdisk_available *bool 107 108 // Make this module available when building for recovery. 109 Recovery_available *bool 110 111 // The name of the image this module is built for 112 ImageVariation string `blueprint:"mutated"` 113 114 // Suffix for the name of Android.mk entries generated by this module 115 SubName string `blueprint:"mutated"` 116} 117 118type TestProperties struct { 119 // list of compatibility suites (for example "cts", "vts") that the module should be 120 // installed into. 121 Test_suites []string `android:"arch_variant"` 122 123 // the name of the test configuration (for example "AndroidTest.xml") that should be 124 // installed with the module. 125 Test_config *string `android:"path,arch_variant"` 126 127 // list of files or filegroup modules that provide data that should be installed alongside 128 // the test. 129 Data []string `android:"path,arch_variant"` 130 131 // same as data, but adds dependencies using the device's os variation and the common 132 // architecture's variation. Can be used to add a module built for device to the data of a 133 // host test. 134 Device_common_data []string `android:"path_device_common"` 135 136 // same as data, but adds dependencies using the device's os variation and the device's first 137 // architecture's variation. Can be used to add a module built for device to the data of a 138 // host test. 139 Device_first_data []string `android:"path_device_first"` 140 141 // Same as data, but will add dependencies on modules using the host's os variation and 142 // the common arch variation. Useful for a device test that wants to depend on a host 143 // module, for example to include a custom Tradefed test runner. 144 Host_common_data []string `android:"path_host_common"` 145 146 // Add RootTargetPreparer to auto generated test config. This guarantees the test to run 147 // with root permission. 148 Require_root *bool 149 150 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 151 // should be installed with the module. 152 Test_config_template *string `android:"path,arch_variant"` 153 154 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 155 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 156 // explicitly. 157 Auto_gen_config *bool 158 159 // list of binary modules that should be installed alongside the test 160 Data_bins []string `android:"path,arch_variant"` 161 162 // list of library modules that should be installed alongside the test 163 Data_libs []string `android:"path,arch_variant"` 164 165 // list of device binary modules that should be installed alongside the test. 166 // Only available for host sh_test modules. 167 Data_device_bins []string `android:"path,arch_variant"` 168 169 // list of device library modules that should be installed alongside the test. 170 // Only available for host sh_test modules. 171 Data_device_libs []string `android:"path,arch_variant"` 172 173 // list of java modules that provide data that should be installed alongside the test. 174 Java_data []string 175 176 // Install the test into a folder named for the module in all test suites. 177 Per_testcase_directory *bool 178 179 // Test options. 180 Test_options android.CommonTestOptions 181 182 // a list of extra test configuration files that should be installed with the module. 183 Extra_test_configs []string `android:"path,arch_variant"` 184} 185 186type ShBinary struct { 187 android.ModuleBase 188 android.DefaultableModuleBase 189 190 properties shBinaryProperties 191 192 sourceFilePath android.Path 193 outputFilePath android.OutputPath 194 installedFile android.InstallPath 195} 196 197var _ android.HostToolProvider = (*ShBinary)(nil) 198 199type ShTest struct { 200 ShBinary 201 202 testProperties TestProperties 203 204 installDir android.InstallPath 205 206 data []android.DataPath 207 testConfig android.Path 208 extraTestConfigs android.Paths 209 210 dataModules map[string]android.Path 211} 212 213func (s *ShBinary) HostToolPath() android.OptionalPath { 214 return android.OptionalPathForPath(s.installedFile) 215} 216 217func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) { 218} 219 220func (s *ShBinary) OutputFile() android.Path { 221 return s.outputFilePath 222} 223 224func (s *ShBinary) SubDir() string { 225 return proptools.String(s.properties.Sub_dir) 226} 227 228func (s *ShBinary) RelativeInstallPath() string { 229 return s.SubDir() 230} 231func (s *ShBinary) Installable() bool { 232 return s.properties.Installable == nil || proptools.Bool(s.properties.Installable) 233} 234 235func (s *ShBinary) Symlinks() []string { 236 return s.properties.Symlinks 237} 238 239var _ android.ImageInterface = (*ShBinary)(nil) 240 241func (s *ShBinary) ImageMutatorBegin(ctx android.ImageInterfaceContext) {} 242 243func (s *ShBinary) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool { 244 return s.InstallInVendor() 245} 246 247func (s *ShBinary) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool { 248 return s.InstallInProduct() 249} 250 251func (s *ShBinary) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool { 252 return !s.InstallInRecovery() && !s.InstallInRamdisk() && !s.InstallInVendorRamdisk() && !s.ModuleBase.InstallInVendor() 253} 254 255func (s *ShBinary) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool { 256 return proptools.Bool(s.properties.Ramdisk_available) || s.InstallInRamdisk() 257} 258 259func (s *ShBinary) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool { 260 return proptools.Bool(s.properties.Vendor_ramdisk_available) || s.InstallInVendorRamdisk() 261} 262 263func (s *ShBinary) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool { 264 return false 265} 266 267func (s *ShBinary) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool { 268 return proptools.Bool(s.properties.Recovery_available) || s.InstallInRecovery() 269} 270 271func (s *ShBinary) ExtraImageVariations(ctx android.ImageInterfaceContext) []string { 272 return nil 273} 274 275func (s *ShBinary) SetImageVariation(ctx android.ImageInterfaceContext, variation string) { 276 s.properties.ImageVariation = variation 277} 278 279// Overrides ModuleBase.InstallInRamdisk() so that the install rule respects 280// Ramdisk_available property for ramdisk variant 281func (s *ShBinary) InstallInRamdisk() bool { 282 return s.ModuleBase.InstallInRamdisk() || 283 (proptools.Bool(s.properties.Ramdisk_available) && s.properties.ImageVariation == android.RamdiskVariation) 284} 285 286// Overrides ModuleBase.InstallInVendorRamdisk() so that the install rule respects 287// Vendor_ramdisk_available property for vendor ramdisk variant 288func (s *ShBinary) InstallInVendorRamdisk() bool { 289 return s.ModuleBase.InstallInVendorRamdisk() || 290 (proptools.Bool(s.properties.Vendor_ramdisk_available) && s.properties.ImageVariation == android.VendorRamdiskVariation) 291} 292 293// Overrides ModuleBase.InstallInRecovery() so that the install rule respects 294// Recovery_available property for recovery variant 295func (s *ShBinary) InstallInRecovery() bool { 296 return s.ModuleBase.InstallInRecovery() || 297 (proptools.Bool(s.properties.Recovery_available) && s.properties.ImageVariation == android.RecoveryVariation) 298} 299 300func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) { 301 if s.properties.Src == nil { 302 ctx.PropertyErrorf("src", "missing prebuilt source file") 303 } 304 305 s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src)) 306 filename := proptools.String(s.properties.Filename) 307 filenameFromSrc := proptools.Bool(s.properties.Filename_from_src) 308 if filename == "" { 309 if filenameFromSrc { 310 filename = s.sourceFilePath.Base() 311 } else { 312 filename = ctx.ModuleName() 313 } 314 } else if filenameFromSrc { 315 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true") 316 return 317 } 318 s.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath 319 320 // This ensures that outputFilePath has the correct name for others to 321 // use, as the source file may have a different name. 322 ctx.Build(pctx, android.BuildParams{ 323 Rule: android.CpExecutable, 324 Output: s.outputFilePath, 325 Input: s.sourceFilePath, 326 }) 327 328 s.properties.SubName = s.GetSubname(ctx) 329 330 android.SetProvider(ctx, ShBinaryInfoProvider, ShBinaryInfo{ 331 SubDir: s.SubDir(), 332 OutputFile: s.OutputFile(), 333 Symlinks: s.Symlinks(), 334 }) 335 336 ctx.SetOutputFiles(android.Paths{s.outputFilePath}, "") 337} 338 339func (s *ShBinary) GetSubname(ctx android.ModuleContext) string { 340 ret := "" 341 if s.properties.ImageVariation != "" { 342 if s.properties.ImageVariation != android.VendorVariation { 343 ret = "." + s.properties.ImageVariation 344 } 345 } 346 return ret 347} 348 349func (s *ShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 350 s.generateAndroidBuildActions(ctx) 351 installDir := android.PathForModuleInstall(ctx, "bin", proptools.String(s.properties.Sub_dir)) 352 if !s.Installable() { 353 s.SkipInstall() 354 } 355 s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath) 356 for _, symlink := range s.Symlinks() { 357 ctx.InstallSymlink(installDir, symlink, s.installedFile) 358 } 359 moduleInfoJSON := ctx.ModuleInfoJSON() 360 moduleInfoJSON.Class = []string{"EXECUTABLES"} 361} 362 363func (s *ShBinary) AndroidMkEntries() []android.AndroidMkEntries { 364 return []android.AndroidMkEntries{{ 365 Class: "EXECUTABLES", 366 OutputFile: android.OptionalPathForPath(s.outputFilePath), 367 Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", 368 ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 369 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 370 s.customAndroidMkEntries(entries) 371 entries.SetString("LOCAL_MODULE_RELATIVE_PATH", proptools.String(s.properties.Sub_dir)) 372 entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !s.Installable()) 373 }, 374 }, 375 SubName: s.properties.SubName, 376 }} 377} 378 379func (s *ShBinary) customAndroidMkEntries(entries *android.AndroidMkEntries) { 380 entries.SetString("LOCAL_MODULE_SUFFIX", "") 381 entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel()) 382 if len(s.properties.Symlinks) > 0 { 383 entries.SetString("LOCAL_MODULE_SYMLINKS", strings.Join(s.properties.Symlinks, " ")) 384 } 385} 386 387type dependencyTag struct { 388 blueprint.BaseDependencyTag 389 name string 390} 391 392var ( 393 shTestDataBinsTag = dependencyTag{name: "dataBins"} 394 shTestDataLibsTag = dependencyTag{name: "dataLibs"} 395 shTestDataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} 396 shTestDataDeviceLibsTag = dependencyTag{name: "dataDeviceLibs"} 397 shTestJavaDataTag = dependencyTag{name: "javaData"} 398) 399 400var sharedLibVariations = []blueprint.Variation{{Mutator: "link", Variation: "shared"}} 401 402func (s *ShTest) DepsMutator(ctx android.BottomUpMutatorContext) { 403 s.ShBinary.DepsMutator(ctx) 404 405 ctx.AddFarVariationDependencies(ctx.Target().Variations(), shTestDataBinsTag, s.testProperties.Data_bins...) 406 ctx.AddFarVariationDependencies(append(ctx.Target().Variations(), sharedLibVariations...), 407 shTestDataLibsTag, s.testProperties.Data_libs...) 408 if ctx.Target().Os.Class == android.Host && len(ctx.Config().Targets[android.Android]) > 0 { 409 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() 410 ctx.AddFarVariationDependencies(deviceVariations, shTestDataDeviceBinsTag, s.testProperties.Data_device_bins...) 411 ctx.AddFarVariationDependencies(append(deviceVariations, sharedLibVariations...), 412 shTestDataDeviceLibsTag, s.testProperties.Data_device_libs...) 413 414 javaDataVariation := []blueprint.Variation{{"arch", android.Common.String()}} 415 ctx.AddVariationDependencies(javaDataVariation, shTestJavaDataTag, s.testProperties.Java_data...) 416 417 } else if ctx.Target().Os.Class != android.Host { 418 if len(s.testProperties.Data_device_bins) > 0 { 419 ctx.PropertyErrorf("data_device_bins", "only available for host modules") 420 } 421 if len(s.testProperties.Data_device_libs) > 0 { 422 ctx.PropertyErrorf("data_device_libs", "only available for host modules") 423 } 424 if len(s.testProperties.Java_data) > 0 { 425 ctx.PropertyErrorf("Java_data", "only available for host modules") 426 } 427 } 428} 429 430func (s *ShTest) addToDataModules(ctx android.ModuleContext, relPath string, path android.Path) { 431 if _, exists := s.dataModules[relPath]; exists { 432 ctx.ModuleErrorf("data modules have a conflicting installation path, %v - %s, %s", 433 relPath, s.dataModules[relPath].String(), path.String()) 434 return 435 } 436 s.dataModules[relPath] = path 437 s.data = append(s.data, android.DataPath{SrcPath: path}) 438} 439 440func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { 441 s.ShBinary.generateAndroidBuildActions(ctx) 442 443 expandedData := android.PathsForModuleSrc(ctx, s.testProperties.Data) 444 expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_common_data)...) 445 expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_first_data)...) 446 expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Host_common_data)...) 447 // Emulate the data property for java_data dependencies. 448 for _, javaData := range ctx.GetDirectDepsProxyWithTag(shTestJavaDataTag) { 449 expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...) 450 } 451 for _, d := range expandedData { 452 s.data = append(s.data, android.DataPath{SrcPath: d}) 453 } 454 455 testDir := "nativetest" 456 if ctx.Target().Arch.ArchType.Multilib == "lib64" { 457 testDir = "nativetest64" 458 } 459 if ctx.Target().NativeBridge == android.NativeBridgeEnabled { 460 testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath) 461 } else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) { 462 testDir = filepath.Join(testDir, ctx.Arch().ArchType.String()) 463 } 464 if s.SubDir() != "" { 465 // Don't add the module name to the installation path if sub_dir is specified for backward 466 // compatibility. 467 s.installDir = android.PathForModuleInstall(ctx, testDir, s.SubDir()) 468 } else { 469 s.installDir = android.PathForModuleInstall(ctx, testDir, s.Name()) 470 } 471 472 var configs []tradefed.Config 473 if Bool(s.testProperties.Require_root) { 474 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil}) 475 } else { 476 options := []tradefed.Option{{Name: "force-root", Value: "false"}} 477 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options}) 478 } 479 if len(s.testProperties.Data_device_bins) > 0 { 480 moduleName := s.Name() 481 remoteDir := "/data/local/tests/unrestricted/" + moduleName + "/" 482 options := []tradefed.Option{{Name: "cleanup", Value: "true"}} 483 for _, bin := range s.testProperties.Data_device_bins { 484 options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: remoteDir + bin}) 485 } 486 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options}) 487 } 488 s.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ 489 TestConfigProp: s.testProperties.Test_config, 490 TestConfigTemplateProp: s.testProperties.Test_config_template, 491 TestSuites: s.testProperties.Test_suites, 492 Config: configs, 493 AutoGenConfig: s.testProperties.Auto_gen_config, 494 OutputFileName: s.outputFilePath.Base(), 495 DeviceTemplate: "${ShellTestConfigTemplate}", 496 HostTemplate: "${ShellTestConfigTemplate}", 497 }) 498 499 s.extraTestConfigs = android.PathsForModuleSrc(ctx, s.testProperties.Extra_test_configs) 500 s.dataModules = make(map[string]android.Path) 501 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { 502 depTag := ctx.OtherModuleDependencyTag(dep) 503 switch depTag { 504 case shTestDataBinsTag, shTestDataDeviceBinsTag: 505 path := android.OutputFileForModule(ctx, dep, "") 506 s.addToDataModules(ctx, path.Base(), path) 507 case shTestDataLibsTag, shTestDataDeviceLibsTag: 508 if _, isCc := android.OtherModuleProvider(ctx, dep, cc.CcInfoProvider); isCc { 509 // Copy to an intermediate output directory to append "lib[64]" to the path, 510 // so that it's compatible with the default rpath values. 511 var relPath string 512 linkableInfo := android.OtherModuleProviderOrDefault(ctx, dep, cc.LinkableInfoProvider) 513 commonInfo := android.OtherModulePointerProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider) 514 515 if commonInfo.Target.Arch.ArchType.Multilib == "lib64" { 516 relPath = filepath.Join("lib64", linkableInfo.OutputFile.Path().Base()) 517 } else { 518 relPath = filepath.Join("lib", linkableInfo.OutputFile.Path().Base()) 519 } 520 if _, exist := s.dataModules[relPath]; exist { 521 return 522 } 523 relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath) 524 ctx.Build(pctx, android.BuildParams{ 525 Rule: android.Cp, 526 Input: linkableInfo.OutputFile.Path(), 527 Output: relocatedLib, 528 }) 529 s.addToDataModules(ctx, relPath, relocatedLib) 530 return 531 } 532 property := "data_libs" 533 if depTag == shTestDataDeviceBinsTag { 534 property = "data_device_libs" 535 } 536 ctx.PropertyErrorf(property, "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep)) 537 } 538 }) 539 540 installedData := ctx.InstallTestData(s.installDir, s.data) 541 s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath, installedData...) 542 543 mkEntries := s.AndroidMkEntries()[0] 544 android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{ 545 TestcaseRelDataFiles: addArch(ctx.Arch().ArchType.String(), installedData.Paths()), 546 OutputFile: s.outputFilePath, 547 TestConfig: s.testConfig, 548 TestSuites: s.testProperties.Test_suites, 549 IsHost: false, 550 IsUnitTest: Bool(s.testProperties.Test_options.Unit_test), 551 MkInclude: mkEntries.Include, 552 MkAppClass: mkEntries.Class, 553 InstallDir: s.installDir, 554 }) 555 556 moduleInfoJSON := ctx.ModuleInfoJSON() 557 moduleInfoJSON.Class = []string{"NATIVE_TESTS"} 558 if len(s.testProperties.Test_suites) > 0 { 559 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, s.testProperties.Test_suites...) 560 } else { 561 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "null-suite") 562 } 563 if proptools.Bool(s.testProperties.Test_options.Unit_test) { 564 moduleInfoJSON.IsUnitTest = "true" 565 if ctx.Host() { 566 moduleInfoJSON.CompatibilitySuites = append(moduleInfoJSON.CompatibilitySuites, "host-unit-tests") 567 } 568 } 569 moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, s.testProperties.Data_bins...) 570 if s.testConfig != nil { 571 if _, ok := s.testConfig.(android.WritablePath); ok { 572 moduleInfoJSON.AutoTestConfig = []string{"true"} 573 } 574 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.testConfig.String()) 575 } 576 moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, s.extraTestConfigs.Strings()...) 577 578 android.SetProvider(ctx, android.TestSuiteInfoProvider, android.TestSuiteInfo{ 579 TestSuites: s.testProperties.Test_suites, 580 }) 581} 582 583func addArch(archType string, paths android.Paths) []string { 584 archRelPaths := []string{} 585 for _, p := range paths { 586 archRelPaths = append(archRelPaths, fmt.Sprintf("%s/%s", archType, p.Rel())) 587 } 588 return archRelPaths 589} 590 591func (s *ShTest) InstallInData() bool { 592 return true 593} 594 595func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries { 596 return []android.AndroidMkEntries{android.AndroidMkEntries{ 597 Class: "NATIVE_TESTS", 598 OutputFile: android.OptionalPathForPath(s.outputFilePath), 599 Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", 600 ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 601 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 602 s.customAndroidMkEntries(entries) 603 entries.SetPath("LOCAL_MODULE_PATH", s.installDir) 604 entries.AddCompatibilityTestSuites(s.testProperties.Test_suites...) 605 if s.testConfig != nil { 606 entries.SetPath("LOCAL_FULL_TEST_CONFIG", s.testConfig) 607 } 608 if s.testProperties.Data_bins != nil { 609 entries.AddStrings("LOCAL_TEST_DATA_BINS", s.testProperties.Data_bins...) 610 } 611 entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(s.testProperties.Per_testcase_directory)) 612 if len(s.extraTestConfigs) > 0 { 613 entries.AddStrings("LOCAL_EXTRA_FULL_TEST_CONFIGS", s.extraTestConfigs.Strings()...) 614 } 615 616 entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !proptools.BoolDefault(s.testProperties.Auto_gen_config, true)) 617 618 s.testProperties.Test_options.SetAndroidMkEntries(entries) 619 }, 620 }, 621 }} 622} 623 624func initShBinaryModule(s *ShBinary) { 625 s.AddProperties(&s.properties) 626} 627 628// sh_binary is for a shell script or batch file to be installed as an 629// executable binary to <partition>/bin. 630func ShBinaryFactory() android.Module { 631 module := &ShBinary{} 632 initShBinaryModule(module) 633 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) 634 android.InitDefaultableModule(module) 635 return module 636} 637 638// sh_binary_host is for a shell script to be installed as an executable binary 639// to $(HOST_OUT)/bin. 640func ShBinaryHostFactory() android.Module { 641 module := &ShBinary{} 642 initShBinaryModule(module) 643 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) 644 android.InitDefaultableModule(module) 645 return module 646} 647 648// sh_test defines a shell script based test module. 649func ShTestFactory() android.Module { 650 module := &ShTest{} 651 initShBinaryModule(&module.ShBinary) 652 module.AddProperties(&module.testProperties) 653 654 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) 655 android.InitDefaultableModule(module) 656 return module 657} 658 659// sh_test_host defines a shell script based test module that runs on a host. 660func ShTestHostFactory() android.Module { 661 module := &ShTest{} 662 initShBinaryModule(&module.ShBinary) 663 module.AddProperties(&module.testProperties) 664 // Default sh_test_host to unit_tests = true 665 if module.testProperties.Test_options.Unit_test == nil { 666 module.testProperties.Test_options.Unit_test = proptools.BoolPtr(true) 667 } 668 669 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) 670 android.InitDefaultableModule(module) 671 return module 672} 673 674type ShDefaults struct { 675 android.ModuleBase 676 android.DefaultsModuleBase 677} 678 679func ShDefaultsFactory() android.Module { 680 module := &ShDefaults{} 681 682 module.AddProperties(&shBinaryProperties{}, &TestProperties{}) 683 android.InitDefaultsModule(module) 684 685 return module 686} 687 688var Bool = proptools.Bool 689