blob: fb7446dccd1872bb1f061d1258cd34dca85084cc [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)
Dan Willemsenb0552672019-01-25 16:04:11 -080032}
33
34type shBinaryProperties struct {
35 // Source file of this prebuilt.
Colin Cross27b922f2019-03-04 22:35:41 -080036 Src *string `android:"path,arch_variant"`
Dan Willemsenb0552672019-01-25 16:04:11 -080037
38 // optional subdirectory under which this file is installed into
39 Sub_dir *string `android:"arch_variant"`
40
41 // optional name for the installed file. If unspecified, name of the module is used as the file name
42 Filename *string `android:"arch_variant"`
43
44 // when set to true, and filename property is not set, the name for the installed file
45 // is the same as the file name of the source file.
46 Filename_from_src *bool `android:"arch_variant"`
47
48 // Whether this module is directly installable to one of the partitions. Default: true.
49 Installable *bool
50}
51
Julien Desprez9e7fc142019-03-08 11:07:05 -080052type TestProperties struct {
53 // list of compatibility suites (for example "cts", "vts") that the module should be
54 // installed into.
55 Test_suites []string `android:"arch_variant"`
56
57 // the name of the test configuration (for example "AndroidTest.xml") that should be
58 // installed with the module.
59 Test_config *string `android:"arch_variant"`
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070060
61 // list of files or filegroup modules that provide data that should be installed alongside
62 // the test.
63 Data []string `android:"path,arch_variant"`
Julien Desprez9e7fc142019-03-08 11:07:05 -080064}
65
Dan Willemsenb0552672019-01-25 16:04:11 -080066type ShBinary struct {
67 ModuleBase
68
69 properties shBinaryProperties
70
71 sourceFilePath Path
72 outputFilePath OutputPath
73}
74
Julien Desprez9e7fc142019-03-08 11:07:05 -080075type ShTest struct {
76 ShBinary
77
78 testProperties TestProperties
Jaewoong Jung8eaeb092019-05-16 14:58:29 -070079
80 data Paths
Julien Desprez9e7fc142019-03-08 11:07:05 -080081}
82
Dan Willemsenb0552672019-01-25 16:04:11 -080083func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
84 if s.properties.Src == nil {
85 ctx.PropertyErrorf("src", "missing prebuilt source file")
86 }
Dan Willemsenb0552672019-01-25 16:04:11 -080087}
88
89func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
Colin Cross8a497952019-03-05 22:25:09 -080090 return PathForModuleSrc(ctx, String(s.properties.Src))
Dan Willemsenb0552672019-01-25 16:04:11 -080091}
92
93func (s *ShBinary) OutputFile() OutputPath {
94 return s.outputFilePath
95}
96
97func (s *ShBinary) SubDir() string {
98 return String(s.properties.Sub_dir)
99}
100
101func (s *ShBinary) Installable() bool {
102 return s.properties.Installable == nil || Bool(s.properties.Installable)
103}
104
105func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Cross8a497952019-03-05 22:25:09 -0800106 s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
Dan Willemsenb0552672019-01-25 16:04:11 -0800107 filename := String(s.properties.Filename)
108 filename_from_src := Bool(s.properties.Filename_from_src)
109 if filename == "" {
110 if filename_from_src {
111 filename = s.sourceFilePath.Base()
112 } else {
113 filename = ctx.ModuleName()
114 }
115 } else if filename_from_src {
116 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
117 return
118 }
119 s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
120
121 // This ensures that outputFilePath has the correct name for others to
122 // use, as the source file may have a different name.
123 ctx.Build(pctx, BuildParams{
124 Rule: CpExecutable,
125 Output: s.outputFilePath,
126 Input: s.sourceFilePath,
127 })
128}
129
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700130func (s *ShBinary) AndroidMkEntries() AndroidMkEntries {
131 return AndroidMkEntries{
Dan Willemsenb0552672019-01-25 16:04:11 -0800132 Class: "EXECUTABLES",
133 OutputFile: OptionalPathForPath(s.outputFilePath),
134 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700135 AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
136 s.customAndroidMkEntries(entries)
Dan Willemsenb0552672019-01-25 16:04:11 -0800137 },
138 }
139}
140
Jaewoong Jung8eaeb092019-05-16 14:58:29 -0700141func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) {
142 entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir))
143 entries.SetString("LOCAL_MODULE_SUFFIX", "")
144 entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
145}
146
147func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
148 s.ShBinary.GenerateAndroidBuildActions(ctx)
149
150 s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
151}
152
153func (s *ShTest) AndroidMkEntries() AndroidMkEntries {
154 return AndroidMkEntries{
155 Class: "NATIVE_TESTS",
156 OutputFile: OptionalPathForPath(s.outputFilePath),
157 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
158 AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
159 s.customAndroidMkEntries(entries)
160
161 entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
162 entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
163 for _, d := range s.data {
164 rel := d.Rel()
165 path := d.String()
166 if !strings.HasSuffix(path, rel) {
167 panic(fmt.Errorf("path %q does not end with %q", path, rel))
168 }
169 path = strings.TrimSuffix(path, rel)
170 entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
171 }
172 },
173 }
Julien Desprez9e7fc142019-03-08 11:07:05 -0800174}
175
Dan Willemsenb0552672019-01-25 16:04:11 -0800176func InitShBinaryModule(s *ShBinary) {
177 s.AddProperties(&s.properties)
178}
179
Patrice Arrudae1034192019-03-11 13:20:17 -0700180// sh_binary is for a shell script or batch file to be installed as an
181// executable binary to <partition>/bin.
Dan Willemsenb0552672019-01-25 16:04:11 -0800182func ShBinaryFactory() Module {
183 module := &ShBinary{}
184 InitShBinaryModule(module)
185 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
186 return module
187}
188
Patrice Arrudae1034192019-03-11 13:20:17 -0700189// sh_binary_host is for a shell script to be installed as an executable binary
190// to $(HOST_OUT)/bin.
Dan Willemsenb0552672019-01-25 16:04:11 -0800191func ShBinaryHostFactory() Module {
192 module := &ShBinary{}
193 InitShBinaryModule(module)
194 InitAndroidArchModule(module, HostSupported, MultilibFirst)
195 return module
196}
Julien Desprez9e7fc142019-03-08 11:07:05 -0800197
198func ShTestFactory() Module {
199 module := &ShTest{}
200 InitShBinaryModule(&module.ShBinary)
201 module.AddProperties(&module.testProperties)
202
203 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
204 return module
205}