blob: 3a0857b21992d411fd6578dd64c8ded926e2cfe1 [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"
Kiyoung Kim48f37782021-07-07 12:42:39 +090025 "android/soong/snapshot"
Inseob Kime498dd92020-08-04 09:24:04 +090026)
27
28var _ android.ImageInterface = (*Module)(nil)
29
Ivan Lozano3968d8f2020-12-14 11:27:52 -050030type ImageVariantType string
Inseob Kim74d25562020-08-04 00:41:38 +090031
32const (
Ivan Lozano3968d8f2020-12-14 11:27:52 -050033 coreImageVariant ImageVariantType = "core"
34 vendorImageVariant ImageVariantType = "vendor"
35 productImageVariant ImageVariantType = "product"
36 ramdiskImageVariant ImageVariantType = "ramdisk"
37 vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk"
38 recoveryImageVariant ImageVariantType = "recovery"
39 hostImageVariant ImageVariantType = "host"
Inseob Kim74d25562020-08-04 00:41:38 +090040)
41
Inseob Kime498dd92020-08-04 09:24:04 +090042const (
43 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
44 // against the VNDK.
45 VendorVariationPrefix = "vendor."
46
47 // ProductVariationPrefix is the variant prefix used for /product code that compiles
48 // against the VNDK.
49 ProductVariationPrefix = "product."
50)
51
52func (ctx *moduleContext) ProductSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090053 return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext()
Inseob Kime498dd92020-08-04 09:24:04 +090054}
55
56func (ctx *moduleContext) SocSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090057 return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext()
Justin Yunebcf0c52021-01-08 18:00:19 +090058}
59
60func (ctx *moduleContext) DeviceSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090061 return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext()
Inseob Kime498dd92020-08-04 09:24:04 +090062}
63
64func (ctx *moduleContextImpl) inProduct() bool {
Ivan Lozanof9e21722020-12-02 09:00:51 -050065 return ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090066}
67
68func (ctx *moduleContextImpl) inVendor() bool {
Ivan Lozano3968d8f2020-12-14 11:27:52 -050069 return ctx.mod.InVendor()
Inseob Kime498dd92020-08-04 09:24:04 +090070}
71
72func (ctx *moduleContextImpl) inRamdisk() bool {
73 return ctx.mod.InRamdisk()
74}
75
Yifan Hong60e0cfb2020-10-21 15:17:56 -070076func (ctx *moduleContextImpl) inVendorRamdisk() bool {
77 return ctx.mod.InVendorRamdisk()
78}
79
Inseob Kime498dd92020-08-04 09:24:04 +090080func (ctx *moduleContextImpl) inRecovery() bool {
81 return ctx.mod.InRecovery()
82}
83
Justin Yun7f99ec72021-04-12 13:19:28 +090084func (c *Module) productSpecificModuleContext() bool {
85 // Additionally check if this module is inProduct() that means it is a "product" variant of a
86 // module. As well as product specific modules, product variants must be installed to /product.
87 return c.InProduct()
88}
89
90func (c *Module) socSpecificModuleContext() bool {
91 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a
92 // module. As well as SoC specific modules, vendor variants must be installed to /vendor
93 // unless they have "odm_available: true".
94 return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
95}
96
97func (c *Module) deviceSpecificModuleContext() bool {
98 // Some vendor variants want to be installed to /odm by setting "odm_available: true".
99 return c.InVendor() && c.VendorVariantToOdm()
100}
101
Justin Yun63e9ec72020-10-29 16:49:43 +0900102// Returns true when this module is configured to have core and vendor variants.
Inseob Kime498dd92020-08-04 09:24:04 +0900103func (c *Module) HasVendorVariant() bool {
Justin Yunebcf0c52021-01-08 18:00:19 +0900104 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
105}
106
107// Returns true when this module creates a vendor variant and wants to install the vendor variant
108// to the odm partition.
109func (c *Module) VendorVariantToOdm() bool {
110 return Bool(c.VendorProperties.Odm_available)
Inseob Kime498dd92020-08-04 09:24:04 +0900111}
112
Justin Yun63e9ec72020-10-29 16:49:43 +0900113// Returns true when this module is configured to have core and product variants.
114func (c *Module) HasProductVariant() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900115 return Bool(c.VendorProperties.Product_available)
Justin Yun63e9ec72020-10-29 16:49:43 +0900116}
117
118// Returns true when this module is configured to have core and either product or vendor variants.
119func (c *Module) HasNonSystemVariants() bool {
Justin Yun6977e8a2020-10-29 18:24:11 +0900120 return c.HasVendorVariant() || c.HasProductVariant()
Justin Yun63e9ec72020-10-29 16:49:43 +0900121}
122
Inseob Kime498dd92020-08-04 09:24:04 +0900123// Returns true if the module is "product" variant. Usually these modules are installed in /product
Ivan Lozanof9e21722020-12-02 09:00:51 -0500124func (c *Module) InProduct() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900125 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
126}
127
128// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500129func (c *Module) InVendor() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900130 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
131}
132
133func (c *Module) InRamdisk() bool {
134 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
135}
136
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700137func (c *Module) InVendorRamdisk() bool {
138 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
139}
140
Inseob Kime498dd92020-08-04 09:24:04 +0900141func (c *Module) InRecovery() bool {
142 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
143}
144
145func (c *Module) OnlyInRamdisk() bool {
146 return c.ModuleBase.InstallInRamdisk()
147}
148
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700149func (c *Module) OnlyInVendorRamdisk() bool {
150 return c.ModuleBase.InstallInVendorRamdisk()
151}
152
Inseob Kime498dd92020-08-04 09:24:04 +0900153func (c *Module) OnlyInRecovery() bool {
154 return c.ModuleBase.InstallInRecovery()
155}
156
Justin Yun6977e8a2020-10-29 18:24:11 +0900157func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
158 if v.Kind() != reflect.Struct {
159 return true
160 }
161 for i := 0; i < v.NumField(); i++ {
162 prop := v.Field(i)
163 if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
164 vendor_prop := prop.FieldByName("Vendor")
165 product_prop := prop.FieldByName("Product")
166 if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
167 // Neither Target.Vendor nor Target.Product is defined
168 continue
169 }
170 if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
171 !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
172 // If only one of either Target.Vendor or Target.Product is
173 // defined or they have different values, it fails the build
174 // since VNDK must have the same properties for both vendor
175 // and product variants.
176 return false
177 }
178 } else if !visitPropsAndCompareVendorAndProductProps(prop) {
179 // Visit the substructures to find Target.Vendor and Target.Product
180 return false
181 }
182 }
183 return true
184}
185
186// In the case of VNDK, vendor and product variants must have the same properties.
187// VNDK installs only one file and shares it for both vendor and product modules on
188// runtime. We may not define different versions of a VNDK lib for each partition.
189// This function is used only for the VNDK modules that is available to both vendor
190// and product partitions.
191func (c *Module) compareVendorAndProductProps() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900192 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
Justin Yun6977e8a2020-10-29 18:24:11 +0900193 panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
194 }
195 for _, properties := range c.GetProperties() {
196 if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
197 return false
198 }
199 }
200 return true
201}
202
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400203// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules.
204type ImageMutatableModule interface {
205 android.Module
206 LinkableInterface
207
208 // AndroidModuleBase returns the android.ModuleBase for this module
209 AndroidModuleBase() *android.ModuleBase
210
211 // VendorAvailable returns true if this module is available on the vendor image.
212 VendorAvailable() bool
213
214 // OdmAvailable returns true if this module is available on the odm image.
215 OdmAvailable() bool
216
217 // ProductAvailable returns true if this module is available on the product image.
218 ProductAvailable() bool
219
220 // RamdiskAvailable returns true if this module is available on the ramdisk image.
221 RamdiskAvailable() bool
222
223 // RecoveryAvailable returns true if this module is available on the recovery image.
224 RecoveryAvailable() bool
225
226 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
227 VendorRamdiskAvailable() bool
228
229 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
230 IsSnapshotPrebuilt() bool
231
232 // SnapshotVersion returns the snapshot version for this module.
233 SnapshotVersion(mctx android.BaseModuleContext) string
234
235 // SdkVersion returns the SDK version for this module.
236 SdkVersion() string
237
238 // ExtraVariants returns the list of extra variants this module requires.
239 ExtraVariants() []string
240
241 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
242 AppendExtraVariant(extraVariant string)
243
244 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
245 SetRamdiskVariantNeeded(b bool)
246
247 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
248 SetVendorRamdiskVariantNeeded(b bool)
249
250 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
251 SetRecoveryVariantNeeded(b bool)
252
253 // SetCoreVariantNeeded sets whether the Core Variant is needed.
254 SetCoreVariantNeeded(b bool)
255}
256
257var _ ImageMutatableModule = (*Module)(nil)
258
Inseob Kime498dd92020-08-04 09:24:04 +0900259func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400260 m.CheckVndkProperties(mctx)
261 MutateImage(mctx, m)
262}
263
264// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
265// If properties are not set correctly, results in a module context property error.
266func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
Inseob Kime498dd92020-08-04 09:24:04 +0900267 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
268 productSpecific := mctx.ProductSpecific()
269
Inseob Kime498dd92020-08-04 09:24:04 +0900270 if vndkdep := m.vndkdep; vndkdep != nil {
271 if vndkdep.isVndk() {
272 if vendorSpecific || productSpecific {
273 if !vndkdep.isVndkExt() {
274 mctx.PropertyErrorf("vndk",
275 "must set `extends: \"...\"` to vndk extension")
Justin Yunc0d8c492021-01-07 17:45:31 +0900276 } else if Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900277 mctx.PropertyErrorf("vendor_available",
278 "must not set at the same time as `vndk: {extends: \"...\"}`")
Justin Yunc0d8c492021-01-07 17:45:31 +0900279 } else if Bool(m.VendorProperties.Product_available) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900280 mctx.PropertyErrorf("product_available",
281 "must not set at the same time as `vndk: {extends: \"...\"}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900282 }
283 } else {
284 if vndkdep.isVndkExt() {
285 mctx.PropertyErrorf("vndk",
286 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
287 m.getVndkExtendsModuleName())
288 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900289 if !Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900290 mctx.PropertyErrorf("vndk",
Justin Yunc0d8c492021-01-07 17:45:31 +0900291 "vendor_available must be set to true when `vndk: {enabled: true}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900292 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900293 if Bool(m.VendorProperties.Product_available) {
Justin Yunfd9e8042020-12-23 18:23:14 +0900294 // If a VNDK module creates both product and vendor variants, they
295 // must have the same properties since they share a single VNDK
296 // library on runtime.
Justin Yun6977e8a2020-10-29 18:24:11 +0900297 if !m.compareVendorAndProductProps() {
298 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
299 }
300 }
Inseob Kime498dd92020-08-04 09:24:04 +0900301 }
302 } else {
303 if vndkdep.isVndkSp() {
304 mctx.PropertyErrorf("vndk",
305 "must set `enabled: true` to set `support_system_process: true`")
306 }
307 if vndkdep.isVndkExt() {
308 mctx.PropertyErrorf("vndk",
309 "must set `enabled: true` to set `extends: %q`",
310 m.getVndkExtendsModuleName())
311 }
312 }
313 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400314}
315
316func (m *Module) VendorAvailable() bool {
317 return Bool(m.VendorProperties.Vendor_available)
318}
319
320func (m *Module) OdmAvailable() bool {
321 return Bool(m.VendorProperties.Odm_available)
322}
323
324func (m *Module) ProductAvailable() bool {
325 return Bool(m.VendorProperties.Product_available)
326}
327
328func (m *Module) RamdiskAvailable() bool {
329 return Bool(m.Properties.Ramdisk_available)
330}
331
332func (m *Module) VendorRamdiskAvailable() bool {
333 return Bool(m.Properties.Vendor_ramdisk_available)
334}
335
336func (m *Module) AndroidModuleBase() *android.ModuleBase {
337 return &m.ModuleBase
338}
339
340func (m *Module) RecoveryAvailable() bool {
341 return Bool(m.Properties.Recovery_available)
342}
343
344func (m *Module) ExtraVariants() []string {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200345 return m.Properties.ExtraVersionedImageVariations
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400346}
347
348func (m *Module) AppendExtraVariant(extraVariant string) {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200349 m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant)
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400350}
351
352func (m *Module) SetRamdiskVariantNeeded(b bool) {
353 m.Properties.RamdiskVariantNeeded = b
354}
355
356func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
357 m.Properties.VendorRamdiskVariantNeeded = b
358}
359
360func (m *Module) SetRecoveryVariantNeeded(b bool) {
361 m.Properties.RecoveryVariantNeeded = b
362}
363
364func (m *Module) SetCoreVariantNeeded(b bool) {
365 m.Properties.CoreVariantNeeded = b
366}
367
368func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
Ivan Lozanod1dec542021-05-26 15:33:11 -0400369 if snapshot, ok := m.linker.(SnapshotInterface); ok {
370 return snapshot.Version()
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400371 } else {
372 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
373 // Should we be panicking here instead?
374 return ""
375 }
376}
377
378func (m *Module) KernelHeadersDecorator() bool {
379 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
380 return true
381 }
382 return false
383}
384
385// MutateImage handles common image mutations for ImageMutatableModule interfaces.
386func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
387 // Validation check
388 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
389 productSpecific := mctx.ProductSpecific()
390
391 if m.VendorAvailable() {
392 if vendorSpecific {
393 mctx.PropertyErrorf("vendor_available",
394 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
395 }
396 if m.OdmAvailable() {
397 mctx.PropertyErrorf("vendor_available",
398 "doesn't make sense at the same time as `odm_available: true`")
399 }
400 }
401
402 if m.OdmAvailable() {
403 if vendorSpecific {
404 mctx.PropertyErrorf("odm_available",
405 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
406 }
407 }
408
409 if m.ProductAvailable() {
410 if productSpecific {
411 mctx.PropertyErrorf("product_available",
412 "doesn't make sense at the same time as `product_specific: true`")
413 }
414 if vendorSpecific {
415 mctx.PropertyErrorf("product_available",
416 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
417 }
418 }
Inseob Kime498dd92020-08-04 09:24:04 +0900419
420 var coreVariantNeeded bool = false
421 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700422 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900423 var recoveryVariantNeeded bool = false
424
425 var vendorVariants []string
426 var productVariants []string
427
428 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
429 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
430 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
Jose Galmes6f843bc2020-12-11 13:36:29 -0800431 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
432 usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
433 recoverySnapshotVersion != ""
Justin Yundee806f2021-05-18 23:10:00 +0900434 needVndkVersionVendorVariantForLlndk := false
435 if boardVndkVersion != "" {
436 boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
437 if err == nil && !boardVndkApiLevel.IsPreview() {
438 // VNDK snapshot newer than v30 has LLNDK stub libraries.
439 // Only the VNDK version less than or equal to v30 requires generating the vendor
440 // variant of the VNDK version from the source tree.
441 needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
442 }
443 }
Inseob Kime498dd92020-08-04 09:24:04 +0900444 if boardVndkVersion == "current" {
445 boardVndkVersion = platformVndkVersion
446 }
447 if productVndkVersion == "current" {
448 productVndkVersion = platformVndkVersion
449 }
450
Colin Cross203b4212021-04-26 17:19:41 -0700451 if m.NeedsLlndkVariants() {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800452 // This is an LLNDK library. The implementation of the library will be on /system,
453 // and vendor and product variants will be created with LLNDK stubs.
454 // The LLNDK libraries need vendor variants even if there is no VNDK.
Colin Cross203b4212021-04-26 17:19:41 -0700455 coreVariantNeeded = true
Colin Crossb5f6fa62021-01-06 17:05:04 -0800456 if platformVndkVersion != "" {
457 vendorVariants = append(vendorVariants, platformVndkVersion)
458 productVariants = append(productVariants, platformVndkVersion)
459 }
Justin Yundee806f2021-05-18 23:10:00 +0900460 // Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
461 // provide the LLNDK stub libraries.
462 if needVndkVersionVendorVariantForLlndk {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800463 vendorVariants = append(vendorVariants, boardVndkVersion)
464 }
465 if productVndkVersion != "" {
466 productVariants = append(productVariants, productVndkVersion)
467 }
Colin Cross5271fea2021-04-27 13:06:04 -0700468 } else if m.NeedsVendorPublicLibraryVariants() {
469 // A vendor public library has the implementation on /vendor, with stub variants
470 // for system and product.
471 coreVariantNeeded = true
472 vendorVariants = append(vendorVariants, boardVndkVersion)
473 if platformVndkVersion != "" {
474 productVariants = append(productVariants, platformVndkVersion)
475 }
476 if productVndkVersion != "" {
477 productVariants = append(productVariants, productVndkVersion)
478 }
Colin Crossb5f6fa62021-01-06 17:05:04 -0800479 } else if boardVndkVersion == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900480 // If the device isn't compiling against the VNDK, we always
481 // use the core mode.
482 coreVariantNeeded = true
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400483 } else if m.IsSnapshotPrebuilt() {
Inseob Kime498dd92020-08-04 09:24:04 +0900484 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
485 // PRODUCT_EXTRA_VNDK_VERSIONS.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400486 if m.InstallInRecovery() {
487 recoveryVariantNeeded = true
Inseob Kime498dd92020-08-04 09:24:04 +0900488 } else {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400489 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
Inseob Kime498dd92020-08-04 09:24:04 +0900490 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500491 } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
Justin Yun63e9ec72020-10-29 16:49:43 +0900492 // This will be available to /system unless it is product_specific
493 // which will be handled later.
Inseob Kime498dd92020-08-04 09:24:04 +0900494 coreVariantNeeded = true
495
496 // We assume that modules under proprietary paths are compatible for
497 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
498 // PLATFORM_VNDK_VERSION.
Justin Yun63e9ec72020-10-29 16:49:43 +0900499 if m.HasVendorVariant() {
Kiyoung Kim48f37782021-07-07 12:42:39 +0900500 if snapshot.IsVendorProprietaryModule(mctx) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900501 vendorVariants = append(vendorVariants, boardVndkVersion)
502 } else {
503 vendorVariants = append(vendorVariants, platformVndkVersion)
504 }
Inseob Kime498dd92020-08-04 09:24:04 +0900505 }
506
Justin Yun6977e8a2020-10-29 18:24:11 +0900507 // product_available modules are available to /product.
508 if m.HasProductVariant() {
509 productVariants = append(productVariants, platformVndkVersion)
510 // VNDK is always PLATFORM_VNDK_VERSION
511 if !m.IsVndk() {
512 productVariants = append(productVariants, productVndkVersion)
513 }
Inseob Kime498dd92020-08-04 09:24:04 +0900514 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400515 } else if vendorSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900516 // This will be available in /vendor (or /odm) only
517
518 // kernel_headers is a special module type whose exported headers
519 // are coming from DeviceKernelHeaders() which is always vendor
520 // dependent. They'll always have both vendor variants.
521 // For other modules, we assume that modules under proprietary
522 // paths are compatible for BOARD_VNDK_VERSION. The other modules
523 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400524 if m.KernelHeadersDecorator() {
Inseob Kime498dd92020-08-04 09:24:04 +0900525 vendorVariants = append(vendorVariants,
526 platformVndkVersion,
527 boardVndkVersion,
528 )
Kiyoung Kim48f37782021-07-07 12:42:39 +0900529 } else if snapshot.IsVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900530 vendorVariants = append(vendorVariants, boardVndkVersion)
531 } else {
532 vendorVariants = append(vendorVariants, platformVndkVersion)
533 }
534 } else {
535 // This is either in /system (or similar: /data), or is a
536 // modules built with the NDK. Modules built with the NDK
537 // will be restricted using the existing link type checks.
538 coreVariantNeeded = true
539 }
540
541 if boardVndkVersion != "" && productVndkVersion != "" {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400542 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900543 // The module has "product_specific: true" that does not create core variant.
544 coreVariantNeeded = false
545 productVariants = append(productVariants, productVndkVersion)
546 }
547 } else {
548 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
549 // restriction to use system libs.
550 // No product variants defined in this case.
551 productVariants = []string{}
552 }
553
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400554 if m.RamdiskAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900555 ramdiskVariantNeeded = true
556 }
557
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400558 if m.AndroidModuleBase().InstallInRamdisk() {
Inseob Kime498dd92020-08-04 09:24:04 +0900559 ramdiskVariantNeeded = true
560 coreVariantNeeded = false
561 }
562
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400563 if m.VendorRamdiskAvailable() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700564 vendorRamdiskVariantNeeded = true
565 }
566
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400567 if m.AndroidModuleBase().InstallInVendorRamdisk() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700568 vendorRamdiskVariantNeeded = true
569 coreVariantNeeded = false
570 }
571
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400572 if m.RecoveryAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900573 recoveryVariantNeeded = true
574 }
575
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400576 if m.AndroidModuleBase().InstallInRecovery() {
Inseob Kime498dd92020-08-04 09:24:04 +0900577 recoveryVariantNeeded = true
578 coreVariantNeeded = false
579 }
580
Jose Galmes6f843bc2020-12-11 13:36:29 -0800581 // If using a snapshot, the recovery variant under AOSP directories is not needed,
582 // except for kernel headers, which needs all variants.
Jose Galmes737d0a12021-05-25 22:06:41 -0700583 if !m.KernelHeadersDecorator() &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400584 !m.IsSnapshotPrebuilt() &&
Jose Galmes6f843bc2020-12-11 13:36:29 -0800585 usingRecoverySnapshot &&
Kiyoung Kim48f37782021-07-07 12:42:39 +0900586 !snapshot.IsRecoveryProprietaryModule(mctx) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800587 recoveryVariantNeeded = false
588 }
589
Inseob Kime498dd92020-08-04 09:24:04 +0900590 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400591 m.AppendExtraVariant(VendorVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900592 }
593
594 for _, variant := range android.FirstUniqueStrings(productVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400595 m.AppendExtraVariant(ProductVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900596 }
597
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400598 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
599 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
600 m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
601 m.SetCoreVariantNeeded(coreVariantNeeded)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800602
603 // Disable the module if no variants are needed.
604 if !ramdiskVariantNeeded &&
605 !recoveryVariantNeeded &&
606 !coreVariantNeeded &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400607 len(m.ExtraVariants()) == 0 {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800608 m.Disable()
609 }
Inseob Kime498dd92020-08-04 09:24:04 +0900610}
611
612func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
613 return c.Properties.CoreVariantNeeded
614}
615
616func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
617 return c.Properties.RamdiskVariantNeeded
618}
619
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700620func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
621 return c.Properties.VendorRamdiskVariantNeeded
622}
623
Inseob Kim08758f02021-04-08 21:13:22 +0900624func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
625 return false
626}
627
Inseob Kime498dd92020-08-04 09:24:04 +0900628func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
629 return c.Properties.RecoveryVariantNeeded
630}
631
632func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200633 return c.Properties.ExtraVersionedImageVariations
Inseob Kime498dd92020-08-04 09:24:04 +0900634}
635
Justin Yun63e9ec72020-10-29 16:49:43 +0900636func squashVendorSrcs(m *Module) {
637 if lib, ok := m.compiler.(*libraryDecorator); ok {
638 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
639 lib.baseCompiler.Properties.Target.Vendor.Srcs...)
640
641 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
642 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
643
644 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
645 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
646 }
647}
648
649func squashProductSrcs(m *Module) {
650 if lib, ok := m.compiler.(*libraryDecorator); ok {
651 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
652 lib.baseCompiler.Properties.Target.Product.Srcs...)
653
654 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
655 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
656
657 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
658 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
659 }
660}
661
662func squashRecoverySrcs(m *Module) {
663 if lib, ok := m.compiler.(*libraryDecorator); ok {
664 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
665 lib.baseCompiler.Properties.Target.Recovery.Srcs...)
666
667 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
668 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
669
670 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
671 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
672 }
673}
674
675func squashVendorRamdiskSrcs(m *Module) {
676 if lib, ok := m.compiler.(*libraryDecorator); ok {
677 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
678 }
679}
680
Inseob Kime498dd92020-08-04 09:24:04 +0900681func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
682 m := module.(*Module)
Yifan Hong6da33c22020-10-27 15:01:21 -0700683 if variant == android.RamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900684 m.MakeAsPlatform()
Yifan Hong6da33c22020-10-27 15:01:21 -0700685 } else if variant == android.VendorRamdiskVariation {
686 m.MakeAsPlatform()
687 squashVendorRamdiskSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900688 } else if variant == android.RecoveryVariation {
689 m.MakeAsPlatform()
690 squashRecoverySrcs(m)
691 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
692 m.Properties.ImageVariationPrefix = VendorVariationPrefix
693 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
694 squashVendorSrcs(m)
695
696 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
697 // Hide other vendor variants to avoid collision.
698 vndkVersion := ctx.DeviceConfig().VndkVersion()
699 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
700 m.Properties.HideFromMake = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800701 m.HideFromMake()
Inseob Kime498dd92020-08-04 09:24:04 +0900702 }
703 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
704 m.Properties.ImageVariationPrefix = ProductVariationPrefix
705 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
Justin Yun6977e8a2020-10-29 18:24:11 +0900706 squashProductSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900707 }
Colin Cross5271fea2021-04-27 13:06:04 -0700708
709 if c.NeedsVendorPublicLibraryVariants() &&
710 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) {
711 c.VendorProperties.IsVendorPublicLibrary = true
712 }
Inseob Kime498dd92020-08-04 09:24:04 +0900713}