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