blob: cc1f84616c8f4515ed4a1a86242535628a41be2c [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
Tao Bao0ba5c942018-08-14 22:20:22 -070043 // Make this module available when building for recovery.
44 Recovery_available *bool
45
46 InRecovery bool `blueprint:"mutated"`
Jiyong Parkc678ad32018-04-10 13:07:10 +090047}
48
Jiyong Park5a8d1be2018-04-25 22:57:34 +090049type PrebuiltEtc struct {
Jiyong Parkc678ad32018-04-10 13:07:10 +090050 ModuleBase
Jiyong Parkc678ad32018-04-10 13:07:10 +090051
52 properties prebuiltEtcProperties
53
Jiyong Park5a8d1be2018-04-25 22:57:34 +090054 sourceFilePath Path
Jiyong Parkc43e0ac2018-10-04 20:27:15 +090055 outputFilePath OutputPath
Jiyong Park5a8d1be2018-04-25 22:57:34 +090056 installDirPath OutputPath
57 additionalDependencies *Paths
Jiyong Parkc678ad32018-04-10 13:07:10 +090058}
59
Tao Bao0ba5c942018-08-14 22:20:22 -070060func (p *PrebuiltEtc) inRecovery() bool {
61 return p.properties.InRecovery || p.ModuleBase.InstallInRecovery()
62}
63
64func (p *PrebuiltEtc) onlyInRecovery() bool {
65 return p.ModuleBase.InstallInRecovery()
66}
67
68func (p *PrebuiltEtc) InstallInRecovery() bool {
69 return p.inRecovery()
70}
71
Jiyong Park5a8d1be2018-04-25 22:57:34 +090072func (p *PrebuiltEtc) DepsMutator(ctx BottomUpMutatorContext) {
73 if p.properties.Src == nil {
74 ctx.PropertyErrorf("src", "missing prebuilt source file")
Jiyong Parkc678ad32018-04-10 13:07:10 +090075 }
76
77 // To support ":modulename" in src
Jiyong Park5a8d1be2018-04-25 22:57:34 +090078 ExtractSourceDeps(ctx, p.properties.Src)
Jiyong Parkc678ad32018-04-10 13:07:10 +090079}
80
Jiyong Park5a8d1be2018-04-25 22:57:34 +090081func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
82 return ctx.ExpandSource(String(p.properties.Src), "src")
83}
84
85// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
86// additional steps (like validating the src) before the file is installed.
87func (p *PrebuiltEtc) SetAdditionalDependencies(paths Paths) {
88 p.additionalDependencies = &paths
89}
90
Jiyong Parkc43e0ac2018-10-04 20:27:15 +090091func (p *PrebuiltEtc) OutputFile() OutputPath {
92 return p.outputFilePath
93}
94
95func (p *PrebuiltEtc) SubDir() string {
96 return String(p.properties.Sub_dir)
97}
98
Jiyong Park5a8d1be2018-04-25 22:57:34 +090099func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
100 p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
Jiyong Park139a2e62018-10-26 21:49:39 +0900101 filename := String(p.properties.Filename)
102 if filename == "" {
103 filename = ctx.ModuleName()
104 }
105 p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
Jiyong Parkc678ad32018-04-10 13:07:10 +0900106 p.installDirPath = PathForModuleInstall(ctx, "etc", String(p.properties.Sub_dir))
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900107
108 // This ensures that outputFilePath has the same name as this module.
109 ctx.Build(pctx, BuildParams{
110 Rule: Cp,
111 Output: p.outputFilePath,
112 Input: p.sourceFilePath,
113 })
Jiyong Parkc678ad32018-04-10 13:07:10 +0900114}
115
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900116func (p *PrebuiltEtc) AndroidMk() AndroidMkData {
Jiyong Parkc678ad32018-04-10 13:07:10 +0900117 return AndroidMkData{
118 Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
Tao Bao0ba5c942018-08-14 22:20:22 -0700119 nameSuffix := ""
120 if p.inRecovery() && !p.onlyInRecovery() {
121 nameSuffix = ".recovery"
122 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900123 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
124 fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
Tao Bao0ba5c942018-08-14 22:20:22 -0700125 fmt.Fprintln(w, "LOCAL_MODULE :=", name+nameSuffix)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900126 fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
127 fmt.Fprintln(w, "LOCAL_MODULE_TAGS := optional")
Jiyong Parkc43e0ac2018-10-04 20:27:15 +0900128 fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", p.outputFilePath.String())
Jiyong Parkc678ad32018-04-10 13:07:10 +0900129 fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", "$(OUT_DIR)/"+p.installDirPath.RelPathString())
Jiyong Park139a2e62018-10-26 21:49:39 +0900130 fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", p.outputFilePath.Base())
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900131 if p.additionalDependencies != nil {
132 fmt.Fprint(w, "LOCAL_ADDITIONAL_DEPENDENCIES :=")
133 for _, path := range *p.additionalDependencies {
134 fmt.Fprint(w, " "+path.String())
135 }
136 fmt.Fprintln(w, "")
137 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900138 fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
139 },
140 }
141}
142
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900143func InitPrebuiltEtcModule(p *PrebuiltEtc) {
144 p.AddProperties(&p.properties)
145}
Jiyong Parkc678ad32018-04-10 13:07:10 +0900146
Jiyong Park5a8d1be2018-04-25 22:57:34 +0900147func PrebuiltEtcFactory() Module {
148 module := &PrebuiltEtc{}
149 InitPrebuiltEtcModule(module)
150 // This module is device-only
151 InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
Jiyong Parkc678ad32018-04-10 13:07:10 +0900152 return module
153}
Tao Bao0ba5c942018-08-14 22:20:22 -0700154
155const (
156 // coreMode is the variant for modules to be installed to system.
157 coreMode = "core"
158
159 // recoveryMode means a module to be installed to recovery image.
160 recoveryMode = "recovery"
161)
162
163// prebuiltEtcMutator creates the needed variants to install the module to
164// system or recovery.
165func prebuiltEtcMutator(mctx BottomUpMutatorContext) {
166 m, ok := mctx.Module().(*PrebuiltEtc)
167 if !ok {
168 return
169 }
170
171 var coreVariantNeeded bool = true
172 var recoveryVariantNeeded bool = false
173 if Bool(m.properties.Recovery_available) {
174 recoveryVariantNeeded = true
175 }
176
177 if m.ModuleBase.InstallInRecovery() {
178 recoveryVariantNeeded = true
179 coreVariantNeeded = false
180 }
181
182 var variants []string
183 if coreVariantNeeded {
184 variants = append(variants, coreMode)
185 }
186 if recoveryVariantNeeded {
187 variants = append(variants, recoveryMode)
188 }
189 mod := mctx.CreateVariations(variants...)
190 for i, v := range variants {
191 if v == recoveryMode {
192 m := mod[i].(*PrebuiltEtc)
193 m.properties.InRecovery = true
194 }
195 }
196}