blob: 2b649c4a24fd65cdd58d1ed3e44f11cd7be8b8db [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
15package android
16
17import (
18 "fmt"
Julien Desprez9e7fc142019-03-08 11:07:05 -080019 "strings"
Dan Willemsenb0552672019-01-25 16:04:11 -080020)
21
22// sh_binary is for shell scripts (and batch files) that are installed as
23// executable files into .../bin/
24//
25// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
26// instead.
27
28func init() {
29 RegisterModuleType("sh_binary", ShBinaryFactory)
30 RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
Julien Desprez9e7fc142019-03-08 11:07:05 -080031 RegisterModuleType("sh_test", ShTestFactory)
Jaewoong Jung61a83682019-07-01 09:08:50 -070032 RegisterModuleType("sh_test_host", ShTestHostFactory)
Dan Willemsenb0552672019-01-25 16:04:11 -080033}
34
35type shBinaryProperties struct {
36 // Source file of this prebuilt.
Colin Cross27b922f2019-03-04 22:35:41 -080037 Src *string `android:"path,arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080038
39 // optional subdirectory under which this file is installed into
40 Sub_dir *string `android:"arch_variant"`
41
42 // optional name for the installed file. If unspecified, name of the module is used as the file name
43 Filename *string `android:"arch_variant"`
44
45 // when set to true, and filename property is not set, the name for the installed file
46 // is the same as the file name of the source file.
47 Filename_from_src *bool `android:"arch_variant"`
48
49 // Whether this module is directly installable to one of the partitions. Default: true.
50 Installable *bool
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -070051
52 // install symlinks to the binary
53 Symlinks []string `android:"arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080054}
55
Julien Desprez9e7fc142019-03-08 11:07:05 -080056type TestProperties struct {
57 // list of compatibility suites (for example "cts", "vts") that the module should be
58 // installed into.
59 Test_suites []string `android:"arch_variant"`
60
61 // the name of the test configuration (for example "AndroidTest.xml") that should be
62 // installed with the module.
63 Test_config *string `android:"arch_variant"`
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070064
65 // list of files or filegroup modules that provide data that should be installed alongside
66 // the test.
67 Data []string `android:"path,arch_variant"`
Julien Desprez9e7fc142019-03-08 11:07:05 -080068}
69
Dan Willemsenb0552672019-01-25 16:04:11 -080070type ShBinary struct {
71 ModuleBase
72
73 properties shBinaryProperties
74
75 sourceFilePath Path
76 outputFilePath OutputPath
77}
78
Julien Desprez9e7fc142019-03-08 11:07:05 -080079type ShTest struct {
80 ShBinary
81
82 testProperties TestProperties
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070083
84 data Paths
Julien Desprez9e7fc142019-03-08 11:07:05 -080085}
86
Dan Willemsenb0552672019-01-25 16:04:11 -080087func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
88 if s.properties.Src == nil {
89 ctx.PropertyErrorf("src", "missing prebuilt source file")
90 }
Dan Willemsenb0552672019-01-25 16:04:11 -080091}
92
93func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
Colin Cross8a497952019-03-05 22:25:09 -080094 return PathForModuleSrc(ctx, String(s.properties.Src))
Dan Willemsenb0552672019-01-25 16:04:11 -080095}
96
97func (s *ShBinary) OutputFile() OutputPath {
98 return s.outputFilePath
99}
100
101func (s *ShBinary) SubDir() string {
102 return String(s.properties.Sub_dir)
103}
104
105func (s *ShBinary) Installable() bool {
106 return s.properties.Installable == nil || Bool(s.properties.Installable)
107}
108
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -0700109func (s *ShBinary) Symlinks() []string {
110 return s.properties.Symlinks
111}
112
Dan Willemsenb0552672019-01-25 16:04:11 -0800113func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Cross8a497952019-03-05 22:25:09 -0800114 s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
Dan Willemsenb0552672019-01-25 16:04:11 -0800115 filename := String(s.properties.Filename)
116 filename_from_src := Bool(s.properties.Filename_from_src)
117 if filename == "" {
118 if filename_from_src {
119 filename = s.sourceFilePath.Base()
120 } else {
121 filename = ctx.ModuleName()
122 }
123 } else if filename_from_src {
124 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
125 return
126 }
127 s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
128
129 // This ensures that outputFilePath has the correct name for others to
130 // use, as the source file may have a different name.
131 ctx.Build(pctx, BuildParams{
132 Rule: CpExecutable,
133 Output: s.outputFilePath,
134 Input: s.sourceFilePath,
135 })
136}
137
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700138func (s *ShBinary) AndroidMkEntries() AndroidMkEntries {
139 return AndroidMkEntries{
Dan Willemsenb0552672019-01-25 16:04:11 -0800140 Class: "EXECUTABLES",
141 OutputFile: OptionalPathForPath(s.outputFilePath),
142 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700143 ExtraEntries: []AndroidMkExtraEntriesFunc{
144 func(entries *AndroidMkEntries) {
145 s.customAndroidMkEntries(entries)
146 },
Dan Willemsenb0552672019-01-25 16:04:11 -0800147 },
148 }
149}
150
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700151func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) {
152 entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir))
153 entries.SetString("LOCAL_MODULE_SUFFIX", "")
154 entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -0700155 if len(s.properties.Symlinks) > 0 {
156 entries.SetString("LOCAL_MODULE_SYMLINKS", strings.Join(s.properties.Symlinks, " "))
157 }
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700158}
159
160func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
161 s.ShBinary.GenerateAndroidBuildActions(ctx)
162
163 s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
164}
165
166func (s *ShTest) AndroidMkEntries() AndroidMkEntries {
167 return AndroidMkEntries{
168 Class: "NATIVE_TESTS",
169 OutputFile: OptionalPathForPath(s.outputFilePath),
170 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700171 ExtraEntries: []AndroidMkExtraEntriesFunc{
172 func(entries *AndroidMkEntries) {
173 s.customAndroidMkEntries(entries)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700174
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700175 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
176 entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
177 for _, d := range s.data {
178 rel := d.Rel()
179 path := d.String()
180 if !strings.HasSuffix(path, rel) {
181 panic(fmt.Errorf("path %q does not end with %q", path, rel))
182 }
183 path = strings.TrimSuffix(path, rel)
184 entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700185 }
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700186 },
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700187 },
188 }
Julien Desprez9e7fc142019-03-08 11:07:05 -0800189}
190
Dan Willemsenb0552672019-01-25 16:04:11 -0800191func InitShBinaryModule(s *ShBinary) {
192 s.AddProperties(&s.properties)
193}
194
Patrice Arrudae1034192019-03-11 13:20:17 -0700195// sh_binary is for a shell script or batch file to be installed as an
196// executable binary to <partition>/bin.
Dan Willemsenb0552672019-01-25 16:04:11 -0800197func ShBinaryFactory() Module {
198 module := &ShBinary{}
Jiyong Park6ac3cac2019-11-19 12:57:57 +0900199 module.Prefer32(func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool {
200 return class == Device && ctx.Config().DevicePrefer32BitExecutables()
201 })
Dan Willemsenb0552672019-01-25 16:04:11 -0800202 InitShBinaryModule(module)
203 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
204 return module
205}
206
Patrice Arrudae1034192019-03-11 13:20:17 -0700207// sh_binary_host is for a shell script to be installed as an executable binary
208// to $(HOST_OUT)/bin.
Dan Willemsenb0552672019-01-25 16:04:11 -0800209func ShBinaryHostFactory() Module {
210 module := &ShBinary{}
211 InitShBinaryModule(module)
212 InitAndroidArchModule(module, HostSupported, MultilibFirst)
213 return module
214}
Julien Desprez9e7fc142019-03-08 11:07:05 -0800215
Jaewoong Jung61a83682019-07-01 09:08:50 -0700216// sh_test defines a shell script based test module.
Julien Desprez9e7fc142019-03-08 11:07:05 -0800217func ShTestFactory() Module {
218 module := &ShTest{}
219 InitShBinaryModule(&module.ShBinary)
220 module.AddProperties(&module.testProperties)
221
222 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
223 return module
224}
Jaewoong Jung61a83682019-07-01 09:08:50 -0700225
226// sh_test_host defines a shell script based test module that runs on a host.
227func ShTestHostFactory() Module {
228 module := &ShTest{}
229 InitShBinaryModule(&module.ShBinary)
230 module.AddProperties(&module.testProperties)
231
232 InitAndroidArchModule(module, HostSupported, MultilibFirst)
233 return module
234}