blob: c58cc4f8a8d592566e78e13a33f127e1e744cacd [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)
Patrice Arruda300cef92019-02-22 15:47:57 -080029 RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
Tao Bao0ba5c942018-08-14 22:20:22 -070030
31 PreDepsMutators(func(ctx RegisterMutatorsContext) {
32 ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
33 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090034}
35
36type prebuiltEtcProperties struct {
37 // Source file of this prebuilt.
Jiyong Park5a8d1be2018-04-25 22:57:34 +090038 Src *string `android:"arch_variant"`
Jiyong Parkc678ad32018-04-10 13:07:10 +090039
40 // optional subdirectory under which this file is installed into
41 Sub_dir *string `android:"arch_variant"`
Tao Bao0ba5c942018-08-14 22:20:22 -070042
Jiyong Park139a2e62018-10-26 21:49:39 +090043 // optional name for the installed file. If unspecified, name of the module is used as the file name
44 Filename *string `android:"arch_variant"`
45
Jiyong Park1a7cf082018-11-13 11:59:12 +090046 // when set to true, and filename property is not set, the name for the installed file
47 // is the same as the file name of the source file.
48 Filename_from_src *bool `android:"arch_variant"`
49
Tao Bao0ba5c942018-08-14 22:20:22 -070050 // Make this module available when building for recovery.
51 Recovery_available *bool
52
53 InRecovery bool `blueprint:"mutated"`
Jiyong Parkad9ce042018-10-31 22:49:57 +090054
55 // Whether this module is directly installable to one of the partitions. Default: true.
56 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +090057}
58
Jiyong Park5a8d1be2018-04-25 22:57:34 +090059type PrebuiltEtc struct {
Jiyong Parkc678ad32018-04-10 13:07:10 +090060 ModuleBase
Jiyong Parkc678ad32018-04-10 13:07:10 +090061
62 properties prebuiltEtcProperties
63
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -080064 sourceFilePath Path
65 outputFilePath OutputPath
66 // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
67 installDirBase string
Jiyong Park5a8d1be2018-04-25 22:57:34 +090068 installDirPath OutputPath
69 additionalDependencies *Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +090070}
71
Tao Bao0ba5c942018-08-14 22:20:22 -070072func (p *PrebuiltEtc) inRecovery() bool {
73 return p.properties.InRecovery || p.ModuleBase.InstallInRecovery()
74}
75
76func (p *PrebuiltEtc) onlyInRecovery() bool {
77 return p.ModuleBase.InstallInRecovery()
78}
79
80func (p *PrebuiltEtc) InstallInRecovery() bool {
81 return p.inRecovery()
82}
83
Jiyong Park5a8d1be2018-04-25 22:57:34 +090084func (p *PrebuiltEtc) DepsMutator(ctx BottomUpMutatorContext) {
85 if p.properties.Src == nil {
86 ctx.PropertyErrorf("src", "missing prebuilt source file")
Jiyong Parkc678ad32018-04-10 13:07:10 +090087 }
88
89 // To support ":modulename" in src
Jiyong Park5a8d1be2018-04-25 22:57:34 +090090 ExtractSourceDeps(ctx, p.properties.Src)
Jiyong Parkc678ad32018-04-10 13:07:10 +090091}
92
Jiyong Park5a8d1be2018-04-25 22:57:34 +090093func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
94 return ctx.ExpandSource(String(p.properties.Src), "src")
95}
96
97// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
98// additional steps (like validating the src) before the file is installed.
99func (p *PrebuiltEtc) SetAdditionalDependencies(paths Paths) {
100 p.additionalDependencies = &paths
101}
102
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900103func (p *PrebuiltEtc) OutputFile() OutputPath {
104 return p.outputFilePath
105}
106
107func (p *PrebuiltEtc) SubDir() string {
108 return String(p.properties.Sub_dir)
109}
110
Jiyong Parkad9ce042018-10-31 22:49:57 +0900111func (p *PrebuiltEtc) Installable() bool {
112 return p.properties.Installable == nil || Bool(p.properties.Installable)
113}
114
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900115func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
116 p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
Jiyong Park139a2e62018-10-26 21:49:39 +0900117 filename := String(p.properties.Filename)
Jiyong Park1a7cf082018-11-13 11:59:12 +0900118 filename_from_src := Bool(p.properties.Filename_from_src)
Jiyong Park139a2e62018-10-26 21:49:39 +0900119 if filename == "" {
Jiyong Park1a7cf082018-11-13 11:59:12 +0900120 if filename_from_src {
121 filename = p.sourceFilePath.Base()
122 } else {
123 filename = ctx.ModuleName()
124 }
125 } else if filename_from_src {
126 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
127 return
Jiyong Park139a2e62018-10-26 21:49:39 +0900128 }
129 p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800130 p.installDirPath = PathForModuleInstall(ctx, p.installDirBase, String(p.properties.Sub_dir))
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900131
Dan Willemsenb0552672019-01-25 16:04:11 -0800132 // This ensures that outputFilePath has the correct name for others to
133 // use, as the source file may have a different name.
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900134 ctx.Build(pctx, BuildParams{
135 Rule: Cp,
136 Output: p.outputFilePath,
137 Input: p.sourceFilePath,
138 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900139}
140
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900141func (p *PrebuiltEtc) AndroidMk() AndroidMkData {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900142 return AndroidMkData{
143 Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
Tao Bao0ba5c942018-08-14 22:20:22 -0700144 nameSuffix := ""
145 if p.inRecovery() && !p.onlyInRecovery() {
146 nameSuffix = ".recovery"
147 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900148 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
149 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
Tao Bao0ba5c942018-08-14 22:20:22 -0700150 fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900151 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
Anton Hanssonce0e2582019-02-04 14:19:27 +0000152 if p.commonProperties.Owner != nil {
153 fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", *p.commonProperties.Owner)
154 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900155 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
Jaewoong Jung24788182019-02-04 14:34:10 -0800156 if p.Host() {
157 fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
158 }
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900159 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900160 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
Jiyong Park139a2e62018-10-26 21:49:39 +0900161 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
Jiyong Parkad9ce042018-10-31 22:49:57 +0900162 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !p.Installable())
Anton Hansson4ca89892019-01-14 12:17:40 +0000163 fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(data.Required, " "))
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900164 if p.additionalDependencies != nil {
165 fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
166 for _, path := range *p.additionalDependencies {
167 fmt.Fprint(w, " "+path.String())
168 }
169 fmt.Fprintln(w, "")
170 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900171 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
172 },
173 }
174}
175
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900176func InitPrebuiltEtcModule(p *PrebuiltEtc) {
177 p.AddProperties(&p.properties)
178}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900179
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800180// prebuilt_etc is for prebuilts that will be installed to <partition>/etc/<subdir>
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900181func PrebuiltEtcFactory() Module {
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800182 module := &PrebuiltEtc{installDirBase: "etc"}
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900183 InitPrebuiltEtcModule(module)
184 // This module is device-only
Jaewoong Jungb9a11512019-01-15 10:47:05 -0800185 InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900186 return module
187}
Tao Bao0ba5c942018-08-14 22:20:22 -0700188
Jaewoong Jung4b44fcd2019-02-07 08:28:03 -0800189func PrebuiltEtcHostFactory() Module {
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800190 module := &PrebuiltEtc{installDirBase: "etc"}
Jaewoong Jung24788182019-02-04 14:34:10 -0800191 InitPrebuiltEtcModule(module)
192 // This module is host-only
193 InitAndroidArchModule(module, HostSupported, MultilibCommon)
194 return module
195}
196
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800197// prebuilt_usr_share is for prebuilts that will be installed to <partition>/usr/share/<subdir>
198func PrebuiltUserShareFactory() Module {
199 module := &PrebuiltEtc{installDirBase: "usr/share"}
200 InitPrebuiltEtcModule(module)
201 // This module is device-only
202 InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
203 return module
204}
205
Patrice Arruda300cef92019-02-22 15:47:57 -0800206// prebuild_usr_share_host is for host prebuilts that will be installed to <partition>/usr/share/<subdir>
207func PrebuiltUserShareHostFactory() Module {
208 module := &PrebuiltEtc{installDirBase: "usr/share"}
209 InitPrebuiltEtcModule(module)
210 // This module is host-only
211 InitAndroidArchModule(module, HostSupported, MultilibCommon)
212 return module
213}
214
Tao Bao0ba5c942018-08-14 22:20:22 -0700215const (
216 // coreMode is the variant for modules to be installed to system.
217 coreMode = "core"
218
219 // recoveryMode means a module to be installed to recovery image.
220 recoveryMode = "recovery"
221)
222
223// prebuiltEtcMutator creates the needed variants to install the module to
224// system or recovery.
225func prebuiltEtcMutator(mctx BottomUpMutatorContext) {
226 m, ok := mctx.Module().(*PrebuiltEtc)
Jaewoong Jung24788182019-02-04 14:34:10 -0800227 if !ok || m.Host() {
Tao Bao0ba5c942018-08-14 22:20:22 -0700228 return
229 }
230
231 var coreVariantNeeded bool = true
232 var recoveryVariantNeeded bool = false
233 if Bool(m.properties.Recovery_available) {
234 recoveryVariantNeeded = true
235 }
236
237 if m.ModuleBase.InstallInRecovery() {
238 recoveryVariantNeeded = true
239 coreVariantNeeded = false
240 }
241
242 var variants []string
243 if coreVariantNeeded {
244 variants = append(variants, coreMode)
245 }
246 if recoveryVariantNeeded {
247 variants = append(variants, recoveryMode)
248 }
249 mod := mctx.CreateVariations(variants...)
250 for i, v := range variants {
251 if v == recoveryMode {
252 m := mod[i].(*PrebuiltEtc)
253 m.properties.InRecovery = true
254 }
255 }
256}