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 android 16 17import ( 18 "fmt" 19 "io" 20 "strings" 21) 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) 32 RegisterModuleType("sh_test", ShTestFactory) 33} 34 35type shBinaryProperties struct { 36 // Source file of this prebuilt. 37 Src *string `android:"path,arch_variant"` 38 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 51} 52 53type TestProperties struct { 54 // list of compatibility suites (for example "cts", "vts") that the module should be 55 // installed into. 56 Test_suites []string `android:"arch_variant"` 57 58 // the name of the test configuration (for example "AndroidTest.xml") that should be 59 // installed with the module. 60 Test_config *string `android:"arch_variant"` 61} 62 63type ShBinary struct { 64 ModuleBase 65 66 properties shBinaryProperties 67 68 sourceFilePath Path 69 outputFilePath OutputPath 70} 71 72type ShTest struct { 73 ShBinary 74 75 testProperties TestProperties 76} 77 78func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) { 79 if s.properties.Src == nil { 80 ctx.PropertyErrorf("src", "missing prebuilt source file") 81 } 82} 83 84func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path { 85 return PathForModuleSrc(ctx, String(s.properties.Src)) 86} 87 88func (s *ShBinary) OutputFile() OutputPath { 89 return s.outputFilePath 90} 91 92func (s *ShBinary) SubDir() string { 93 return String(s.properties.Sub_dir) 94} 95 96func (s *ShBinary) Installable() bool { 97 return s.properties.Installable == nil || Bool(s.properties.Installable) 98} 99 100func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) { 101 s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src)) 102 filename := String(s.properties.Filename) 103 filename_from_src := Bool(s.properties.Filename_from_src) 104 if filename == "" { 105 if filename_from_src { 106 filename = s.sourceFilePath.Base() 107 } else { 108 filename = ctx.ModuleName() 109 } 110 } else if filename_from_src { 111 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true") 112 return 113 } 114 s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath 115 116 // This ensures that outputFilePath has the correct name for others to 117 // use, as the source file may have a different name. 118 ctx.Build(pctx, BuildParams{ 119 Rule: CpExecutable, 120 Output: s.outputFilePath, 121 Input: s.sourceFilePath, 122 }) 123} 124 125func (s *ShBinary) AndroidMk() AndroidMkData { 126 return AndroidMkData{ 127 Class: "EXECUTABLES", 128 OutputFile: OptionalPathForPath(s.outputFilePath), 129 Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk", 130 Extra: []AndroidMkExtraFunc{ 131 func(w io.Writer, outputFile Path) { 132 fmt.Fprintln(w, "LOCAL_MODULE_RELATIVE_PATH :=", String(s.properties.Sub_dir)) 133 fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX :=") 134 fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", s.outputFilePath.Rel()) 135 }, 136 }, 137 } 138} 139 140func (s *ShTest) AndroidMk() AndroidMkData { 141 data := s.ShBinary.AndroidMk() 142 data.Class = "NATIVE_TESTS" 143 data.Extra = append(data.Extra, func(w io.Writer, outputFile Path) { 144 fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=", 145 strings.Join(s.testProperties.Test_suites, " ")) 146 fmt.Fprintln(w, "LOCAL_TEST_CONFIG :=", String(s.testProperties.Test_config)) 147 }) 148 return data 149} 150 151func InitShBinaryModule(s *ShBinary) { 152 s.AddProperties(&s.properties) 153} 154 155// sh_binary is for a shell script or batch file to be installed as an 156// executable binary to <partition>/bin. 157func ShBinaryFactory() Module { 158 module := &ShBinary{} 159 InitShBinaryModule(module) 160 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst) 161 return module 162} 163 164// sh_binary_host is for a shell script to be installed as an executable binary 165// to $(HOST_OUT)/bin. 166func ShBinaryHostFactory() Module { 167 module := &ShBinary{} 168 InitShBinaryModule(module) 169 InitAndroidArchModule(module, HostSupported, MultilibFirst) 170 return module 171} 172 173func ShTestFactory() Module { 174 module := &ShTest{} 175 InitShBinaryModule(&module.ShBinary) 176 module.AddProperties(&module.testProperties) 177 178 InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst) 179 return module 180} 181