blob: 3cadaeb22b5c78e41f99b4a50334d7897b2a4c14 [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"
20)
21
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -080022// TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file.
Jiyong Parkc678ad32018-04-10 13:07:10 +090023
24func init() {
25 RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
Jaewoong Jung4b44fcd2019-02-07 08:28:03 -080026 RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -080027 RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
Patrice Arruda300cef92019-02-22 15:47:57 -080028 RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
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.
Colin Cross27b922f2019-03-04 22:35:41 -080037 Src *string `android:"path,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 }
Jiyong Parkc678ad32018-04-10 13:07:10 +090087}
88
Jiyong Park5a8d1be2018-04-25 22:57:34 +090089func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
Colin Cross8a497952019-03-05 22:25:09 -080090 return PathForModuleSrc(ctx, String(p.properties.Src))
Jiyong Park5a8d1be2018-04-25 22:57:34 +090091}
92
93// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
94// additional steps (like validating the src) before the file is installed.
95func (p *PrebuiltEtc) SetAdditionalDependencies(paths Paths) {
96 p.additionalDependencies = &paths
97}
98
Jiyong Parkc43e0ac2018-10-04 20:27:15 +090099func (p *PrebuiltEtc) OutputFile() OutputPath {
100 return p.outputFilePath
101}
102
103func (p *PrebuiltEtc) SubDir() string {
104 return String(p.properties.Sub_dir)
105}
106
Jiyong Parkad9ce042018-10-31 22:49:57 +0900107func (p *PrebuiltEtc) Installable() bool {
108 return p.properties.Installable == nil || Bool(p.properties.Installable)
109}
110
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900111func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
Colin Cross8a497952019-03-05 22:25:09 -0800112 p.sourceFilePath = PathForModuleSrc(ctx, String(p.properties.Src))
Jiyong Park139a2e62018-10-26 21:49:39 +0900113 filename := String(p.properties.Filename)
Jiyong Park1a7cf082018-11-13 11:59:12 +0900114 filename_from_src := Bool(p.properties.Filename_from_src)
Jiyong Park139a2e62018-10-26 21:49:39 +0900115 if filename == "" {
Jiyong Park1a7cf082018-11-13 11:59:12 +0900116 if filename_from_src {
117 filename = p.sourceFilePath.Base()
118 } else {
119 filename = ctx.ModuleName()
120 }
121 } else if filename_from_src {
122 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
123 return
Jiyong Park139a2e62018-10-26 21:49:39 +0900124 }
125 p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800126 p.installDirPath = PathForModuleInstall(ctx, p.installDirBase, String(p.properties.Sub_dir))
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900127
Dan Willemsenb0552672019-01-25 16:04:11 -0800128 // This ensures that outputFilePath has the correct name for others to
129 // use, as the source file may have a different name.
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900130 ctx.Build(pctx, BuildParams{
131 Rule: Cp,
132 Output: p.outputFilePath,
133 Input: p.sourceFilePath,
134 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900135}
136
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900137func (p *PrebuiltEtc) AndroidMk() AndroidMkData {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900138 return AndroidMkData{
139 Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
Tao Bao0ba5c942018-08-14 22:20:22 -0700140 nameSuffix := ""
141 if p.inRecovery() && !p.onlyInRecovery() {
142 nameSuffix = ".recovery"
143 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900144 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
145 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
Tao Bao0ba5c942018-08-14 22:20:22 -0700146 fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900147 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
Anton Hanssonce0e2582019-02-04 14:19:27 +0000148 if p.commonProperties.Owner != nil {
149 fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", *p.commonProperties.Owner)
150 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900151 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
Jaewoong Jung24788182019-02-04 14:34:10 -0800152 if p.Host() {
153 fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
154 }
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900155 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900156 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
Jiyong Park139a2e62018-10-26 21:49:39 +0900157 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
Jiyong Parkad9ce042018-10-31 22:49:57 +0900158 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !p.Installable())
Sasha Smundakb6d23052019-04-01 18:37:36 -0700159 WriteRequiredModulesSettings(w, data)
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900160 if p.additionalDependencies != nil {
161 fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
162 for _, path := range *p.additionalDependencies {
163 fmt.Fprint(w, " "+path.String())
164 }
165 fmt.Fprintln(w, "")
166 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900167 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
168 },
169 }
170}
171
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900172func InitPrebuiltEtcModule(p *PrebuiltEtc) {
173 p.AddProperties(&p.properties)
174}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900175
Patrice Arruda9e14b962019-03-11 15:58:50 -0700176// prebuilt_etc is for a prebuilt artifact that is installed in
177// <partition>/etc/<sub_dir> directory.
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900178func PrebuiltEtcFactory() Module {
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800179 module := &PrebuiltEtc{installDirBase: "etc"}
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900180 InitPrebuiltEtcModule(module)
181 // This module is device-only
Jaewoong Jungb9a11512019-01-15 10:47:05 -0800182 InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900183 return module
184}
Tao Bao0ba5c942018-08-14 22:20:22 -0700185
Patrice Arruda9e14b962019-03-11 15:58:50 -0700186// prebuilt_etc_host is for a host prebuilt artifact that is installed in
187// $(HOST_OUT)/etc/<sub_dir> directory.
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
Patrice Arruda9e14b962019-03-11 15:58:50 -0700196// prebuilt_usr_share is for a prebuilt artifact that is installed in
197// <partition>/usr/share/<sub_dir> directory.
Jaewoong Jungc3fcdb42019-02-13 05:50:33 -0800198func 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 Arruda9e14b962019-03-11 15:58:50 -0700206// prebuild_usr_share_host is for a host prebuilt artifact that is installed in
207// $(HOST_OUT)/usr/share/<sub_dir> directory.
Patrice Arruda300cef92019-02-22 15:47:57 -0800208func PrebuiltUserShareHostFactory() Module {
209 module := &PrebuiltEtc{installDirBase: "usr/share"}
210 InitPrebuiltEtcModule(module)
211 // This module is host-only
212 InitAndroidArchModule(module, HostSupported, MultilibCommon)
213 return module
214}
215
Tao Bao0ba5c942018-08-14 22:20:22 -0700216const (
217 // coreMode is the variant for modules to be installed to system.
218 coreMode = "core"
219
220 // recoveryMode means a module to be installed to recovery image.
221 recoveryMode = "recovery"
222)
223
224// prebuiltEtcMutator creates the needed variants to install the module to
225// system or recovery.
226func prebuiltEtcMutator(mctx BottomUpMutatorContext) {
227 m, ok := mctx.Module().(*PrebuiltEtc)
Jaewoong Jung24788182019-02-04 14:34:10 -0800228 if !ok || m.Host() {
Tao Bao0ba5c942018-08-14 22:20:22 -0700229 return
230 }
231
232 var coreVariantNeeded bool = true
233 var recoveryVariantNeeded bool = false
234 if Bool(m.properties.Recovery_available) {
235 recoveryVariantNeeded = true
236 }
237
238 if m.ModuleBase.InstallInRecovery() {
239 recoveryVariantNeeded = true
240 coreVariantNeeded = false
241 }
242
243 var variants []string
244 if coreVariantNeeded {
245 variants = append(variants, coreMode)
246 }
247 if recoveryVariantNeeded {
248 variants = append(variants, recoveryMode)
249 }
250 mod := mctx.CreateVariations(variants...)
251 for i, v := range variants {
252 if v == recoveryMode {
253 m := mod[i].(*PrebuiltEtc)
254 m.properties.InRecovery = true
255 }
256 }
257}