blob: ba091e13cf2a374be22e4427abcad3a7ec717124 [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
Inseob Kim74d25562020-08-04 00:41:38 +090027type imageVariantType string
28
29const (
Yifan Hong60e0cfb2020-10-21 15:17:56 -070030 coreImageVariant imageVariantType = "core"
31 vendorImageVariant imageVariantType = "vendor"
32 productImageVariant imageVariantType = "product"
33 ramdiskImageVariant imageVariantType = "ramdisk"
34 vendorRamdiskImageVariant imageVariantType = "vendor_ramdisk"
35 recoveryImageVariant imageVariantType = "recovery"
36 hostImageVariant imageVariantType = "host"
Inseob Kim74d25562020-08-04 00:41:38 +090037)
38
39func (c *Module) getImageVariantType() imageVariantType {
40 if c.Host() {
41 return hostImageVariant
42 } else if c.inVendor() {
43 return vendorImageVariant
44 } else if c.inProduct() {
45 return productImageVariant
46 } else if c.InRamdisk() {
47 return ramdiskImageVariant
Yifan Hong60e0cfb2020-10-21 15:17:56 -070048 } else if c.InVendorRamdisk() {
49 return vendorRamdiskImageVariant
Inseob Kim74d25562020-08-04 00:41:38 +090050 } else if c.InRecovery() {
51 return recoveryImageVariant
52 } else {
53 return coreImageVariant
54 }
55}
56
Inseob Kime498dd92020-08-04 09:24:04 +090057const (
58 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
59 // against the VNDK.
60 VendorVariationPrefix = "vendor."
61
62 // ProductVariationPrefix is the variant prefix used for /product code that compiles
63 // against the VNDK.
64 ProductVariationPrefix = "product."
65)
66
67func (ctx *moduleContext) ProductSpecific() bool {
68 return ctx.ModuleContext.ProductSpecific() ||
Justin Yun543f60b2020-10-18 10:54:31 +090069 (ctx.mod.HasVendorVariant() && ctx.mod.inProduct())
Inseob Kime498dd92020-08-04 09:24:04 +090070}
71
72func (ctx *moduleContext) SocSpecific() bool {
73 return ctx.ModuleContext.SocSpecific() ||
Justin Yun543f60b2020-10-18 10:54:31 +090074 (ctx.mod.HasVendorVariant() && ctx.mod.inVendor())
Inseob Kime498dd92020-08-04 09:24:04 +090075}
76
77func (ctx *moduleContextImpl) inProduct() bool {
78 return ctx.mod.inProduct()
79}
80
81func (ctx *moduleContextImpl) inVendor() bool {
82 return ctx.mod.inVendor()
83}
84
85func (ctx *moduleContextImpl) inRamdisk() bool {
86 return ctx.mod.InRamdisk()
87}
88
Yifan Hong60e0cfb2020-10-21 15:17:56 -070089func (ctx *moduleContextImpl) inVendorRamdisk() bool {
90 return ctx.mod.InVendorRamdisk()
91}
92
Inseob Kime498dd92020-08-04 09:24:04 +090093func (ctx *moduleContextImpl) inRecovery() bool {
94 return ctx.mod.InRecovery()
95}
96
97// Returns true only when this module is configured to have core, product and vendor
98// variants.
99func (c *Module) HasVendorVariant() bool {
100 return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
101}
102
103// Returns true if the module is "product" variant. Usually these modules are installed in /product
104func (c *Module) inProduct() bool {
105 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
106}
107
108// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
109func (c *Module) inVendor() bool {
110 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
111}
112
113func (c *Module) InRamdisk() bool {
114 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
115}
116
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700117func (c *Module) InVendorRamdisk() bool {
118 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
119}
120
Inseob Kime498dd92020-08-04 09:24:04 +0900121func (c *Module) InRecovery() bool {
122 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
123}
124
125func (c *Module) OnlyInRamdisk() bool {
126 return c.ModuleBase.InstallInRamdisk()
127}
128
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700129func (c *Module) OnlyInVendorRamdisk() bool {
130 return c.ModuleBase.InstallInVendorRamdisk()
131}
132
Inseob Kime498dd92020-08-04 09:24:04 +0900133func (c *Module) OnlyInRecovery() bool {
134 return c.ModuleBase.InstallInRecovery()
135}
136
137func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
138 // Validation check
139 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
140 productSpecific := mctx.ProductSpecific()
141
142 if m.VendorProperties.Vendor_available != nil && vendorSpecific {
143 mctx.PropertyErrorf("vendor_available",
144 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
145 }
146
147 if vndkdep := m.vndkdep; vndkdep != nil {
148 if vndkdep.isVndk() {
149 if vendorSpecific || productSpecific {
150 if !vndkdep.isVndkExt() {
151 mctx.PropertyErrorf("vndk",
152 "must set `extends: \"...\"` to vndk extension")
153 } else if m.VendorProperties.Vendor_available != nil {
154 mctx.PropertyErrorf("vendor_available",
155 "must not set at the same time as `vndk: {extends: \"...\"}`")
156 }
157 } else {
158 if vndkdep.isVndkExt() {
159 mctx.PropertyErrorf("vndk",
160 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
161 m.getVndkExtendsModuleName())
162 }
163 if m.VendorProperties.Vendor_available == nil {
164 mctx.PropertyErrorf("vndk",
165 "vendor_available must be set to either true or false when `vndk: {enabled: true}`")
166 }
167 }
168 } else {
169 if vndkdep.isVndkSp() {
170 mctx.PropertyErrorf("vndk",
171 "must set `enabled: true` to set `support_system_process: true`")
172 }
173 if vndkdep.isVndkExt() {
174 mctx.PropertyErrorf("vndk",
175 "must set `enabled: true` to set `extends: %q`",
176 m.getVndkExtendsModuleName())
177 }
178 }
179 }
180
181 var coreVariantNeeded bool = false
182 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700183 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900184 var recoveryVariantNeeded bool = false
185
186 var vendorVariants []string
187 var productVariants []string
188
189 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
190 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
191 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
192 if boardVndkVersion == "current" {
193 boardVndkVersion = platformVndkVersion
194 }
195 if productVndkVersion == "current" {
196 productVndkVersion = platformVndkVersion
197 }
198
199 if boardVndkVersion == "" {
200 // If the device isn't compiling against the VNDK, we always
201 // use the core mode.
202 coreVariantNeeded = true
203 } else if _, ok := m.linker.(*llndkStubDecorator); ok {
204 // LL-NDK stubs only exist in the vendor and product variants,
205 // since the real libraries will be used in the core variant.
206 vendorVariants = append(vendorVariants,
207 platformVndkVersion,
208 boardVndkVersion,
209 )
210 productVariants = append(productVariants,
211 platformVndkVersion,
212 productVndkVersion,
213 )
214 } else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
215 // ... and LL-NDK headers as well
216 vendorVariants = append(vendorVariants,
217 platformVndkVersion,
218 boardVndkVersion,
219 )
220 productVariants = append(productVariants,
221 platformVndkVersion,
222 productVndkVersion,
223 )
224 } else if m.isSnapshotPrebuilt() {
225 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
226 // PRODUCT_EXTRA_VNDK_VERSIONS.
227 if snapshot, ok := m.linker.(interface {
228 version() string
229 }); ok {
230 vendorVariants = append(vendorVariants, snapshot.version())
231 } else {
232 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
233 }
234 } else if m.HasVendorVariant() && !m.isVndkExt() {
235 // This will be available in /system, /vendor and /product
236 // or a /system directory that is available to vendor and product.
237 coreVariantNeeded = true
238
239 // We assume that modules under proprietary paths are compatible for
240 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
241 // PLATFORM_VNDK_VERSION.
Bill Peckham945441c2020-08-31 16:07:58 -0700242 if isVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900243 vendorVariants = append(vendorVariants, boardVndkVersion)
244 } else {
245 vendorVariants = append(vendorVariants, platformVndkVersion)
246 }
247
248 // vendor_available modules are also available to /product.
249 productVariants = append(productVariants, platformVndkVersion)
250 // VNDK is always PLATFORM_VNDK_VERSION
251 if !m.IsVndk() {
252 productVariants = append(productVariants, productVndkVersion)
253 }
254 } else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
255 // This will be available in /vendor (or /odm) only
256
257 // kernel_headers is a special module type whose exported headers
258 // are coming from DeviceKernelHeaders() which is always vendor
259 // dependent. They'll always have both vendor variants.
260 // For other modules, we assume that modules under proprietary
261 // paths are compatible for BOARD_VNDK_VERSION. The other modules
262 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
263 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
264 vendorVariants = append(vendorVariants,
265 platformVndkVersion,
266 boardVndkVersion,
267 )
Bill Peckham945441c2020-08-31 16:07:58 -0700268 } else if isVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900269 vendorVariants = append(vendorVariants, boardVndkVersion)
270 } else {
271 vendorVariants = append(vendorVariants, platformVndkVersion)
272 }
273 } else {
274 // This is either in /system (or similar: /data), or is a
275 // modules built with the NDK. Modules built with the NDK
276 // will be restricted using the existing link type checks.
277 coreVariantNeeded = true
278 }
279
280 if boardVndkVersion != "" && productVndkVersion != "" {
281 if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" {
282 // The module has "product_specific: true" that does not create core variant.
283 coreVariantNeeded = false
284 productVariants = append(productVariants, productVndkVersion)
285 }
286 } else {
287 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
288 // restriction to use system libs.
289 // No product variants defined in this case.
290 productVariants = []string{}
291 }
292
293 if Bool(m.Properties.Ramdisk_available) {
294 ramdiskVariantNeeded = true
295 }
296
297 if m.ModuleBase.InstallInRamdisk() {
298 ramdiskVariantNeeded = true
299 coreVariantNeeded = false
300 }
301
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700302 if Bool(m.Properties.Vendor_ramdisk_available) {
303 vendorRamdiskVariantNeeded = true
304 }
305
306 if m.ModuleBase.InstallInVendorRamdisk() {
307 vendorRamdiskVariantNeeded = true
308 coreVariantNeeded = false
309 }
310
Inseob Kime498dd92020-08-04 09:24:04 +0900311 if Bool(m.Properties.Recovery_available) {
312 recoveryVariantNeeded = true
313 }
314
315 if m.ModuleBase.InstallInRecovery() {
316 recoveryVariantNeeded = true
317 coreVariantNeeded = false
318 }
319
320 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
321 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant)
322 }
323
324 for _, variant := range android.FirstUniqueStrings(productVariants) {
325 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant)
326 }
327
328 m.Properties.RamdiskVariantNeeded = ramdiskVariantNeeded
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700329 m.Properties.VendorRamdiskVariantNeeded = vendorRamdiskVariantNeeded
Inseob Kime498dd92020-08-04 09:24:04 +0900330 m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded
331 m.Properties.CoreVariantNeeded = coreVariantNeeded
332}
333
334func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
335 return c.Properties.CoreVariantNeeded
336}
337
338func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
339 return c.Properties.RamdiskVariantNeeded
340}
341
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700342func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
343 return c.Properties.VendorRamdiskVariantNeeded
344}
345
Inseob Kime498dd92020-08-04 09:24:04 +0900346func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
347 return c.Properties.RecoveryVariantNeeded
348}
349
350func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
351 return c.Properties.ExtraVariants
352}
353
354func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
355 m := module.(*Module)
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700356 if variant == android.RamdiskVariation || variant == android.VendorRamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900357 m.MakeAsPlatform()
358 } else if variant == android.RecoveryVariation {
359 m.MakeAsPlatform()
360 squashRecoverySrcs(m)
361 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
362 m.Properties.ImageVariationPrefix = VendorVariationPrefix
363 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
364 squashVendorSrcs(m)
365
366 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
367 // Hide other vendor variants to avoid collision.
368 vndkVersion := ctx.DeviceConfig().VndkVersion()
369 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
370 m.Properties.HideFromMake = true
371 m.SkipInstall()
372 }
373 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
374 m.Properties.ImageVariationPrefix = ProductVariationPrefix
375 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
376 squashVendorSrcs(m)
377 }
378}