From b05526711edfc1d42658ceffcca520558085b50a Mon Sep 17 00:00:00 2001 From: Dan Willemsen Date: Fri, 25 Jan 2019 16:04:11 -0800 Subject: [PATCH] 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 --- Android.bp | 1 + android/prebuilt_etc.go | 3 +- android/sh_binary.go | 141 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 android/sh_binary.go diff --git a/Android.bp b/Android.bp index 3215fa2b4..a70f73c92 100644 --- a/Android.bp +++ b/Android.bp @@ -61,6 +61,7 @@ bootstrap_go_package { "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 46d128eba..42c7c2c6f 100644 --- a/android/prebuilt_etc.go +++ b/android/prebuilt_etc.go @@ -125,7 +125,8 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) { 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 000000000..391519391 --- /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 +}