• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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