blob: cb8589db59352c7cc69abe1e0e44cf5673ecf1f1 [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 (
Justin Yun6977e8a2020-10-29 18:24:11 +090020 "fmt"
21 "reflect"
Inseob Kime498dd92020-08-04 09:24:04 +090022 "strings"
23
24 "android/soong/android"
25)
26
27var _ android.ImageInterface = (*Module)(nil)
28
Ivan Lozano3968d8f2020-12-14 11:27:52 -050029type ImageVariantType string
Inseob Kim74d25562020-08-04 00:41:38 +090030
31const (
Ivan Lozano3968d8f2020-12-14 11:27:52 -050032 coreImageVariant ImageVariantType = "core"
33 vendorImageVariant ImageVariantType = "vendor"
34 productImageVariant ImageVariantType = "product"
35 ramdiskImageVariant ImageVariantType = "ramdisk"
36 vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk"
37 recoveryImageVariant ImageVariantType = "recovery"
38 hostImageVariant ImageVariantType = "host"
Inseob Kim74d25562020-08-04 00:41:38 +090039)
40
Inseob Kime498dd92020-08-04 09:24:04 +090041const (
42 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
43 // against the VNDK.
44 VendorVariationPrefix = "vendor."
45
46 // ProductVariationPrefix is the variant prefix used for /product code that compiles
47 // against the VNDK.
48 ProductVariationPrefix = "product."
49)
50
51func (ctx *moduleContext) ProductSpecific() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +090052 // Additionally check if this module is inProduct() that means it is a "product" variant of a
53 // module. As well as product specific modules, product variants must be installed to /product.
54 return ctx.ModuleContext.ProductSpecific() || ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090055}
56
57func (ctx *moduleContext) SocSpecific() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +090058 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a
Justin Yunebcf0c52021-01-08 18:00:19 +090059 // module. As well as SoC specific modules, vendor variants must be installed to /vendor
60 // unless they have "odm_available: true".
61 return ctx.ModuleContext.SocSpecific() || (ctx.mod.InVendor() && !ctx.mod.VendorVariantToOdm())
62}
63
64func (ctx *moduleContext) DeviceSpecific() bool {
65 // Some vendor variants want to be installed to /odm by setting "odm_available: true".
66 return ctx.ModuleContext.DeviceSpecific() || (ctx.mod.InVendor() && ctx.mod.VendorVariantToOdm())
Inseob Kime498dd92020-08-04 09:24:04 +090067}
68
69func (ctx *moduleContextImpl) inProduct() bool {
Ivan Lozanof9e21722020-12-02 09:00:51 -050070 return ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090071}
72
73func (ctx *moduleContextImpl) inVendor() bool {
Ivan Lozano3968d8f2020-12-14 11:27:52 -050074 return ctx.mod.InVendor()
Inseob Kime498dd92020-08-04 09:24:04 +090075}
76
77func (ctx *moduleContextImpl) inRamdisk() bool {
78 return ctx.mod.InRamdisk()
79}
80
Yifan Hong60e0cfb2020-10-21 15:17:56 -070081func (ctx *moduleContextImpl) inVendorRamdisk() bool {
82 return ctx.mod.InVendorRamdisk()
83}
84
Inseob Kime498dd92020-08-04 09:24:04 +090085func (ctx *moduleContextImpl) inRecovery() bool {
86 return ctx.mod.InRecovery()
87}
88
Justin Yun63e9ec72020-10-29 16:49:43 +090089// Returns true when this module is configured to have core and vendor variants.
Inseob Kime498dd92020-08-04 09:24:04 +090090func (c *Module) HasVendorVariant() bool {
Justin Yunebcf0c52021-01-08 18:00:19 +090091 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
92}
93
94// Returns true when this module creates a vendor variant and wants to install the vendor variant
95// to the odm partition.
96func (c *Module) VendorVariantToOdm() bool {
97 return Bool(c.VendorProperties.Odm_available)
Inseob Kime498dd92020-08-04 09:24:04 +090098}
99
Justin Yun63e9ec72020-10-29 16:49:43 +0900100// Returns true when this module is configured to have core and product variants.
101func (c *Module) HasProductVariant() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900102 return Bool(c.VendorProperties.Product_available)
Justin Yun63e9ec72020-10-29 16:49:43 +0900103}
104
105// Returns true when this module is configured to have core and either product or vendor variants.
106func (c *Module) HasNonSystemVariants() bool {
Justin Yun6977e8a2020-10-29 18:24:11 +0900107 return c.HasVendorVariant() || c.HasProductVariant()
Justin Yun63e9ec72020-10-29 16:49:43 +0900108}
109
Inseob Kime498dd92020-08-04 09:24:04 +0900110// Returns true if the module is "product" variant. Usually these modules are installed in /product
Ivan Lozanof9e21722020-12-02 09:00:51 -0500111func (c *Module) InProduct() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900112 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
113}
114
115// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500116func (c *Module) InVendor() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900117 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
118}
119
120func (c *Module) InRamdisk() bool {
121 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
122}
123
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700124func (c *Module) InVendorRamdisk() bool {
125 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
126}
127
Inseob Kime498dd92020-08-04 09:24:04 +0900128func (c *Module) InRecovery() bool {
129 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
130}
131
132func (c *Module) OnlyInRamdisk() bool {
133 return c.ModuleBase.InstallInRamdisk()
134}
135
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700136func (c *Module) OnlyInVendorRamdisk() bool {
137 return c.ModuleBase.InstallInVendorRamdisk()
138}
139
Inseob Kime498dd92020-08-04 09:24:04 +0900140func (c *Module) OnlyInRecovery() bool {
141 return c.ModuleBase.InstallInRecovery()
142}
143
Justin Yun6977e8a2020-10-29 18:24:11 +0900144func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
145 if v.Kind() != reflect.Struct {
146 return true
147 }
148 for i := 0; i < v.NumField(); i++ {
149 prop := v.Field(i)
150 if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
151 vendor_prop := prop.FieldByName("Vendor")
152 product_prop := prop.FieldByName("Product")
153 if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
154 // Neither Target.Vendor nor Target.Product is defined
155 continue
156 }
157 if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
158 !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
159 // If only one of either Target.Vendor or Target.Product is
160 // defined or they have different values, it fails the build
161 // since VNDK must have the same properties for both vendor
162 // and product variants.
163 return false
164 }
165 } else if !visitPropsAndCompareVendorAndProductProps(prop) {
166 // Visit the substructures to find Target.Vendor and Target.Product
167 return false
168 }
169 }
170 return true
171}
172
173// In the case of VNDK, vendor and product variants must have the same properties.
174// VNDK installs only one file and shares it for both vendor and product modules on
175// runtime. We may not define different versions of a VNDK lib for each partition.
176// This function is used only for the VNDK modules that is available to both vendor
177// and product partitions.
178func (c *Module) compareVendorAndProductProps() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900179 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
Justin Yun6977e8a2020-10-29 18:24:11 +0900180 panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
181 }
182 for _, properties := range c.GetProperties() {
183 if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
184 return false
185 }
186 }
187 return true
188}
189
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400190// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules.
191type ImageMutatableModule interface {
192 android.Module
193 LinkableInterface
194
195 // AndroidModuleBase returns the android.ModuleBase for this module
196 AndroidModuleBase() *android.ModuleBase
197
198 // VendorAvailable returns true if this module is available on the vendor image.
199 VendorAvailable() bool
200
201 // OdmAvailable returns true if this module is available on the odm image.
202 OdmAvailable() bool
203
204 // ProductAvailable returns true if this module is available on the product image.
205 ProductAvailable() bool
206
207 // RamdiskAvailable returns true if this module is available on the ramdisk image.
208 RamdiskAvailable() bool
209
210 // RecoveryAvailable returns true if this module is available on the recovery image.
211 RecoveryAvailable() bool
212
213 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
214 VendorRamdiskAvailable() bool
215
216 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
217 IsSnapshotPrebuilt() bool
218
219 // SnapshotVersion returns the snapshot version for this module.
220 SnapshotVersion(mctx android.BaseModuleContext) string
221
222 // SdkVersion returns the SDK version for this module.
223 SdkVersion() string
224
225 // ExtraVariants returns the list of extra variants this module requires.
226 ExtraVariants() []string
227
228 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
229 AppendExtraVariant(extraVariant string)
230
231 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
232 SetRamdiskVariantNeeded(b bool)
233
234 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
235 SetVendorRamdiskVariantNeeded(b bool)
236
237 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
238 SetRecoveryVariantNeeded(b bool)
239
240 // SetCoreVariantNeeded sets whether the Core Variant is needed.
241 SetCoreVariantNeeded(b bool)
242}
243
244var _ ImageMutatableModule = (*Module)(nil)
245
Inseob Kime498dd92020-08-04 09:24:04 +0900246func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400247 m.CheckVndkProperties(mctx)
248 MutateImage(mctx, m)
249}
250
251// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
252// If properties are not set correctly, results in a module context property error.
253func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
Inseob Kime498dd92020-08-04 09:24:04 +0900254 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
255 productSpecific := mctx.ProductSpecific()
256
Inseob Kime498dd92020-08-04 09:24:04 +0900257 if vndkdep := m.vndkdep; vndkdep != nil {
258 if vndkdep.isVndk() {
259 if vendorSpecific || productSpecific {
260 if !vndkdep.isVndkExt() {
261 mctx.PropertyErrorf("vndk",
262 "must set `extends: \"...\"` to vndk extension")
Justin Yunc0d8c492021-01-07 17:45:31 +0900263 } else if Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900264 mctx.PropertyErrorf("vendor_available",
265 "must not set at the same time as `vndk: {extends: \"...\"}`")
Justin Yunc0d8c492021-01-07 17:45:31 +0900266 } else if Bool(m.VendorProperties.Product_available) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900267 mctx.PropertyErrorf("product_available",
268 "must not set at the same time as `vndk: {extends: \"...\"}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900269 }
270 } else {
271 if vndkdep.isVndkExt() {
272 mctx.PropertyErrorf("vndk",
273 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
274 m.getVndkExtendsModuleName())
275 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900276 if !Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900277 mctx.PropertyErrorf("vndk",
Justin Yunc0d8c492021-01-07 17:45:31 +0900278 "vendor_available must be set to true when `vndk: {enabled: true}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900279 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900280 if Bool(m.VendorProperties.Product_available) {
Justin Yunfd9e8042020-12-23 18:23:14 +0900281 // If a VNDK module creates both product and vendor variants, they
282 // must have the same properties since they share a single VNDK
283 // library on runtime.
Justin Yun6977e8a2020-10-29 18:24:11 +0900284 if !m.compareVendorAndProductProps() {
285 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
286 }
287 }
Inseob Kime498dd92020-08-04 09:24:04 +0900288 }
289 } else {
290 if vndkdep.isVndkSp() {
291 mctx.PropertyErrorf("vndk",
292 "must set `enabled: true` to set `support_system_process: true`")
293 }
294 if vndkdep.isVndkExt() {
295 mctx.PropertyErrorf("vndk",
296 "must set `enabled: true` to set `extends: %q`",
297 m.getVndkExtendsModuleName())
298 }
299 }
300 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400301}
302
303func (m *Module) VendorAvailable() bool {
304 return Bool(m.VendorProperties.Vendor_available)
305}
306
307func (m *Module) OdmAvailable() bool {
308 return Bool(m.VendorProperties.Odm_available)
309}
310
311func (m *Module) ProductAvailable() bool {
312 return Bool(m.VendorProperties.Product_available)
313}
314
315func (m *Module) RamdiskAvailable() bool {
316 return Bool(m.Properties.Ramdisk_available)
317}
318
319func (m *Module) VendorRamdiskAvailable() bool {
320 return Bool(m.Properties.Vendor_ramdisk_available)
321}
322
323func (m *Module) AndroidModuleBase() *android.ModuleBase {
324 return &m.ModuleBase
325}
326
327func (m *Module) RecoveryAvailable() bool {
328 return Bool(m.Properties.Recovery_available)
329}
330
331func (m *Module) ExtraVariants() []string {
332 return m.Properties.ExtraVariants
333}
334
335func (m *Module) AppendExtraVariant(extraVariant string) {
336 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, extraVariant)
337}
338
339func (m *Module) SetRamdiskVariantNeeded(b bool) {
340 m.Properties.RamdiskVariantNeeded = b
341}
342
343func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
344 m.Properties.VendorRamdiskVariantNeeded = b
345}
346
347func (m *Module) SetRecoveryVariantNeeded(b bool) {
348 m.Properties.RecoveryVariantNeeded = b
349}
350
351func (m *Module) SetCoreVariantNeeded(b bool) {
352 m.Properties.CoreVariantNeeded = b
353}
354
355func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
356 if snapshot, ok := m.linker.(snapshotInterface); ok {
357 return snapshot.version()
358 } else {
359 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
360 // Should we be panicking here instead?
361 return ""
362 }
363}
364
365func (m *Module) KernelHeadersDecorator() bool {
366 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
367 return true
368 }
369 return false
370}
371
372// MutateImage handles common image mutations for ImageMutatableModule interfaces.
373func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
374 // Validation check
375 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
376 productSpecific := mctx.ProductSpecific()
377
378 if m.VendorAvailable() {
379 if vendorSpecific {
380 mctx.PropertyErrorf("vendor_available",
381 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
382 }
383 if m.OdmAvailable() {
384 mctx.PropertyErrorf("vendor_available",
385 "doesn't make sense at the same time as `odm_available: true`")
386 }
387 }
388
389 if m.OdmAvailable() {
390 if vendorSpecific {
391 mctx.PropertyErrorf("odm_available",
392 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
393 }
394 }
395
396 if m.ProductAvailable() {
397 if productSpecific {
398 mctx.PropertyErrorf("product_available",
399 "doesn't make sense at the same time as `product_specific: true`")
400 }
401 if vendorSpecific {
402 mctx.PropertyErrorf("product_available",
403 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
404 }
405 }
Inseob Kime498dd92020-08-04 09:24:04 +0900406
407 var coreVariantNeeded bool = false
408 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700409 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900410 var recoveryVariantNeeded bool = false
411
412 var vendorVariants []string
413 var productVariants []string
414
415 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
416 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
417 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
Jose Galmes6f843bc2020-12-11 13:36:29 -0800418 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
419 usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
420 recoverySnapshotVersion != ""
Inseob Kime498dd92020-08-04 09:24:04 +0900421 if boardVndkVersion == "current" {
422 boardVndkVersion = platformVndkVersion
423 }
424 if productVndkVersion == "current" {
425 productVndkVersion = platformVndkVersion
426 }
427
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400428 if m.IsLlndkLibrary() || m.IsLlndkHeaders() || m.HasLlndkStubs() {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800429 // This is an LLNDK library. The implementation of the library will be on /system,
430 // and vendor and product variants will be created with LLNDK stubs.
431 // The LLNDK libraries need vendor variants even if there is no VNDK.
432 // The obsolete llndk_library and llndk_headers modules also need the vendor variants
433 // so the cc_library LLNDK stubs can depend on them.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400434 if m.HasLlndkStubs() {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800435 coreVariantNeeded = true
436 }
437 if platformVndkVersion != "" {
438 vendorVariants = append(vendorVariants, platformVndkVersion)
439 productVariants = append(productVariants, platformVndkVersion)
440 }
441 if boardVndkVersion != "" {
442 vendorVariants = append(vendorVariants, boardVndkVersion)
443 }
444 if productVndkVersion != "" {
445 productVariants = append(productVariants, productVndkVersion)
446 }
447 } else if boardVndkVersion == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900448 // If the device isn't compiling against the VNDK, we always
449 // use the core mode.
450 coreVariantNeeded = true
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400451 } else if m.IsSnapshotPrebuilt() {
Inseob Kime498dd92020-08-04 09:24:04 +0900452 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
453 // PRODUCT_EXTRA_VNDK_VERSIONS.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400454 if m.InstallInRecovery() {
455 recoveryVariantNeeded = true
Inseob Kime498dd92020-08-04 09:24:04 +0900456 } else {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400457 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
Inseob Kime498dd92020-08-04 09:24:04 +0900458 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500459 } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
Justin Yun63e9ec72020-10-29 16:49:43 +0900460 // This will be available to /system unless it is product_specific
461 // which will be handled later.
Inseob Kime498dd92020-08-04 09:24:04 +0900462 coreVariantNeeded = true
463
464 // We assume that modules under proprietary paths are compatible for
465 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
466 // PLATFORM_VNDK_VERSION.
Justin Yun63e9ec72020-10-29 16:49:43 +0900467 if m.HasVendorVariant() {
468 if isVendorProprietaryModule(mctx) {
469 vendorVariants = append(vendorVariants, boardVndkVersion)
470 } else {
471 vendorVariants = append(vendorVariants, platformVndkVersion)
472 }
Inseob Kime498dd92020-08-04 09:24:04 +0900473 }
474
Justin Yun6977e8a2020-10-29 18:24:11 +0900475 // product_available modules are available to /product.
476 if m.HasProductVariant() {
477 productVariants = append(productVariants, platformVndkVersion)
478 // VNDK is always PLATFORM_VNDK_VERSION
479 if !m.IsVndk() {
480 productVariants = append(productVariants, productVndkVersion)
481 }
Inseob Kime498dd92020-08-04 09:24:04 +0900482 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400483 } else if vendorSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900484 // This will be available in /vendor (or /odm) only
485
486 // kernel_headers is a special module type whose exported headers
487 // are coming from DeviceKernelHeaders() which is always vendor
488 // dependent. They'll always have both vendor variants.
489 // For other modules, we assume that modules under proprietary
490 // paths are compatible for BOARD_VNDK_VERSION. The other modules
491 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400492 if m.KernelHeadersDecorator() {
Inseob Kime498dd92020-08-04 09:24:04 +0900493 vendorVariants = append(vendorVariants,
494 platformVndkVersion,
495 boardVndkVersion,
496 )
Bill Peckham945441c2020-08-31 16:07:58 -0700497 } else if isVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900498 vendorVariants = append(vendorVariants, boardVndkVersion)
499 } else {
500 vendorVariants = append(vendorVariants, platformVndkVersion)
501 }
502 } else {
503 // This is either in /system (or similar: /data), or is a
504 // modules built with the NDK. Modules built with the NDK
505 // will be restricted using the existing link type checks.
506 coreVariantNeeded = true
507 }
508
509 if boardVndkVersion != "" && productVndkVersion != "" {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400510 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900511 // The module has "product_specific: true" that does not create core variant.
512 coreVariantNeeded = false
513 productVariants = append(productVariants, productVndkVersion)
514 }
515 } else {
516 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
517 // restriction to use system libs.
518 // No product variants defined in this case.
519 productVariants = []string{}
520 }
521
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400522 if m.RamdiskAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900523 ramdiskVariantNeeded = true
524 }
525
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400526 if m.AndroidModuleBase().InstallInRamdisk() {
Inseob Kime498dd92020-08-04 09:24:04 +0900527 ramdiskVariantNeeded = true
528 coreVariantNeeded = false
529 }
530
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400531 if m.VendorRamdiskAvailable() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700532 vendorRamdiskVariantNeeded = true
533 }
534
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400535 if m.AndroidModuleBase().InstallInVendorRamdisk() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700536 vendorRamdiskVariantNeeded = true
537 coreVariantNeeded = false
538 }
539
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400540 if m.RecoveryAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900541 recoveryVariantNeeded = true
542 }
543
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400544 if m.AndroidModuleBase().InstallInRecovery() {
Inseob Kime498dd92020-08-04 09:24:04 +0900545 recoveryVariantNeeded = true
546 coreVariantNeeded = false
547 }
548
Jose Galmes6f843bc2020-12-11 13:36:29 -0800549 // If using a snapshot, the recovery variant under AOSP directories is not needed,
550 // except for kernel headers, which needs all variants.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400551 if m.KernelHeadersDecorator() &&
552 !m.IsSnapshotPrebuilt() &&
Jose Galmes6f843bc2020-12-11 13:36:29 -0800553 usingRecoverySnapshot &&
554 !isRecoveryProprietaryModule(mctx) {
555 recoveryVariantNeeded = false
556 }
557
Inseob Kime498dd92020-08-04 09:24:04 +0900558 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400559 m.AppendExtraVariant(VendorVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900560 }
561
562 for _, variant := range android.FirstUniqueStrings(productVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400563 m.AppendExtraVariant(ProductVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900564 }
565
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400566 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
567 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
568 m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
569 m.SetCoreVariantNeeded(coreVariantNeeded)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800570
571 // Disable the module if no variants are needed.
572 if !ramdiskVariantNeeded &&
573 !recoveryVariantNeeded &&
574 !coreVariantNeeded &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400575 len(m.ExtraVariants()) == 0 {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800576 m.Disable()
577 }
Inseob Kime498dd92020-08-04 09:24:04 +0900578}
579
580func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
581 return c.Properties.CoreVariantNeeded
582}
583
584func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
585 return c.Properties.RamdiskVariantNeeded
586}
587
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700588func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
589 return c.Properties.VendorRamdiskVariantNeeded
590}
591
Inseob Kime498dd92020-08-04 09:24:04 +0900592func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
593 return c.Properties.RecoveryVariantNeeded
594}
595
596func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
597 return c.Properties.ExtraVariants
598}
599
Justin Yun63e9ec72020-10-29 16:49:43 +0900600func squashVendorSrcs(m *Module) {
601 if lib, ok := m.compiler.(*libraryDecorator); ok {
602 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
603 lib.baseCompiler.Properties.Target.Vendor.Srcs...)
604
605 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
606 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
607
608 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
609 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
610 }
611}
612
613func squashProductSrcs(m *Module) {
614 if lib, ok := m.compiler.(*libraryDecorator); ok {
615 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
616 lib.baseCompiler.Properties.Target.Product.Srcs...)
617
618 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
619 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
620
621 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
622 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
623 }
624}
625
626func squashRecoverySrcs(m *Module) {
627 if lib, ok := m.compiler.(*libraryDecorator); ok {
628 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
629 lib.baseCompiler.Properties.Target.Recovery.Srcs...)
630
631 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
632 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
633
634 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
635 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
636 }
637}
638
639func squashVendorRamdiskSrcs(m *Module) {
640 if lib, ok := m.compiler.(*libraryDecorator); ok {
641 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
642 }
643}
644
Inseob Kime498dd92020-08-04 09:24:04 +0900645func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
646 m := module.(*Module)
Yifan Hong6da33c22020-10-27 15:01:21 -0700647 if variant == android.RamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900648 m.MakeAsPlatform()
Yifan Hong6da33c22020-10-27 15:01:21 -0700649 } else if variant == android.VendorRamdiskVariation {
650 m.MakeAsPlatform()
651 squashVendorRamdiskSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900652 } else if variant == android.RecoveryVariation {
653 m.MakeAsPlatform()
654 squashRecoverySrcs(m)
655 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
656 m.Properties.ImageVariationPrefix = VendorVariationPrefix
657 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
658 squashVendorSrcs(m)
659
660 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
661 // Hide other vendor variants to avoid collision.
662 vndkVersion := ctx.DeviceConfig().VndkVersion()
663 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
664 m.Properties.HideFromMake = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800665 m.HideFromMake()
Inseob Kime498dd92020-08-04 09:24:04 +0900666 }
667 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
668 m.Properties.ImageVariationPrefix = ProductVariationPrefix
669 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
Justin Yun6977e8a2020-10-29 18:24:11 +0900670 squashProductSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900671 }
672}