blob: 7d9dc67b86a218859a07cc715606c14412e3db8a [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"
Colin Cross7c7c1142019-07-29 16:46:49 -070019 "path/filepath"
Julien Desprez9e7fc142019-03-08 11:07:05 -080020 "strings"
Dan Willemsenb0552672019-01-25 16:04:11 -080021)
22
23// sh_binary is for shell scripts (and batch files) that are installed as
24// executable files into .../bin/
25//
26// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
27// instead.
28
29func init() {
30 RegisterModuleType("sh_binary", ShBinaryFactory)
31 RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
Julien Desprez9e7fc142019-03-08 11:07:05 -080032 RegisterModuleType("sh_test", ShTestFactory)
Jaewoong Jung61a83682019-07-01 09:08:50 -070033 RegisterModuleType("sh_test_host", ShTestHostFactory)
Dan Willemsenb0552672019-01-25 16:04:11 -080034}
35
36type shBinaryProperties struct {
37 // Source file of this prebuilt.
Colin Cross27b922f2019-03-04 22:35:41 -080038 Src *string `android:"path,arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080039
40 // optional subdirectory under which this file is installed into
41 Sub_dir *string `android:"arch_variant"`
42
43 // optional name for the installed file. If unspecified, name of the module is used as the file name
44 Filename *string `android:"arch_variant"`
45
46 // when set to true, and filename property is not set, the name for the installed file
47 // is the same as the file name of the source file.
48 Filename_from_src *bool `android:"arch_variant"`
49
50 // Whether this module is directly installable to one of the partitions. Default: true.
51 Installable *bool
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -070052
53 // install symlinks to the binary
54 Symlinks []string `android:"arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080055}
56
Julien Desprez9e7fc142019-03-08 11:07:05 -080057type TestProperties struct {
58 // list of compatibility suites (for example "cts", "vts") that the module should be
59 // installed into.
60 Test_suites []string `android:"arch_variant"`
61
62 // the name of the test configuration (for example "AndroidTest.xml") that should be
63 // installed with the module.
64 Test_config *string `android:"arch_variant"`
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070065
66 // list of files or filegroup modules that provide data that should be installed alongside
67 // the test.
68 Data []string `android:"path,arch_variant"`
Julien Desprez9e7fc142019-03-08 11:07:05 -080069}
70
Dan Willemsenb0552672019-01-25 16:04:11 -080071type ShBinary struct {
72 ModuleBase
73
74 properties shBinaryProperties
75
76 sourceFilePath Path
77 outputFilePath OutputPath
Colin Cross7c7c1142019-07-29 16:46:49 -070078 installedFile InstallPath
Dan Willemsenb0552672019-01-25 16:04:11 -080079}
80
Colin Cross7c7c1142019-07-29 16:46:49 -070081var _ HostToolProvider = (*ShBinary)(nil)
82
Julien Desprez9e7fc142019-03-08 11:07:05 -080083type ShTest struct {
84 ShBinary
85
86 testProperties TestProperties
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070087
88 data Paths
Julien Desprez9e7fc142019-03-08 11:07:05 -080089}
90
Colin Cross7c7c1142019-07-29 16:46:49 -070091func (s *ShBinary) HostToolPath() OptionalPath {
92 return OptionalPathForPath(s.installedFile)
93}
94
Dan Willemsenb0552672019-01-25 16:04:11 -080095func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
96 if s.properties.Src == nil {
97 ctx.PropertyErrorf("src", "missing prebuilt source file")
98 }
Dan Willemsenb0552672019-01-25 16:04:11 -080099}
100
Dan Willemsenb0552672019-01-25 16:04:11 -0800101func (s *ShBinary) OutputFile() OutputPath {
102 return s.outputFilePath
103}
104
105func (s *ShBinary) SubDir() string {
106 return String(s.properties.Sub_dir)
107}
108
109func (s *ShBinary) Installable() bool {
110 return s.properties.Installable == nil || Bool(s.properties.Installable)
111}
112
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -0700113func (s *ShBinary) Symlinks() []string {
114 return s.properties.Symlinks
115}
116
Colin Cross7c7c1142019-07-29 16:46:49 -0700117func (s *ShBinary) generateAndroidBuildActions(ctx ModuleContext) {
Colin Cross8a497952019-03-05 22:25:09 -0800118 s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
Dan Willemsenb0552672019-01-25 16:04:11 -0800119 filename := String(s.properties.Filename)
120 filename_from_src := Bool(s.properties.Filename_from_src)
121 if filename == "" {
122 if filename_from_src {
123 filename = s.sourceFilePath.Base()
124 } else {
125 filename = ctx.ModuleName()
126 }
127 } else if filename_from_src {
128 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
129 return
130 }
131 s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
132
133 // This ensures that outputFilePath has the correct name for others to
134 // use, as the source file may have a different name.
135 ctx.Build(pctx, BuildParams{
136 Rule: CpExecutable,
137 Output: s.outputFilePath,
138 Input: s.sourceFilePath,
139 })
140}
141
Colin Cross7c7c1142019-07-29 16:46:49 -0700142func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
143 s.generateAndroidBuildActions(ctx)
144 installDir := PathForModuleInstall(ctx, "bin", String(s.properties.Sub_dir))
145 s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
146}
147
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900148func (s *ShBinary) AndroidMkEntries() []AndroidMkEntries {
149 return []AndroidMkEntries{AndroidMkEntries{
Dan Willemsenb0552672019-01-25 16:04:11 -0800150 Class: "EXECUTABLES",
151 OutputFile: OptionalPathForPath(s.outputFilePath),
152 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700153 ExtraEntries: []AndroidMkExtraEntriesFunc{
154 func(entries *AndroidMkEntries) {
155 s.customAndroidMkEntries(entries)
156 },
Dan Willemsenb0552672019-01-25 16:04:11 -0800157 },
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900158 }}
Dan Willemsenb0552672019-01-25 16:04:11 -0800159}
160
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700161func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) {
162 entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir))
163 entries.SetString("LOCAL_MODULE_SUFFIX", "")
164 entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
Rashed Abdel-Tawab6a341312019-10-04 20:38:01 -0700165 if len(s.properties.Symlinks) > 0 {
166 entries.SetString("LOCAL_MODULE_SYMLINKS", strings.Join(s.properties.Symlinks, " "))
167 }
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700168}
169
170func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Cross7c7c1142019-07-29 16:46:49 -0700171 s.ShBinary.generateAndroidBuildActions(ctx)
172 testDir := "nativetest"
173 if ctx.Target().Arch.ArchType.Multilib == "lib64" {
174 testDir = "nativetest64"
175 }
176 if ctx.Target().NativeBridge == NativeBridgeEnabled {
177 testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath)
178 } else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
179 testDir = filepath.Join(testDir, ctx.Arch().ArchType.String())
180 }
181 installDir := PathForModuleInstall(ctx, testDir, String(s.properties.Sub_dir))
182 s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700183
184 s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
185}
186
Colin Cross7c7c1142019-07-29 16:46:49 -0700187func (s *ShTest) InstallInData() bool {
188 return true
189}
190
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900191func (s *ShTest) AndroidMkEntries() []AndroidMkEntries {
192 return []AndroidMkEntries{AndroidMkEntries{
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700193 Class: "NATIVE_TESTS",
194 OutputFile: OptionalPathForPath(s.outputFilePath),
195 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700196 ExtraEntries: []AndroidMkExtraEntriesFunc{
197 func(entries *AndroidMkEntries) {
198 s.customAndroidMkEntries(entries)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700199
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700200 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
201 entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
202 for _, d := range s.data {
203 rel := d.Rel()
204 path := d.String()
205 if !strings.HasSuffix(path, rel) {
206 panic(fmt.Errorf("path %q does not end with %q", path, rel))
207 }
208 path = strings.TrimSuffix(path, rel)
209 entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700210 }
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700211 },
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700212 },
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900213 }}
Julien Desprez9e7fc142019-03-08 11:07:05 -0800214}
215
Dan Willemsenb0552672019-01-25 16:04:11 -0800216func InitShBinaryModule(s *ShBinary) {
217 s.AddProperties(&s.properties)
218}
219
Patrice Arrudae1034192019-03-11 13:20:17 -0700220// sh_binary is for a shell script or batch file to be installed as an
221// executable binary to <partition>/bin.
Dan Willemsenb0552672019-01-25 16:04:11 -0800222func ShBinaryFactory() Module {
223 module := &ShBinary{}
Jiyong Park6ac3cac2019-11-19 12:57:57 +0900224 module.Prefer32(func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool {
225 return class == Device && ctx.Config().DevicePrefer32BitExecutables()
226 })
Dan Willemsenb0552672019-01-25 16:04:11 -0800227 InitShBinaryModule(module)
228 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
229 return module
230}
231
Patrice Arrudae1034192019-03-11 13:20:17 -0700232// sh_binary_host is for a shell script to be installed as an executable binary
233// to $(HOST_OUT)/bin.
Dan Willemsenb0552672019-01-25 16:04:11 -0800234func ShBinaryHostFactory() Module {
235 module := &ShBinary{}
236 InitShBinaryModule(module)
237 InitAndroidArchModule(module, HostSupported, MultilibFirst)
238 return module
239}
Julien Desprez9e7fc142019-03-08 11:07:05 -0800240
Jaewoong Jung61a83682019-07-01 09:08:50 -0700241// sh_test defines a shell script based test module.
Julien Desprez9e7fc142019-03-08 11:07:05 -0800242func ShTestFactory() Module {
243 module := &ShTest{}
244 InitShBinaryModule(&module.ShBinary)
245 module.AddProperties(&module.testProperties)
246
247 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
248 return module
249}
Jaewoong Jung61a83682019-07-01 09:08:50 -0700250
251// sh_test_host defines a shell script based test module that runs on a host.
252func ShTestHostFactory() Module {
253 module := &ShTest{}
254 InitShBinaryModule(&module.ShBinary)
255 module.AddProperties(&module.testProperties)
256
257 InitAndroidArchModule(module, HostSupported, MultilibFirst)
258 return module
259}