blob: f567a22cc93a899861e99b32b138172c2152e02f [file] [log] [blame]
Inseob Kime498dd92020-08-04 09:24:04 +09001// Copyright 2020 The Android Open Source Project
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.
14package cc
15
16// This file contains image variant related things, including image mutator functions, utility
17// functions to determine where a module is installed, etc.
18
19import (
20 "strings"
21
22 "android/soong/android"
23)
24
25var _ android.ImageInterface = (*Module)(nil)
26
27const (
28 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
29 // against the VNDK.
30 VendorVariationPrefix = "vendor."
31
32 // ProductVariationPrefix is the variant prefix used for /product code that compiles
33 // against the VNDK.
34 ProductVariationPrefix = "product."
35)
36
37func (ctx *moduleContext) ProductSpecific() bool {
38 return ctx.ModuleContext.ProductSpecific() ||
39 (ctx.mod.HasVendorVariant() && ctx.mod.inProduct() && !ctx.mod.IsVndk())
40}
41
42func (ctx *moduleContext) SocSpecific() bool {
43 return ctx.ModuleContext.SocSpecific() ||
44 (ctx.mod.HasVendorVariant() && ctx.mod.inVendor() && !ctx.mod.IsVndk())
45}
46
47func (ctx *moduleContextImpl) inProduct() bool {
48 return ctx.mod.inProduct()
49}
50
51func (ctx *moduleContextImpl) inVendor() bool {
52 return ctx.mod.inVendor()
53}
54
55func (ctx *moduleContextImpl) inRamdisk() bool {
56 return ctx.mod.InRamdisk()
57}
58
59func (ctx *moduleContextImpl) inRecovery() bool {
60 return ctx.mod.InRecovery()
61}
62
63// Returns true only when this module is configured to have core, product and vendor
64// variants.
65func (c *Module) HasVendorVariant() bool {
66 return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
67}
68
69// Returns true if the module is "product" variant. Usually these modules are installed in /product
70func (c *Module) inProduct() bool {
71 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
72}
73
74// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
75func (c *Module) inVendor() bool {
76 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
77}
78
79func (c *Module) InRamdisk() bool {
80 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
81}
82
83func (c *Module) InRecovery() bool {
84 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
85}
86
87func (c *Module) OnlyInRamdisk() bool {
88 return c.ModuleBase.InstallInRamdisk()
89}
90
91func (c *Module) OnlyInRecovery() bool {
92 return c.ModuleBase.InstallInRecovery()
93}
94
95func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
96 // Validation check
97 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
98 productSpecific := mctx.ProductSpecific()
99
100 if m.VendorProperties.Vendor_available != nil && vendorSpecific {
101 mctx.PropertyErrorf("vendor_available",
102 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
103 }
104
105 if vndkdep := m.vndkdep; vndkdep != nil {
106 if vndkdep.isVndk() {
107 if vendorSpecific || productSpecific {
108 if !vndkdep.isVndkExt() {
109 mctx.PropertyErrorf("vndk",
110 "must set `extends: \"...\"` to vndk extension")
111 } else if m.VendorProperties.Vendor_available != nil {
112 mctx.PropertyErrorf("vendor_available",
113 "must not set at the same time as `vndk: {extends: \"...\"}`")
114 }
115 } else {
116 if vndkdep.isVndkExt() {
117 mctx.PropertyErrorf("vndk",
118 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
119 m.getVndkExtendsModuleName())
120 }
121 if m.VendorProperties.Vendor_available == nil {
122 mctx.PropertyErrorf("vndk",
123 "vendor_available must be set to either true or false when `vndk: {enabled: true}`")
124 }
125 }
126 } else {
127 if vndkdep.isVndkSp() {
128 mctx.PropertyErrorf("vndk",
129 "must set `enabled: true` to set `support_system_process: true`")
130 }
131 if vndkdep.isVndkExt() {
132 mctx.PropertyErrorf("vndk",
133 "must set `enabled: true` to set `extends: %q`",
134 m.getVndkExtendsModuleName())
135 }
136 }
137 }
138
139 var coreVariantNeeded bool = false
140 var ramdiskVariantNeeded bool = false
141 var recoveryVariantNeeded bool = false
142
143 var vendorVariants []string
144 var productVariants []string
145
146 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
147 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
148 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
149 if boardVndkVersion == "current" {
150 boardVndkVersion = platformVndkVersion
151 }
152 if productVndkVersion == "current" {
153 productVndkVersion = platformVndkVersion
154 }
155
156 if boardVndkVersion == "" {
157 // If the device isn't compiling against the VNDK, we always
158 // use the core mode.
159 coreVariantNeeded = true
160 } else if _, ok := m.linker.(*llndkStubDecorator); ok {
161 // LL-NDK stubs only exist in the vendor and product variants,
162 // since the real libraries will be used in the core variant.
163 vendorVariants = append(vendorVariants,
164 platformVndkVersion,
165 boardVndkVersion,
166 )
167 productVariants = append(productVariants,
168 platformVndkVersion,
169 productVndkVersion,
170 )
171 } else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
172 // ... and LL-NDK headers as well
173 vendorVariants = append(vendorVariants,
174 platformVndkVersion,
175 boardVndkVersion,
176 )
177 productVariants = append(productVariants,
178 platformVndkVersion,
179 productVndkVersion,
180 )
181 } else if m.isSnapshotPrebuilt() {
182 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
183 // PRODUCT_EXTRA_VNDK_VERSIONS.
184 if snapshot, ok := m.linker.(interface {
185 version() string
186 }); ok {
187 vendorVariants = append(vendorVariants, snapshot.version())
188 } else {
189 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
190 }
191 } else if m.HasVendorVariant() && !m.isVndkExt() {
192 // This will be available in /system, /vendor and /product
193 // or a /system directory that is available to vendor and product.
194 coreVariantNeeded = true
195
196 // We assume that modules under proprietary paths are compatible for
197 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
198 // PLATFORM_VNDK_VERSION.
199 if isVendorProprietaryPath(mctx.ModuleDir()) {
200 vendorVariants = append(vendorVariants, boardVndkVersion)
201 } else {
202 vendorVariants = append(vendorVariants, platformVndkVersion)
203 }
204
205 // vendor_available modules are also available to /product.
206 productVariants = append(productVariants, platformVndkVersion)
207 // VNDK is always PLATFORM_VNDK_VERSION
208 if !m.IsVndk() {
209 productVariants = append(productVariants, productVndkVersion)
210 }
211 } else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
212 // This will be available in /vendor (or /odm) only
213
214 // kernel_headers is a special module type whose exported headers
215 // are coming from DeviceKernelHeaders() which is always vendor
216 // dependent. They'll always have both vendor variants.
217 // For other modules, we assume that modules under proprietary
218 // paths are compatible for BOARD_VNDK_VERSION. The other modules
219 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
220 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
221 vendorVariants = append(vendorVariants,
222 platformVndkVersion,
223 boardVndkVersion,
224 )
225 } else if isVendorProprietaryPath(mctx.ModuleDir()) {
226 vendorVariants = append(vendorVariants, boardVndkVersion)
227 } else {
228 vendorVariants = append(vendorVariants, platformVndkVersion)
229 }
230 } else {
231 // This is either in /system (or similar: /data), or is a
232 // modules built with the NDK. Modules built with the NDK
233 // will be restricted using the existing link type checks.
234 coreVariantNeeded = true
235 }
236
237 if boardVndkVersion != "" && productVndkVersion != "" {
238 if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" {
239 // The module has "product_specific: true" that does not create core variant.
240 coreVariantNeeded = false
241 productVariants = append(productVariants, productVndkVersion)
242 }
243 } else {
244 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
245 // restriction to use system libs.
246 // No product variants defined in this case.
247 productVariants = []string{}
248 }
249
250 if Bool(m.Properties.Ramdisk_available) {
251 ramdiskVariantNeeded = true
252 }
253
254 if m.ModuleBase.InstallInRamdisk() {
255 ramdiskVariantNeeded = true
256 coreVariantNeeded = false
257 }
258
259 if Bool(m.Properties.Recovery_available) {
260 recoveryVariantNeeded = true
261 }
262
263 if m.ModuleBase.InstallInRecovery() {
264 recoveryVariantNeeded = true
265 coreVariantNeeded = false
266 }
267
268 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
269 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant)
270 }
271
272 for _, variant := range android.FirstUniqueStrings(productVariants) {
273 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant)
274 }
275
276 m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded
277 m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded
278 m.Properties.CoreVariantNeeded = coreVariantNeeded
279}
280
281func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
282 return c.Properties.CoreVariantNeeded
283}
284
285func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
286 return c.Properties.RamdiskVariantNeeded
287}
288
289func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
290 return c.Properties.RecoveryVariantNeeded
291}
292
293func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
294 return c.Properties.ExtraVariants
295}
296
297func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
298 m := module.(*Module)
299 if variant == android.RamdiskVariation {
300 m.MakeAsPlatform()
301 } else if variant == android.RecoveryVariation {
302 m.MakeAsPlatform()
303 squashRecoverySrcs(m)
304 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
305 m.Properties.ImageVariationPrefix = VendorVariationPrefix
306 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
307 squashVendorSrcs(m)
308
309 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
310 // Hide other vendor variants to avoid collision.
311 vndkVersion := ctx.DeviceConfig().VndkVersion()
312 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
313 m.Properties.HideFromMake = true
314 m.SkipInstall()
315 }
316 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
317 m.Properties.ImageVariationPrefix = ProductVariationPrefix
318 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
319 squashVendorSrcs(m)
320 }
321}