Add sh_binary[_host] for shell script that should be installed as executable
We've been putting these in cc_prebuilt_binary, but that's not really
correct. It also tries adding '.exe' to the end of windows executables,
which isn't desirable for bat files.
Test: Use sh_binary_host
Change-Id: Idd5418dceb81ac55b766c987fbb69a810aeb8a3b
diff --git a/Android.bp b/Android.bp
index 3215fa2..a70f73c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -61,6 +61,7 @@
"android/prebuilt_etc.go",
"android/proto.go",
"android/register.go",
+ "android/sh_binary.go",
"android/singleton.go",
"android/testing.go",
"android/util.go",
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 46d128e..42c7c2c 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -125,7 +125,8 @@
p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
p.installDirPath = PathForModuleInstall(ctx, "etc", String(p.properties.Sub_dir))
- // This ensures that outputFilePath has the same name as this module.
+ // This ensures that outputFilePath has the correct name for others to
+ // use, as the source file may have a different name.
ctx.Build(pctx, BuildParams{
Rule: Cp,
Output: p.outputFilePath,
diff --git a/android/sh_binary.go b/android/sh_binary.go
new file mode 100644
index 0000000..3915193
--- /dev/null
+++ b/android/sh_binary.go
@@ -0,0 +1,141 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "io"
+)
+
+// sh_binary is for shell scripts (and batch files) that are installed as
+// executable files into .../bin/
+//
+// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
+// instead.
+
+func init() {
+ RegisterModuleType("sh_binary", ShBinaryFactory)
+ RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
+}
+
+type shBinaryProperties struct {
+ // Source file of this prebuilt.
+ Src *string `android:"arch_variant"`
+
+ // optional subdirectory under which this file is installed into
+ Sub_dir *string `android:"arch_variant"`
+
+ // optional name for the installed file. If unspecified, name of the module is used as the file name
+ Filename *string `android:"arch_variant"`
+
+ // when set to true, and filename property is not set, the name for the installed file
+ // is the same as the file name of the source file.
+ Filename_from_src *bool `android:"arch_variant"`
+
+ // Whether this module is directly installable to one of the partitions. Default: true.
+ Installable *bool
+}
+
+type ShBinary struct {
+ ModuleBase
+
+ properties shBinaryProperties
+
+ sourceFilePath Path
+ outputFilePath OutputPath
+}
+
+func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
+ if s.properties.Src == nil {
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ }
+
+ // To support ":modulename" in src
+ ExtractSourceDeps(ctx, s.properties.Src)
+}
+
+func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
+ return ctx.ExpandSource(String(s.properties.Src), "src")
+}
+
+func (s *ShBinary) OutputFile() OutputPath {
+ return s.outputFilePath
+}
+
+func (s *ShBinary) SubDir() string {
+ return String(s.properties.Sub_dir)
+}
+
+func (s *ShBinary) Installable() bool {
+ return s.properties.Installable == nil || Bool(s.properties.Installable)
+}
+
+func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+ s.sourceFilePath = ctx.ExpandSource(String(s.properties.Src), "src")
+ filename := String(s.properties.Filename)
+ filename_from_src := Bool(s.properties.Filename_from_src)
+ if filename == "" {
+ if filename_from_src {
+ filename = s.sourceFilePath.Base()
+ } else {
+ filename = ctx.ModuleName()
+ }
+ } else if filename_from_src {
+ ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
+ return
+ }
+ s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
+
+ // This ensures that outputFilePath has the correct name for others to
+ // use, as the source file may have a different name.
+ ctx.Build(pctx, BuildParams{
+ Rule: CpExecutable,
+ Output: s.outputFilePath,
+ Input: s.sourceFilePath,
+ })
+}
+
+func (s *ShBinary) AndroidMk() AndroidMkData {
+ return AndroidMkData{
+ Class: "EXECUTABLES",
+ OutputFile: OptionalPathForPath(s.outputFilePath),
+ Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
+ Extra: []AndroidMkExtraFunc{
+ func(w io.Writer, outputFile Path) {
+ fmt.Fprintln(w, "LOCAL_MODULE_RELATIVE_PATH :=", String(s.properties.Sub_dir))
+ fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX :=")
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", s.outputFilePath.Rel())
+ },
+ },
+ }
+}
+
+func InitShBinaryModule(s *ShBinary) {
+ s.AddProperties(&s.properties)
+}
+
+func ShBinaryFactory() Module {
+ module := &ShBinary{}
+ InitShBinaryModule(module)
+ InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
+ return module
+}
+
+func ShBinaryHostFactory() Module {
+ module := &ShBinary{}
+ InitShBinaryModule(module)
+ InitAndroidArchModule(module, HostSupported, MultilibFirst)
+ return module
+}