blob: e61c719f46875386acca28a9fda8f203e1b97c1d [file] [log] [blame]
Dan Willemsenb0552672019-01-25 16:04:11 -08001// 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
Jaewoong Jungfccad6b2020-06-01 10:45:49 -070015package sh
Dan Willemsenb0552672019-01-25 16:04:11 -080016
17import (
18 "fmt"
Colin Cross7c7c1142019-07-29 16:46:49 -070019 "path/filepath"
Jaewoong Jung7c3052a2020-05-29 16:15:32 -070020 "sort"
Julien Desprez9e7fc142019-03-08 11:07:05 -080021 "strings"
Jaewoong Jungfccad6b2020-06-01 10:45:49 -070022
Jaewoong Jung7c3052a2020-05-29 16:15:32 -070023 "github.com/google/blueprint"
Jaewoong Jungfccad6b2020-06-01 10:45:49 -070024 "github.com/google/blueprint/proptools"
25
26 "android/soong/android"
Jaewoong Jung7c3052a2020-05-29 16:15:32 -070027 "android/soong/cc"
frankfengd17bc612020-06-03 10:28:47 -070028 "android/soong/tradefed"
Dan Willemsenb0552672019-01-25 16:04:11 -080029)
30
31// sh_binary is for shell scripts (and batch files) that are installed as
32// executable files into .../bin/
33//
34// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
35// instead.
36
Jaewoong Jungfccad6b2020-06-01 10:45:49 -070037var pctx = android.NewPackageContext("android/soong/sh")
38
Dan Willemsenb0552672019-01-25 16:04:11 -080039func init() {
Jaewoong Jungfccad6b2020-06-01 10:45:49 -070040 pctx.Import("android/soong/android")
41
42 android.RegisterModuleType("sh_binary", ShBinaryFactory)
43 android.RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
44 android.RegisterModuleType("sh_test", ShTestFactory)
45 android.RegisterModuleType("sh_test_host", ShTestHostFactory)
Dan Willemsenb0552672019-01-25 16:04:11 -080046}
47
48type shBinaryProperties struct {
49 // Source file of this prebuilt.
Colin Cross27b922f2019-03-04 22:35:41 -080050 Src *string `android:"path,arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080051
52 // optional subdirectory under which this file is installed into
53 Sub_dir *string `android:"arch_variant"`
54
55 // optional name for the installed file. If unspecified, name of the module is used as the file name
56 Filename *string `android:"arch_variant"`
57
58 // when set to true, and filename property is not set, the name for the installed file
59 // is the same as the file name of the source file.
60 Filename_from_src *bool `android:"arch_variant"`
61
62 // Whether this module is directly installable to one of the partitions. Default: true.
63 Installable *bool
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -070064
65 // install symlinks to the binary
66 Symlinks []string `android:"arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080067}
68
Julien Desprez9e7fc142019-03-08 11:07:05 -080069type TestProperties struct {
70 // list of compatibility suites (for example "cts", "vts") that the module should be
71 // installed into.
72 Test_suites []string `android:"arch_variant"`
73
74 // the name of the test configuration (for example "AndroidTest.xml") that should be
75 // installed with the module.
Colin Cross287638b2020-06-09 15:09:22 -070076 Test_config *string `android:"path,arch_variant"`
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070077
78 // list of files or filegroup modules that provide data that should be installed alongside
79 // the test.
80 Data []string `android:"path,arch_variant"`
frankfengd17bc612020-06-03 10:28:47 -070081
82 // Add RootTargetPreparer to auto generated test config. This guarantees the test to run
83 // with root permission.
84 Require_root *bool
85
86 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that
87 // should be installed with the module.
88 Test_config_template *string `android:"path,arch_variant"`
89
90 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
91 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
92 // explicitly.
93 Auto_gen_config *bool
Jaewoong Jung7c3052a2020-05-29 16:15:32 -070094
95 // list of binary modules that should be installed alongside the test
96 Data_bins []string `android:"path,arch_variant"`
97
98 // list of library modules that should be installed alongside the test
99 Data_libs []string `android:"path,arch_variant"`
100
101 // list of device binary modules that should be installed alongside the test.
102 // Only available for host sh_test modules.
103 Data_device_bins []string `android:"path,arch_variant"`
104
105 // list of device library modules that should be installed alongside the test.
106 // Only available for host sh_test modules.
107 Data_device_libs []string `android:"path,arch_variant"`
Julien Desprez9e7fc142019-03-08 11:07:05 -0800108}
109
Dan Willemsenb0552672019-01-25 16:04:11 -0800110type ShBinary struct {
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700111 android.ModuleBase
Dan Willemsenb0552672019-01-25 16:04:11 -0800112
113 properties shBinaryProperties
114
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700115 sourceFilePath android.Path
116 outputFilePath android.OutputPath
117 installedFile android.InstallPath
Dan Willemsenb0552672019-01-25 16:04:11 -0800118}
119
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700120var _ android.HostToolProvider = (*ShBinary)(nil)
Colin Cross7c7c1142019-07-29 16:46:49 -0700121
Julien Desprez9e7fc142019-03-08 11:07:05 -0800122type ShTest struct {
123 ShBinary
124
125 testProperties TestProperties
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700126
frankfengd17bc612020-06-03 10:28:47 -0700127 data android.Paths
128 testConfig android.Path
Jaewoong Jung7c3052a2020-05-29 16:15:32 -0700129
130 dataModules map[string]android.Path
Julien Desprez9e7fc142019-03-08 11:07:05 -0800131}
132
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700133func (s *ShBinary) HostToolPath() android.OptionalPath {
134 return android.OptionalPathForPath(s.installedFile)
Colin Cross7c7c1142019-07-29 16:46:49 -0700135}
136
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700137func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
Dan Willemsenb0552672019-01-25 16:04:11 -0800138 if s.properties.Src == nil {
139 ctx.PropertyErrorf("src", "missing prebuilt source file")
140 }
Dan Willemsenb0552672019-01-25 16:04:11 -0800141}
142
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700143func (s *ShBinary) OutputFile() android.OutputPath {
Dan Willemsenb0552672019-01-25 16:04:11 -0800144 return s.outputFilePath
145}
146
147func (s *ShBinary) SubDir() string {
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700148 return proptools.String(s.properties.Sub_dir)
Dan Willemsenb0552672019-01-25 16:04:11 -0800149}
150
151func (s *ShBinary) Installable() bool {
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700152 return s.properties.Installable == nil || proptools.Bool(s.properties.Installable)
Dan Willemsenb0552672019-01-25 16:04:11 -0800153}
154
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -0700155func (s *ShBinary) Symlinks() []string {
156 return s.properties.Symlinks
157}
158
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700159func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) {
160 s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src))
161 filename := proptools.String(s.properties.Filename)
162 filename_from_src := proptools.Bool(s.properties.Filename_from_src)
Dan Willemsenb0552672019-01-25 16:04:11 -0800163 if filename == "" {
164 if filename_from_src {
165 filename = s.sourceFilePath.Base()
166 } else {
167 filename = ctx.ModuleName()
168 }
169 } else if filename_from_src {
170 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
171 return
172 }
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700173 s.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
Dan Willemsenb0552672019-01-25 16:04:11 -0800174
175 // This ensures that outputFilePath has the correct name for others to
176 // use, as the source file may have a different name.
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700177 ctx.Build(pctx, android.BuildParams{
178 Rule: android.CpExecutable,
Dan Willemsenb0552672019-01-25 16:04:11 -0800179 Output: s.outputFilePath,
180 Input: s.sourceFilePath,
181 })
182}
183
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700184func (s *ShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross7c7c1142019-07-29 16:46:49 -0700185 s.generateAndroidBuildActions(ctx)
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700186 installDir := android.PathForModuleInstall(ctx, "bin", proptools.String(s.properties.Sub_dir))
Colin Cross7c7c1142019-07-29 16:46:49 -0700187 s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
188}
189
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700190func (s *ShBinary) AndroidMkEntries() []android.AndroidMkEntries {
191 return []android.AndroidMkEntries{android.AndroidMkEntries{
Dan Willemsenb0552672019-01-25 16:04:11 -0800192 Class: "EXECUTABLES",
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700193 OutputFile: android.OptionalPathForPath(s.outputFilePath),
Dan Willemsenb0552672019-01-25 16:04:11 -0800194 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700195 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
196 func(entries *android.AndroidMkEntries) {
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700197 s.customAndroidMkEntries(entries)
198 },
Dan Willemsenb0552672019-01-25 16:04:11 -0800199 },
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900200 }}
Dan Willemsenb0552672019-01-25 16:04:11 -0800201}
202
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700203func (s *ShBinary) customAndroidMkEntries(entries *android.AndroidMkEntries) {
204 entries.SetString("LOCAL_MODULE_RELATIVE_PATH", proptools.String(s.properties.Sub_dir))
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700205 entries.SetString("LOCAL_MODULE_SUFFIX", "")
206 entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -0700207 if len(s.properties.Symlinks) > 0 {
208 entries.SetString("LOCAL_MODULE_SYMLINKS", strings.Join(s.properties.Symlinks, " "))
209 }
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700210}
211
Jaewoong Jung7c3052a2020-05-29 16:15:32 -0700212type dependencyTag struct {
213 blueprint.BaseDependencyTag
214 name string
215}
216
217var (
218 shTestDataBinsTag = dependencyTag{name: "dataBins"}
219 shTestDataLibsTag = dependencyTag{name: "dataLibs"}
220 shTestDataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
221 shTestDataDeviceLibsTag = dependencyTag{name: "dataDeviceLibs"}
222)
223
224var sharedLibVariations = []blueprint.Variation{{Mutator: "link", Variation: "shared"}}
225
226func (s *ShTest) DepsMutator(ctx android.BottomUpMutatorContext) {
227 s.ShBinary.DepsMutator(ctx)
228
229 ctx.AddFarVariationDependencies(ctx.Target().Variations(), shTestDataBinsTag, s.testProperties.Data_bins...)
230 ctx.AddFarVariationDependencies(append(ctx.Target().Variations(), sharedLibVariations...),
231 shTestDataLibsTag, s.testProperties.Data_libs...)
232 if ctx.Target().Os.Class == android.Host && len(ctx.Config().Targets[android.Android]) > 0 {
233 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
234 ctx.AddFarVariationDependencies(deviceVariations, shTestDataDeviceBinsTag, s.testProperties.Data_device_bins...)
235 ctx.AddFarVariationDependencies(append(deviceVariations, sharedLibVariations...),
236 shTestDataDeviceLibsTag, s.testProperties.Data_device_libs...)
237 } else if ctx.Target().Os.Class != android.Host {
238 if len(s.testProperties.Data_device_bins) > 0 {
239 ctx.PropertyErrorf("data_device_bins", "only available for host modules")
240 }
241 if len(s.testProperties.Data_device_libs) > 0 {
242 ctx.PropertyErrorf("data_device_libs", "only available for host modules")
243 }
244 }
245}
246
247func (s *ShTest) addToDataModules(ctx android.ModuleContext, relPath string, path android.Path) {
248 if _, exists := s.dataModules[relPath]; exists {
249 ctx.ModuleErrorf("data modules have a conflicting installation path, %v - %s, %s",
250 relPath, s.dataModules[relPath].String(), path.String())
251 return
252 }
253 s.dataModules[relPath] = path
254}
255
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700256func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross7c7c1142019-07-29 16:46:49 -0700257 s.ShBinary.generateAndroidBuildActions(ctx)
258 testDir := "nativetest"
259 if ctx.Target().Arch.ArchType.Multilib == "lib64" {
260 testDir = "nativetest64"
261 }
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700262 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
Colin Cross7c7c1142019-07-29 16:46:49 -0700263 testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath)
264 } else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
265 testDir = filepath.Join(testDir, ctx.Arch().ArchType.String())
266 }
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700267 installDir := android.PathForModuleInstall(ctx, testDir, proptools.String(s.properties.Sub_dir))
Colin Cross7c7c1142019-07-29 16:46:49 -0700268 s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700269
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700270 s.data = android.PathsForModuleSrc(ctx, s.testProperties.Data)
frankfengd17bc612020-06-03 10:28:47 -0700271
272 var configs []tradefed.Config
273 if Bool(s.testProperties.Require_root) {
274 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
275 } else {
276 options := []tradefed.Option{{Name: "force-root", Value: "false"}}
277 configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
278 }
279 s.testConfig = tradefed.AutoGenShellTestConfig(ctx, s.testProperties.Test_config,
280 s.testProperties.Test_config_template, s.testProperties.Test_suites, configs, s.testProperties.Auto_gen_config, s.outputFilePath.Base())
Jaewoong Jung7c3052a2020-05-29 16:15:32 -0700281
282 s.dataModules = make(map[string]android.Path)
283 ctx.VisitDirectDeps(func(dep android.Module) {
284 depTag := ctx.OtherModuleDependencyTag(dep)
285 switch depTag {
286 case shTestDataBinsTag, shTestDataDeviceBinsTag:
287 if cc, isCc := dep.(*cc.Module); isCc {
288 s.addToDataModules(ctx, cc.OutputFile().Path().Base(), cc.OutputFile().Path())
289 return
290 }
291 property := "data_bins"
292 if depTag == shTestDataDeviceBinsTag {
293 property = "data_device_bins"
294 }
295 ctx.PropertyErrorf(property, "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
296 case shTestDataLibsTag, shTestDataDeviceLibsTag:
297 if cc, isCc := dep.(*cc.Module); isCc {
298 // Copy to an intermediate output directory to append "lib[64]" to the path,
299 // so that it's compatible with the default rpath values.
300 var relPath string
301 if cc.Arch().ArchType.Multilib == "lib64" {
302 relPath = filepath.Join("lib64", cc.OutputFile().Path().Base())
303 } else {
304 relPath = filepath.Join("lib", cc.OutputFile().Path().Base())
305 }
306 if _, exist := s.dataModules[relPath]; exist {
307 return
308 }
309 relocatedLib := android.PathForModuleOut(ctx, "relocated", relPath)
310 ctx.Build(pctx, android.BuildParams{
311 Rule: android.Cp,
312 Input: cc.OutputFile().Path(),
313 Output: relocatedLib,
314 })
315 s.addToDataModules(ctx, relPath, relocatedLib)
316 return
317 }
318 property := "data_libs"
319 if depTag == shTestDataDeviceBinsTag {
320 property = "data_device_libs"
321 }
322 ctx.PropertyErrorf(property, "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep))
323 }
324 })
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700325}
326
Colin Cross7c7c1142019-07-29 16:46:49 -0700327func (s *ShTest) InstallInData() bool {
328 return true
329}
330
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700331func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries {
332 return []android.AndroidMkEntries{android.AndroidMkEntries{
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700333 Class: "NATIVE_TESTS",
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700334 OutputFile: android.OptionalPathForPath(s.outputFilePath),
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700335 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700336 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
337 func(entries *android.AndroidMkEntries) {
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700338 s.customAndroidMkEntries(entries)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700339
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700340 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
Colin Cross287638b2020-06-09 15:09:22 -0700341 if s.testConfig != nil {
342 entries.SetPath("LOCAL_FULL_TEST_CONFIG", s.testConfig)
frankfengd17bc612020-06-03 10:28:47 -0700343 }
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700344 for _, d := range s.data {
345 rel := d.Rel()
346 path := d.String()
347 if !strings.HasSuffix(path, rel) {
348 panic(fmt.Errorf("path %q does not end with %q", path, rel))
349 }
350 path = strings.TrimSuffix(path, rel)
351 entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700352 }
Jaewoong Jung7c3052a2020-05-29 16:15:32 -0700353 relPaths := make([]string, 0)
354 for relPath, _ := range s.dataModules {
355 relPaths = append(relPaths, relPath)
356 }
357 sort.Strings(relPaths)
358 for _, relPath := range relPaths {
359 dir := strings.TrimSuffix(s.dataModules[relPath].String(), relPath)
360 entries.AddStrings("LOCAL_TEST_DATA", dir+":"+relPath)
361 }
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700362 },
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700363 },
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900364 }}
Julien Desprez9e7fc142019-03-08 11:07:05 -0800365}
366
Dan Willemsenb0552672019-01-25 16:04:11 -0800367func InitShBinaryModule(s *ShBinary) {
368 s.AddProperties(&s.properties)
369}
370
Patrice Arrudae1034192019-03-11 13:20:17 -0700371// sh_binary is for a shell script or batch file to be installed as an
372// executable binary to <partition>/bin.
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700373func ShBinaryFactory() android.Module {
Dan Willemsenb0552672019-01-25 16:04:11 -0800374 module := &ShBinary{}
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700375 module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
376 return class == android.Device && ctx.Config().DevicePrefer32BitExecutables()
Jiyong Park6ac3cac2019-11-19 12:57:57 +0900377 })
Dan Willemsenb0552672019-01-25 16:04:11 -0800378 InitShBinaryModule(module)
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700379 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst)
Dan Willemsenb0552672019-01-25 16:04:11 -0800380 return module
381}
382
Patrice Arrudae1034192019-03-11 13:20:17 -0700383// sh_binary_host is for a shell script to be installed as an executable binary
384// to $(HOST_OUT)/bin.
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700385func ShBinaryHostFactory() android.Module {
Dan Willemsenb0552672019-01-25 16:04:11 -0800386 module := &ShBinary{}
387 InitShBinaryModule(module)
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700388 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
Dan Willemsenb0552672019-01-25 16:04:11 -0800389 return module
390}
Julien Desprez9e7fc142019-03-08 11:07:05 -0800391
Jaewoong Jung61a83682019-07-01 09:08:50 -0700392// sh_test defines a shell script based test module.
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700393func ShTestFactory() android.Module {
Julien Desprez9e7fc142019-03-08 11:07:05 -0800394 module := &ShTest{}
395 InitShBinaryModule(&module.ShBinary)
396 module.AddProperties(&module.testProperties)
397
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700398 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst)
Julien Desprez9e7fc142019-03-08 11:07:05 -0800399 return module
400}
Jaewoong Jung61a83682019-07-01 09:08:50 -0700401
402// sh_test_host defines a shell script based test module that runs on a host.
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700403func ShTestHostFactory() android.Module {
Jaewoong Jung61a83682019-07-01 09:08:50 -0700404 module := &ShTest{}
405 InitShBinaryModule(&module.ShBinary)
406 module.AddProperties(&module.testProperties)
407
Jaewoong Jungfccad6b2020-06-01 10:45:49 -0700408 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
Jaewoong Jung61a83682019-07-01 09:08:50 -0700409 return module
410}
frankfengd17bc612020-06-03 10:28:47 -0700411
412var Bool = proptools.Bool