blob: f7d08ccfb004bd8ef7f4aae9da8dedd56927aa79 [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
22// prebuilt_etc is for prebuilts that will be installed to
23// <partition>/etc/<subdir>
24
25func init() {
26 RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
Tao Bao0ba5c942018-08-14 22:20:22 -070027
28 PreDepsMutators(func(ctx RegisterMutatorsContext) {
29 ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
30 })
Jiyong Parkc678ad32018-04-10 13:07:10 +090031}
32
33type prebuiltEtcProperties struct {
34 // Source file of this prebuilt.
Jiyong Park5a8d1be2018-04-25 22:57:34 +090035 Src *string `android:"arch_variant"`
Jiyong Parkc678ad32018-04-10 13:07:10 +090036
37 // optional subdirectory under which this file is installed into
38 Sub_dir *string `android:"arch_variant"`
Tao Bao0ba5c942018-08-14 22:20:22 -070039
Jiyong Park139a2e62018-10-26 21:49:39 +090040 // optional name for the installed file. If unspecified, name of the module is used as the file name
41 Filename *string `android:"arch_variant"`
42
Jiyong Park1a7cf082018-11-13 11:59:12 +090043 // when set to true, and filename property is not set, the name for the installed file
44 // is the same as the file name of the source file.
45 Filename_from_src *bool `android:"arch_variant"`
46
Tao Bao0ba5c942018-08-14 22:20:22 -070047 // Make this module available when building for recovery.
48 Recovery_available *bool
49
50 InRecovery bool `blueprint:"mutated"`
Jiyong Parkad9ce042018-10-31 22:49:57 +090051
52 // Whether this module is directly installable to one of the partitions. Default: true.
53 Installable *bool
Jiyong Parkc678ad32018-04-10 13:07:10 +090054}
55
Jiyong Park5a8d1be2018-04-25 22:57:34 +090056type PrebuiltEtc struct {
Jiyong Parkc678ad32018-04-10 13:07:10 +090057 ModuleBase
Jiyong Parkc678ad32018-04-10 13:07:10 +090058
59 properties prebuiltEtcProperties
60
Jiyong Park5a8d1be2018-04-25 22:57:34 +090061 sourceFilePath Path
Jiyong Parkc43e0ac2018-10-04 20:27:15 +090062 outputFilePath OutputPath
Jiyong Park5a8d1be2018-04-25 22:57:34 +090063 installDirPath OutputPath
64 additionalDependencies *Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +090065}
66
Tao Bao0ba5c942018-08-14 22:20:22 -070067func (p *PrebuiltEtc) inRecovery() bool {
68 return p.properties.InRecovery || p.ModuleBase.InstallInRecovery()
69}
70
71func (p *PrebuiltEtc) onlyInRecovery() bool {
72 return p.ModuleBase.InstallInRecovery()
73}
74
75func (p *PrebuiltEtc) InstallInRecovery() bool {
76 return p.inRecovery()
77}
78
Jiyong Park5a8d1be2018-04-25 22:57:34 +090079func (p *PrebuiltEtc) DepsMutator(ctx BottomUpMutatorContext) {
80 if p.properties.Src == nil {
81 ctx.PropertyErrorf("src", "missing prebuilt source file")
Jiyong Parkc678ad32018-04-10 13:07:10 +090082 }
83
84 // To support ":modulename" in src
Jiyong Park5a8d1be2018-04-25 22:57:34 +090085 ExtractSourceDeps(ctx, p.properties.Src)
Jiyong Parkc678ad32018-04-10 13:07:10 +090086}
87
Jiyong Park5a8d1be2018-04-25 22:57:34 +090088func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
89 return ctx.ExpandSource(String(p.properties.Src), "src")
90}
91
92// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
93// additional steps (like validating the src) before the file is installed.
94func (p *PrebuiltEtc) SetAdditionalDependencies(paths Paths) {
95 p.additionalDependencies = &paths
96}
97
Jiyong Parkc43e0ac2018-10-04 20:27:15 +090098func (p *PrebuiltEtc) OutputFile() OutputPath {
99 return p.outputFilePath
100}
101
102func (p *PrebuiltEtc) SubDir() string {
103 return String(p.properties.Sub_dir)
104}
105
Jiyong Parkad9ce042018-10-31 22:49:57 +0900106func (p *PrebuiltEtc) Installable() bool {
107 return p.properties.Installable == nil || Bool(p.properties.Installable)
108}
109
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900110func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
111 p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
Jiyong Park139a2e62018-10-26 21:49:39 +0900112 filename := String(p.properties.Filename)
Jiyong Park1a7cf082018-11-13 11:59:12 +0900113 filename_from_src := Bool(p.properties.Filename_from_src)
Jiyong Park139a2e62018-10-26 21:49:39 +0900114 if filename == "" {
Jiyong Park1a7cf082018-11-13 11:59:12 +0900115 if filename_from_src {
116 filename = p.sourceFilePath.Base()
117 } else {
118 filename = ctx.ModuleName()
119 }
120 } else if filename_from_src {
121 ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
122 return
Jiyong Park139a2e62018-10-26 21:49:39 +0900123 }
124 p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900125 p.installDirPath = PathForModuleInstall(ctx, "etc", String(p.properties.Sub_dir))
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900126
127 // This ensures that outputFilePath has the same name as this module.
128 ctx.Build(pctx, BuildParams{
129 Rule: Cp,
130 Output: p.outputFilePath,
131 Input: p.sourceFilePath,
132 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900133}
134
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900135func (p *PrebuiltEtc) AndroidMk() AndroidMkData {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900136 return AndroidMkData{
137 Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
Tao Bao0ba5c942018-08-14 22:20:22 -0700138 nameSuffix := ""
139 if p.inRecovery() && !p.onlyInRecovery() {
140 nameSuffix = ".recovery"
141 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900142 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
143 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
Tao Bao0ba5c942018-08-14 22:20:22 -0700144 fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900145 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
146 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900147 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900148 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
Jiyong Park139a2e62018-10-26 21:49:39 +0900149 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
Jiyong Parkad9ce042018-10-31 22:49:57 +0900150 fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !p.Installable())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900151 if p.additionalDependencies != nil {
152 fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
153 for _, path := range *p.additionalDependencies {
154 fmt.Fprint(w, " "+path.String())
155 }
156 fmt.Fprintln(w, "")
157 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900158 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
159 },
160 }
161}
162
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900163func InitPrebuiltEtcModule(p *PrebuiltEtc) {
164 p.AddProperties(&p.properties)
165}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900166
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900167func PrebuiltEtcFactory() Module {
168 module := &PrebuiltEtc{}
169 InitPrebuiltEtcModule(module)
170 // This module is device-only
171 InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900172 return module
173}
Tao Bao0ba5c942018-08-14 22:20:22 -0700174
175const (
176 // coreMode is the variant for modules to be installed to system.
177 coreMode = "core"
178
179 // recoveryMode means a module to be installed to recovery image.
180 recoveryMode = "recovery"
181)
182
183// prebuiltEtcMutator creates the needed variants to install the module to
184// system or recovery.
185func prebuiltEtcMutator(mctx BottomUpMutatorContext) {
186 m, ok := mctx.Module().(*PrebuiltEtc)
187 if !ok {
188 return
189 }
190
191 var coreVariantNeeded bool = true
192 var recoveryVariantNeeded bool = false
193 if Bool(m.properties.Recovery_available) {
194 recoveryVariantNeeded = true
195 }
196
197 if m.ModuleBase.InstallInRecovery() {
198 recoveryVariantNeeded = true
199 coreVariantNeeded = false
200 }
201
202 var variants []string
203 if coreVariantNeeded {
204 variants = append(variants, coreMode)
205 }
206 if recoveryVariantNeeded {
207 variants = append(variants, recoveryMode)
208 }
209 mod := mctx.CreateVariations(variants...)
210 for i, v := range variants {
211 if v == recoveryMode {
212 m := mod[i].(*PrebuiltEtc)
213 m.properties.InRecovery = true
214 }
215 }
216}