blob: a047e474e365557b9fd105bbb147d7f81127a474 [file] [log] [blame]
Jiyong Parkc678ad32018-04-10 13:07:10 +09001// Copyright 2016 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"
Anton Hansson4ca89892019-01-14 12:17:40 +000020 "strings"
Jiyong Parkc678ad32018-04-10 13:07:10 +090021)
22
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -080023// TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file.
Jiyong Parkc678ad32018-04-10 13:07:10 +090024
25func init() {
26 RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
Jaewoong Jung4b44fcd2019-02-07 08:28:03 -080027 RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -080028 RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
Tao Bao0ba5c942018-08-14 22:20:22 -070029
30 PreDepsMutators(func(ctx RegisterMutatorsContext) {
31 ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
32 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090033}
34
35type prebuiltEtcProperties struct {
36 // Source file of this prebuilt.
Jiyong Park5a8d1be2018-04-25 22:57:34 +090037 Src *string `android:"arch_variant"`
Jiyong Parkc678ad32018-04-10 13:07:10 +090038
39 // optional subdirectory under which this file is installed into
40 Sub_dir *string `android:"arch_variant"`
Tao Bao0ba5c942018-08-14 22:20:22 -070041
Jiyong Park139a2e62018-10-26 21:49:39 +090042 // 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
Jiyong Park1a7cf082018-11-13 11:59:12 +090045 // 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
Tao Bao0ba5c942018-08-14 22:20:22 -070049 // Make this module available when building for recovery.
50 Recovery_available *bool
51
52 InRecovery bool `blueprint:"mutated"`
Jiyong Parkad9ce042018-10-31 22:49:57 +090053
54 // Whether this module is directly installable to one of the partitions. Default: true.
55 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +090056}
57
Jiyong Park5a8d1be2018-04-25 22:57:34 +090058type PrebuiltEtc struct {
Jiyong Parkc678ad32018-04-10 13:07:10 +090059 ModuleBase
Jiyong Parkc678ad32018-04-10 13:07:10 +090060
61 properties prebuiltEtcProperties
62
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -080063 sourceFilePath Path
64 outputFilePath OutputPath
65 // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
66 installDirBase string
Jiyong Park5a8d1be2018-04-25 22:57:34 +090067 installDirPath OutputPath
68 additionalDependencies *Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +090069}
70
Tao Bao0ba5c942018-08-14 22:20:22 -070071func (p *PrebuiltEtc) inRecovery() bool {
72 return p.properties.InRecovery || p.ModuleBase.InstallInRecovery()
73}
74
75func (p *PrebuiltEtc) onlyInRecovery() bool {
76 return p.ModuleBase.InstallInRecovery()
77}
78
79func (p *PrebuiltEtc) InstallInRecovery() bool {
80 return p.inRecovery()
81}
82
Jiyong Park5a8d1be2018-04-25 22:57:34 +090083func (p *PrebuiltEtc) DepsMutator(ctx BottomUpMutatorContext) {
84 if p.properties.Src == nil {
85 ctx.PropertyErrorf("src", "missing prebuilt source file")
Jiyong Parkc678ad32018-04-10 13:07:10 +090086 }
87
88 // To support ":modulename" in src
Jiyong Park5a8d1be2018-04-25 22:57:34 +090089 ExtractSourceDeps(ctx, p.properties.Src)
Jiyong Parkc678ad32018-04-10 13:07:10 +090090}
91
Jiyong Park5a8d1be2018-04-25 22:57:34 +090092func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
93 return ctx.ExpandSource(String(p.properties.Src), "src")
94}
95
96// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
97// additional steps (like validating the src) before the file is installed.
98func (p *PrebuiltEtc) SetAdditionalDependencies(paths Paths) {
99 p.additionalDependencies = &paths
100}
101
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900102func (p *PrebuiltEtc) OutputFile() OutputPath {
103 return p.outputFilePath
104}
105
106func (p *PrebuiltEtc) SubDir() string {
107 return String(p.properties.Sub_dir)
108}
109
Jiyong Parkad9ce042018-10-31 22:49:57 +0900110func (p *PrebuiltEtc) Installable() bool {
111 return p.properties.Installable == nil || Bool(p.properties.Installable)
112}
113
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900114func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
115 p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
Jiyong Park139a2e62018-10-26 21:49:39 +0900116 filename := String(p.properties.Filename)
Jiyong Park1a7cf082018-11-13 11:59:12 +0900117 filename_from_src := Bool(p.properties.Filename_from_src)
Jiyong Park139a2e62018-10-26 21:49:39 +0900118 if filename == "" {
Jiyong Park1a7cf082018-11-13 11:59:12 +0900119 if filename_from_src {
120 filename = p.sourceFilePath.Base()
121 } else {
122 filename = ctx.ModuleName()
123 }
124 } else if filename_from_src {
125 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
126 return
Jiyong Park139a2e62018-10-26 21:49:39 +0900127 }
128 p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800129 p.installDirPath = PathForModuleInstall(ctx, p.installDirBase, String(p.properties.Sub_dir))
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900130
Dan Willemsenb0552672019-01-25 16:04:11 -0800131 // This ensures that outputFilePath has the correct name for others to
132 // use, as the source file may have a different name.
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900133 ctx.Build(pctx, BuildParams{
134 Rule: Cp,
135 Output: p.outputFilePath,
136 Input: p.sourceFilePath,
137 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900138}
139
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900140func (p *PrebuiltEtc) AndroidMk() AndroidMkData {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900141 return AndroidMkData{
142 Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
Tao Bao0ba5c942018-08-14 22:20:22 -0700143 nameSuffix := ""
144 if p.inRecovery() && !p.onlyInRecovery() {
145 nameSuffix = ".recovery"
146 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900147 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
148 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
Tao Bao0ba5c942018-08-14 22:20:22 -0700149 fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900150 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
Anton Hanssonce0e2582019-02-04 14:19:27 +0000151 if p.commonProperties.Owner != nil {
152 fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", *p.commonProperties.Owner)
153 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900154 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
Jaewoong Jung24788182019-02-04 14:34:10 -0800155 if p.Host() {
156 fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
157 }
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900158 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900159 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
Jiyong Park139a2e62018-10-26 21:49:39 +0900160 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
Jiyong Parkad9ce042018-10-31 22:49:57 +0900161 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !p.Installable())
Anton Hansson4ca89892019-01-14 12:17:40 +0000162 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(data.Required, " "))
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900163 if p.additionalDependencies != nil {
164 fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
165 for _, path := range *p.additionalDependencies {
166 fmt.Fprint(w, " "+path.String())
167 }
168 fmt.Fprintln(w, "")
169 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900170 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
171 },
172 }
173}
174
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900175func InitPrebuiltEtcModule(p *PrebuiltEtc) {
176 p.AddProperties(&p.properties)
177}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900178
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800179// prebuilt_etc is for prebuilts that will be installed to <partition>/etc/<subdir>
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900180func PrebuiltEtcFactory() Module {
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800181 module := &PrebuiltEtc{installDirBase: "etc"}
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900182 InitPrebuiltEtcModule(module)
183 // This module is device-only
Jaewoong Jungb9a11512019-01-15 10:47:05 -0800184 InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900185 return module
186}
Tao Bao0ba5c942018-08-14 22:20:22 -0700187
Jaewoong Jung4b44fcd2019-02-07 08:28:03 -0800188func PrebuiltEtcHostFactory() Module {
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800189 module := &PrebuiltEtc{installDirBase: "etc"}
Jaewoong Jung24788182019-02-04 14:34:10 -0800190 InitPrebuiltEtcModule(module)
191 // This module is host-only
192 InitAndroidArchModule(module, HostSupported, MultilibCommon)
193 return module
194}
195
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800196// prebuilt_usr_share is for prebuilts that will be installed to <partition>/usr/share/<subdir>
197func PrebuiltUserShareFactory() Module {
198 module := &PrebuiltEtc{installDirBase: "usr/share"}
199 InitPrebuiltEtcModule(module)
200 // This module is device-only
201 InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
202 return module
203}
204
Tao Bao0ba5c942018-08-14 22:20:22 -0700205const (
206 // coreMode is the variant for modules to be installed to system.
207 coreMode = "core"
208
209 // recoveryMode means a module to be installed to recovery image.
210 recoveryMode = "recovery"
211)
212
213// prebuiltEtcMutator creates the needed variants to install the module to
214// system or recovery.
215func prebuiltEtcMutator(mctx BottomUpMutatorContext) {
216 m, ok := mctx.Module().(*PrebuiltEtc)
Jaewoong Jung24788182019-02-04 14:34:10 -0800217 if !ok || m.Host() {
Tao Bao0ba5c942018-08-14 22:20:22 -0700218 return
219 }
220
221 var coreVariantNeeded bool = true
222 var recoveryVariantNeeded bool = false
223 if Bool(m.properties.Recovery_available) {
224 recoveryVariantNeeded = true
225 }
226
227 if m.ModuleBase.InstallInRecovery() {
228 recoveryVariantNeeded = true
229 coreVariantNeeded = false
230 }
231
232 var variants []string
233 if coreVariantNeeded {
234 variants = append(variants, coreMode)
235 }
236 if recoveryVariantNeeded {
237 variants = append(variants, recoveryMode)
238 }
239 mod := mctx.CreateVariations(variants...)
240 for i, v := range variants {
241 if v == recoveryMode {
242 m := mod[i].(*PrebuiltEtc)
243 m.properties.InRecovery = true
244 }
245 }
246}