blob: d02a2f3d263a085e2976e5a05e4a4da8d164c587 [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//
Colin Crossd079e0b2022-08-16 10:27:33 -07007// http://www.apache.org/licenses/LICENSE-2.0
Inseob Kime498dd92020-08-04 09:24:04 +09008//
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"
Jooyung Han85707de2023-12-01 14:21:13 +090026
27 "github.com/google/blueprint/proptools"
Inseob Kime498dd92020-08-04 09:24:04 +090028)
29
30var _ android.ImageInterface = (*Module)(nil)
31
Ivan Lozano3968d8f2020-12-14 11:27:52 -050032type ImageVariantType string
Inseob Kim74d25562020-08-04 00:41:38 +090033
34const (
Ivan Lozano3968d8f2020-12-14 11:27:52 -050035 coreImageVariant ImageVariantType = "core"
36 vendorImageVariant ImageVariantType = "vendor"
37 productImageVariant ImageVariantType = "product"
38 ramdiskImageVariant ImageVariantType = "ramdisk"
39 vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk"
40 recoveryImageVariant ImageVariantType = "recovery"
41 hostImageVariant ImageVariantType = "host"
Inseob Kim74d25562020-08-04 00:41:38 +090042)
43
Inseob Kime498dd92020-08-04 09:24:04 +090044const (
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090045 // VendorVariation is the variant name used for /vendor code that does not
46 // compile against the VNDK.
47 VendorVariation = "vendor"
48
Inseob Kime498dd92020-08-04 09:24:04 +090049 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
50 // against the VNDK.
51 VendorVariationPrefix = "vendor."
52
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +090053 // ProductVariation is the variant name used for /product code that does not
54 // compile against the VNDK.
55 ProductVariation = "product"
56
Inseob Kime498dd92020-08-04 09:24:04 +090057 // ProductVariationPrefix is the variant prefix used for /product code that compiles
58 // against the VNDK.
59 ProductVariationPrefix = "product."
60)
61
Inseob Kime498dd92020-08-04 09:24:04 +090062func (ctx *moduleContextImpl) inProduct() bool {
Ivan Lozanof9e21722020-12-02 09:00:51 -050063 return ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090064}
65
66func (ctx *moduleContextImpl) inVendor() bool {
Ivan Lozano3968d8f2020-12-14 11:27:52 -050067 return ctx.mod.InVendor()
Inseob Kime498dd92020-08-04 09:24:04 +090068}
69
70func (ctx *moduleContextImpl) inRamdisk() bool {
71 return ctx.mod.InRamdisk()
72}
73
Yifan Hong60e0cfb2020-10-21 15:17:56 -070074func (ctx *moduleContextImpl) inVendorRamdisk() bool {
75 return ctx.mod.InVendorRamdisk()
76}
77
Inseob Kime498dd92020-08-04 09:24:04 +090078func (ctx *moduleContextImpl) inRecovery() bool {
79 return ctx.mod.InRecovery()
80}
81
Colin Crossea30d852023-11-29 16:00:16 -080082func (c *Module) InstallInProduct() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090083 // Additionally check if this module is inProduct() that means it is a "product" variant of a
84 // module. As well as product specific modules, product variants must be installed to /product.
85 return c.InProduct()
86}
87
Colin Crossea30d852023-11-29 16:00:16 -080088func (c *Module) InstallInVendor() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090089 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a
90 // module. As well as SoC specific modules, vendor variants must be installed to /vendor
91 // unless they have "odm_available: true".
92 return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
93}
94
Colin Crossea30d852023-11-29 16:00:16 -080095func (c *Module) InstallInOdm() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090096 // Some vendor variants want to be installed to /odm by setting "odm_available: true".
97 return c.InVendor() && c.VendorVariantToOdm()
98}
99
Justin Yun63e9ec72020-10-29 16:49:43 +0900100// Returns true when this module is configured to have core and vendor variants.
Inseob Kime498dd92020-08-04 09:24:04 +0900101func (c *Module) HasVendorVariant() bool {
Justin Yunebcf0c52021-01-08 18:00:19 +0900102 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
103}
104
105// Returns true when this module creates a vendor variant and wants to install the vendor variant
106// to the odm partition.
107func (c *Module) VendorVariantToOdm() bool {
108 return Bool(c.VendorProperties.Odm_available)
Inseob Kime498dd92020-08-04 09:24:04 +0900109}
110
Justin Yun63e9ec72020-10-29 16:49:43 +0900111// Returns true when this module is configured to have core and product variants.
112func (c *Module) HasProductVariant() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900113 return Bool(c.VendorProperties.Product_available)
Justin Yun63e9ec72020-10-29 16:49:43 +0900114}
115
116// Returns true when this module is configured to have core and either product or vendor variants.
117func (c *Module) HasNonSystemVariants() bool {
Justin Yun6977e8a2020-10-29 18:24:11 +0900118 return c.HasVendorVariant() || c.HasProductVariant()
Justin Yun63e9ec72020-10-29 16:49:43 +0900119}
120
Inseob Kime498dd92020-08-04 09:24:04 +0900121// Returns true if the module is "product" variant. Usually these modules are installed in /product
Ivan Lozanof9e21722020-12-02 09:00:51 -0500122func (c *Module) InProduct() bool {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900123 return c.Properties.ImageVariation == ProductVariation
Inseob Kime498dd92020-08-04 09:24:04 +0900124}
125
126// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500127func (c *Module) InVendor() bool {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900128 return c.Properties.ImageVariation == VendorVariation
Inseob Kime498dd92020-08-04 09:24:04 +0900129}
130
Kiyoung Kimaa394802024-01-08 12:55:45 +0900131// Returns true if the module is "vendor" or "product" variant. This replaces previous UseVndk usages
132// which were misused to check if the module variant is vendor or product.
133func (c *Module) InVendorOrProduct() bool {
134 return c.InVendor() || c.InProduct()
135}
136
Inseob Kime498dd92020-08-04 09:24:04 +0900137func (c *Module) InRamdisk() bool {
138 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
139}
140
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700141func (c *Module) InVendorRamdisk() bool {
142 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
143}
144
Inseob Kime498dd92020-08-04 09:24:04 +0900145func (c *Module) InRecovery() bool {
146 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
147}
148
149func (c *Module) OnlyInRamdisk() bool {
150 return c.ModuleBase.InstallInRamdisk()
151}
152
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700153func (c *Module) OnlyInVendorRamdisk() bool {
154 return c.ModuleBase.InstallInVendorRamdisk()
155}
156
Inseob Kime498dd92020-08-04 09:24:04 +0900157func (c *Module) OnlyInRecovery() bool {
158 return c.ModuleBase.InstallInRecovery()
159}
160
Justin Yun6977e8a2020-10-29 18:24:11 +0900161func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
162 if v.Kind() != reflect.Struct {
163 return true
164 }
165 for i := 0; i < v.NumField(); i++ {
166 prop := v.Field(i)
167 if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
168 vendor_prop := prop.FieldByName("Vendor")
169 product_prop := prop.FieldByName("Product")
170 if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
171 // Neither Target.Vendor nor Target.Product is defined
172 continue
173 }
174 if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
175 !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
176 // If only one of either Target.Vendor or Target.Product is
177 // defined or they have different values, it fails the build
178 // since VNDK must have the same properties for both vendor
179 // and product variants.
180 return false
181 }
182 } else if !visitPropsAndCompareVendorAndProductProps(prop) {
183 // Visit the substructures to find Target.Vendor and Target.Product
184 return false
185 }
186 }
187 return true
188}
189
190// In the case of VNDK, vendor and product variants must have the same properties.
191// VNDK installs only one file and shares it for both vendor and product modules on
192// runtime. We may not define different versions of a VNDK lib for each partition.
193// This function is used only for the VNDK modules that is available to both vendor
194// and product partitions.
195func (c *Module) compareVendorAndProductProps() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900196 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
Justin Yun6977e8a2020-10-29 18:24:11 +0900197 panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
198 }
199 for _, properties := range c.GetProperties() {
200 if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
201 return false
202 }
203 }
204 return true
205}
206
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400207// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules.
208type ImageMutatableModule interface {
209 android.Module
210 LinkableInterface
211
212 // AndroidModuleBase returns the android.ModuleBase for this module
213 AndroidModuleBase() *android.ModuleBase
214
215 // VendorAvailable returns true if this module is available on the vendor image.
216 VendorAvailable() bool
217
218 // OdmAvailable returns true if this module is available on the odm image.
219 OdmAvailable() bool
220
221 // ProductAvailable returns true if this module is available on the product image.
222 ProductAvailable() bool
223
224 // RamdiskAvailable returns true if this module is available on the ramdisk image.
225 RamdiskAvailable() bool
226
227 // RecoveryAvailable returns true if this module is available on the recovery image.
228 RecoveryAvailable() bool
229
230 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
231 VendorRamdiskAvailable() bool
232
233 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
234 IsSnapshotPrebuilt() bool
235
236 // SnapshotVersion returns the snapshot version for this module.
237 SnapshotVersion(mctx android.BaseModuleContext) string
238
239 // SdkVersion returns the SDK version for this module.
240 SdkVersion() string
241
242 // ExtraVariants returns the list of extra variants this module requires.
243 ExtraVariants() []string
244
245 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
246 AppendExtraVariant(extraVariant string)
247
248 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
249 SetRamdiskVariantNeeded(b bool)
250
251 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
252 SetVendorRamdiskVariantNeeded(b bool)
253
254 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
255 SetRecoveryVariantNeeded(b bool)
256
257 // SetCoreVariantNeeded sets whether the Core Variant is needed.
258 SetCoreVariantNeeded(b bool)
259}
260
261var _ ImageMutatableModule = (*Module)(nil)
262
Inseob Kime498dd92020-08-04 09:24:04 +0900263func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400264 m.CheckVndkProperties(mctx)
265 MutateImage(mctx, m)
266}
267
268// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
269// If properties are not set correctly, results in a module context property error.
270func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
Inseob Kime498dd92020-08-04 09:24:04 +0900271 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
272 productSpecific := mctx.ProductSpecific()
273
Inseob Kime498dd92020-08-04 09:24:04 +0900274 if vndkdep := m.vndkdep; vndkdep != nil {
275 if vndkdep.isVndk() {
276 if vendorSpecific || productSpecific {
277 if !vndkdep.isVndkExt() {
278 mctx.PropertyErrorf("vndk",
279 "must set `extends: \"...\"` to vndk extension")
Justin Yunc0d8c492021-01-07 17:45:31 +0900280 } else if Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900281 mctx.PropertyErrorf("vendor_available",
282 "must not set at the same time as `vndk: {extends: \"...\"}`")
Justin Yunc0d8c492021-01-07 17:45:31 +0900283 } else if Bool(m.VendorProperties.Product_available) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900284 mctx.PropertyErrorf("product_available",
285 "must not set at the same time as `vndk: {extends: \"...\"}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900286 }
287 } else {
288 if vndkdep.isVndkExt() {
289 mctx.PropertyErrorf("vndk",
290 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
291 m.getVndkExtendsModuleName())
292 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900293 if !Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900294 mctx.PropertyErrorf("vndk",
Justin Yunc0d8c492021-01-07 17:45:31 +0900295 "vendor_available must be set to true when `vndk: {enabled: true}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900296 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900297 if Bool(m.VendorProperties.Product_available) {
Justin Yunfd9e8042020-12-23 18:23:14 +0900298 // If a VNDK module creates both product and vendor variants, they
299 // must have the same properties since they share a single VNDK
300 // library on runtime.
Justin Yun6977e8a2020-10-29 18:24:11 +0900301 if !m.compareVendorAndProductProps() {
302 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
303 }
304 }
Inseob Kime498dd92020-08-04 09:24:04 +0900305 }
306 } else {
307 if vndkdep.isVndkSp() {
308 mctx.PropertyErrorf("vndk",
309 "must set `enabled: true` to set `support_system_process: true`")
310 }
311 if vndkdep.isVndkExt() {
312 mctx.PropertyErrorf("vndk",
313 "must set `enabled: true` to set `extends: %q`",
314 m.getVndkExtendsModuleName())
315 }
316 }
317 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400318}
319
320func (m *Module) VendorAvailable() bool {
321 return Bool(m.VendorProperties.Vendor_available)
322}
323
324func (m *Module) OdmAvailable() bool {
325 return Bool(m.VendorProperties.Odm_available)
326}
327
328func (m *Module) ProductAvailable() bool {
329 return Bool(m.VendorProperties.Product_available)
330}
331
332func (m *Module) RamdiskAvailable() bool {
333 return Bool(m.Properties.Ramdisk_available)
334}
335
336func (m *Module) VendorRamdiskAvailable() bool {
337 return Bool(m.Properties.Vendor_ramdisk_available)
338}
339
340func (m *Module) AndroidModuleBase() *android.ModuleBase {
341 return &m.ModuleBase
342}
343
344func (m *Module) RecoveryAvailable() bool {
345 return Bool(m.Properties.Recovery_available)
346}
347
348func (m *Module) ExtraVariants() []string {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200349 return m.Properties.ExtraVersionedImageVariations
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400350}
351
352func (m *Module) AppendExtraVariant(extraVariant string) {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200353 m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant)
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400354}
355
356func (m *Module) SetRamdiskVariantNeeded(b bool) {
357 m.Properties.RamdiskVariantNeeded = b
358}
359
360func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
361 m.Properties.VendorRamdiskVariantNeeded = b
362}
363
364func (m *Module) SetRecoveryVariantNeeded(b bool) {
365 m.Properties.RecoveryVariantNeeded = b
366}
367
368func (m *Module) SetCoreVariantNeeded(b bool) {
369 m.Properties.CoreVariantNeeded = b
370}
371
372func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
Ivan Lozanod1dec542021-05-26 15:33:11 -0400373 if snapshot, ok := m.linker.(SnapshotInterface); ok {
374 return snapshot.Version()
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400375 } else {
376 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
377 // Should we be panicking here instead?
378 return ""
379 }
380}
381
382func (m *Module) KernelHeadersDecorator() bool {
383 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
384 return true
385 }
386 return false
387}
388
389// MutateImage handles common image mutations for ImageMutatableModule interfaces.
390func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
391 // Validation check
392 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
393 productSpecific := mctx.ProductSpecific()
394
395 if m.VendorAvailable() {
396 if vendorSpecific {
397 mctx.PropertyErrorf("vendor_available",
398 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
399 }
400 if m.OdmAvailable() {
401 mctx.PropertyErrorf("vendor_available",
402 "doesn't make sense at the same time as `odm_available: true`")
403 }
404 }
405
406 if m.OdmAvailable() {
407 if vendorSpecific {
408 mctx.PropertyErrorf("odm_available",
409 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
410 }
411 }
412
413 if m.ProductAvailable() {
414 if productSpecific {
415 mctx.PropertyErrorf("product_available",
416 "doesn't make sense at the same time as `product_specific: true`")
417 }
418 if vendorSpecific {
419 mctx.PropertyErrorf("product_available",
420 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
421 }
422 }
Inseob Kime498dd92020-08-04 09:24:04 +0900423
424 var coreVariantNeeded bool = false
425 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700426 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900427 var recoveryVariantNeeded bool = false
428
429 var vendorVariants []string
430 var productVariants []string
431
432 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
433 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
Jose Galmes6f843bc2020-12-11 13:36:29 -0800434 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
435 usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
436 recoverySnapshotVersion != ""
Justin Yundee806f2021-05-18 23:10:00 +0900437 needVndkVersionVendorVariantForLlndk := false
438 if boardVndkVersion != "" {
439 boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
440 if err == nil && !boardVndkApiLevel.IsPreview() {
441 // VNDK snapshot newer than v30 has LLNDK stub libraries.
442 // Only the VNDK version less than or equal to v30 requires generating the vendor
443 // variant of the VNDK version from the source tree.
444 needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
445 }
446 }
Inseob Kime498dd92020-08-04 09:24:04 +0900447 if boardVndkVersion == "current" {
448 boardVndkVersion = platformVndkVersion
449 }
Inseob Kime498dd92020-08-04 09:24:04 +0900450
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
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900456 vendorVariants = append(vendorVariants, platformVndkVersion)
457 productVariants = append(productVariants, platformVndkVersion)
Justin Yundee806f2021-05-18 23:10:00 +0900458 // Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
459 // provide the LLNDK stub libraries.
460 if needVndkVersionVendorVariantForLlndk {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800461 vendorVariants = append(vendorVariants, boardVndkVersion)
462 }
Colin Cross5271fea2021-04-27 13:06:04 -0700463 } else if m.NeedsVendorPublicLibraryVariants() {
464 // A vendor public library has the implementation on /vendor, with stub variants
465 // for system and product.
466 coreVariantNeeded = true
467 vendorVariants = append(vendorVariants, boardVndkVersion)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900468 productVariants = append(productVariants, platformVndkVersion)
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400469 } else if m.IsSnapshotPrebuilt() {
Inseob Kime498dd92020-08-04 09:24:04 +0900470 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
471 // PRODUCT_EXTRA_VNDK_VERSIONS.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400472 if m.InstallInRecovery() {
473 recoveryVariantNeeded = true
Inseob Kime498dd92020-08-04 09:24:04 +0900474 } else {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400475 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
Inseob Kime498dd92020-08-04 09:24:04 +0900476 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500477 } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
Justin Yun63e9ec72020-10-29 16:49:43 +0900478 // This will be available to /system unless it is product_specific
479 // which will be handled later.
Inseob Kime498dd92020-08-04 09:24:04 +0900480 coreVariantNeeded = true
481
482 // We assume that modules under proprietary paths are compatible for
483 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
484 // PLATFORM_VNDK_VERSION.
Justin Yun63e9ec72020-10-29 16:49:43 +0900485 if m.HasVendorVariant() {
Kiyoung Kim48f37782021-07-07 12:42:39 +0900486 if snapshot.IsVendorProprietaryModule(mctx) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900487 vendorVariants = append(vendorVariants, boardVndkVersion)
488 } else {
489 vendorVariants = append(vendorVariants, platformVndkVersion)
490 }
Inseob Kime498dd92020-08-04 09:24:04 +0900491 }
492
Justin Yun6977e8a2020-10-29 18:24:11 +0900493 // product_available modules are available to /product.
494 if m.HasProductVariant() {
495 productVariants = append(productVariants, platformVndkVersion)
Inseob Kime498dd92020-08-04 09:24:04 +0900496 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400497 } else if vendorSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900498 // This will be available in /vendor (or /odm) only
499
500 // kernel_headers is a special module type whose exported headers
501 // are coming from DeviceKernelHeaders() which is always vendor
502 // dependent. They'll always have both vendor variants.
503 // For other modules, we assume that modules under proprietary
504 // paths are compatible for BOARD_VNDK_VERSION. The other modules
505 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400506 if m.KernelHeadersDecorator() {
Inseob Kime498dd92020-08-04 09:24:04 +0900507 vendorVariants = append(vendorVariants,
508 platformVndkVersion,
509 boardVndkVersion,
510 )
Kiyoung Kim48f37782021-07-07 12:42:39 +0900511 } else if snapshot.IsVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900512 vendorVariants = append(vendorVariants, boardVndkVersion)
513 } else {
514 vendorVariants = append(vendorVariants, platformVndkVersion)
515 }
516 } else {
517 // This is either in /system (or similar: /data), or is a
jiajia tangcd1c27b2022-07-21 18:04:37 +0800518 // module built with the NDK. Modules built with the NDK
Inseob Kime498dd92020-08-04 09:24:04 +0900519 // will be restricted using the existing link type checks.
520 coreVariantNeeded = true
521 }
522
Justin Yunaf1fde42023-09-27 16:22:10 +0900523 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
524 // The module has "product_specific: true" that does not create core variant.
525 coreVariantNeeded = false
526 productVariants = append(productVariants, platformVndkVersion)
Inseob Kime498dd92020-08-04 09:24:04 +0900527 }
528
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400529 if m.RamdiskAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900530 ramdiskVariantNeeded = true
531 }
532
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400533 if m.AndroidModuleBase().InstallInRamdisk() {
Inseob Kime498dd92020-08-04 09:24:04 +0900534 ramdiskVariantNeeded = true
535 coreVariantNeeded = false
536 }
537
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400538 if m.VendorRamdiskAvailable() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700539 vendorRamdiskVariantNeeded = true
540 }
541
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400542 if m.AndroidModuleBase().InstallInVendorRamdisk() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700543 vendorRamdiskVariantNeeded = true
544 coreVariantNeeded = false
545 }
546
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400547 if m.RecoveryAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900548 recoveryVariantNeeded = true
549 }
550
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400551 if m.AndroidModuleBase().InstallInRecovery() {
Inseob Kime498dd92020-08-04 09:24:04 +0900552 recoveryVariantNeeded = true
553 coreVariantNeeded = false
554 }
555
Jose Galmes6f843bc2020-12-11 13:36:29 -0800556 // If using a snapshot, the recovery variant under AOSP directories is not needed,
557 // except for kernel headers, which needs all variants.
Jose Galmes737d0a12021-05-25 22:06:41 -0700558 if !m.KernelHeadersDecorator() &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400559 !m.IsSnapshotPrebuilt() &&
Jose Galmes6f843bc2020-12-11 13:36:29 -0800560 usingRecoverySnapshot &&
Kiyoung Kim48f37782021-07-07 12:42:39 +0900561 !snapshot.IsRecoveryProprietaryModule(mctx) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800562 recoveryVariantNeeded = false
563 }
564
Inseob Kime498dd92020-08-04 09:24:04 +0900565 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900566 if variant == "" {
567 m.AppendExtraVariant(VendorVariation)
568 } else {
569 m.AppendExtraVariant(VendorVariationPrefix + variant)
570 }
Inseob Kime498dd92020-08-04 09:24:04 +0900571 }
572
573 for _, variant := range android.FirstUniqueStrings(productVariants) {
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900574 if variant == "" {
575 m.AppendExtraVariant(ProductVariation)
576 } else {
577 m.AppendExtraVariant(ProductVariationPrefix + variant)
578 }
Inseob Kime498dd92020-08-04 09:24:04 +0900579 }
580
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400581 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
582 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
583 m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
584 m.SetCoreVariantNeeded(coreVariantNeeded)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800585
586 // Disable the module if no variants are needed.
587 if !ramdiskVariantNeeded &&
588 !recoveryVariantNeeded &&
589 !coreVariantNeeded &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400590 len(m.ExtraVariants()) == 0 {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800591 m.Disable()
592 }
Inseob Kime498dd92020-08-04 09:24:04 +0900593}
594
595func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
596 return c.Properties.CoreVariantNeeded
597}
598
599func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
600 return c.Properties.RamdiskVariantNeeded
601}
602
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700603func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
604 return c.Properties.VendorRamdiskVariantNeeded
605}
606
Inseob Kim08758f02021-04-08 21:13:22 +0900607func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
608 return false
609}
610
Inseob Kime498dd92020-08-04 09:24:04 +0900611func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
612 return c.Properties.RecoveryVariantNeeded
613}
614
615func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200616 return c.Properties.ExtraVersionedImageVariations
Inseob Kime498dd92020-08-04 09:24:04 +0900617}
618
Justin Yun63e9ec72020-10-29 16:49:43 +0900619func squashVendorSrcs(m *Module) {
620 if lib, ok := m.compiler.(*libraryDecorator); ok {
621 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
622 lib.baseCompiler.Properties.Target.Vendor.Srcs...)
623
624 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
625 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
626
627 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
628 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
Jooyung Han85707de2023-12-01 14:21:13 +0900629
630 if lib.Properties.Target.Vendor.No_stubs {
631 proptools.Clear(&lib.Properties.Stubs)
632 }
Justin Yun63e9ec72020-10-29 16:49:43 +0900633 }
634}
635
636func squashProductSrcs(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.Product.Srcs...)
640
641 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
642 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
643
644 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
645 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
Jooyung Han85707de2023-12-01 14:21:13 +0900646
647 if lib.Properties.Target.Product.No_stubs {
648 proptools.Clear(&lib.Properties.Stubs)
649 }
Justin Yun63e9ec72020-10-29 16:49:43 +0900650 }
651}
652
653func squashRecoverySrcs(m *Module) {
654 if lib, ok := m.compiler.(*libraryDecorator); ok {
655 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
656 lib.baseCompiler.Properties.Target.Recovery.Srcs...)
657
658 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
659 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
660
661 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
662 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
663 }
664}
665
666func squashVendorRamdiskSrcs(m *Module) {
667 if lib, ok := m.compiler.(*libraryDecorator); ok {
668 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
669 }
670}
671
Christopher Ferrise0202c42023-07-27 17:06:46 -0700672func squashRamdiskSrcs(m *Module) {
673 if lib, ok := m.compiler.(*libraryDecorator); ok {
674 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Ramdisk.Exclude_srcs...)
675 }
676}
677
Inseob Kime498dd92020-08-04 09:24:04 +0900678func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
679 m := module.(*Module)
Yifan Hong6da33c22020-10-27 15:01:21 -0700680 if variant == android.RamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900681 m.MakeAsPlatform()
Christopher Ferrise0202c42023-07-27 17:06:46 -0700682 squashRamdiskSrcs(m)
Yifan Hong6da33c22020-10-27 15:01:21 -0700683 } else if variant == android.VendorRamdiskVariation {
684 m.MakeAsPlatform()
685 squashVendorRamdiskSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900686 } else if variant == android.RecoveryVariation {
687 m.MakeAsPlatform()
688 squashRecoverySrcs(m)
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900689 } else if strings.HasPrefix(variant, VendorVariation) {
690 m.Properties.ImageVariation = VendorVariation
691
692 if strings.HasPrefix(variant, VendorVariationPrefix) {
693 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
694 }
Inseob Kime498dd92020-08-04 09:24:04 +0900695 squashVendorSrcs(m)
696
697 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
698 // Hide other vendor variants to avoid collision.
699 vndkVersion := ctx.DeviceConfig().VndkVersion()
700 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
701 m.Properties.HideFromMake = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800702 m.HideFromMake()
Inseob Kime498dd92020-08-04 09:24:04 +0900703 }
Kiyoung Kimb5fdb2e2024-01-03 14:24:34 +0900704 } else if strings.HasPrefix(variant, ProductVariation) {
705 m.Properties.ImageVariation = ProductVariation
706 if strings.HasPrefix(variant, ProductVariationPrefix) {
707 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
708 }
Justin Yun6977e8a2020-10-29 18:24:11 +0900709 squashProductSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900710 }
Colin Cross5271fea2021-04-27 13:06:04 -0700711
712 if c.NeedsVendorPublicLibraryVariants() &&
713 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) {
714 c.VendorProperties.IsVendorPublicLibrary = true
715 }
Inseob Kime498dd92020-08-04 09:24:04 +0900716}