blob: 4f36111ece21ebff8bc6b667e2aee5e488b65e2a [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 (
45 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
46 // against the VNDK.
47 VendorVariationPrefix = "vendor."
48
49 // ProductVariationPrefix is the variant prefix used for /product code that compiles
50 // against the VNDK.
51 ProductVariationPrefix = "product."
52)
53
54func (ctx *moduleContext) ProductSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090055 return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext()
Inseob Kime498dd92020-08-04 09:24:04 +090056}
57
58func (ctx *moduleContext) SocSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090059 return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext()
Justin Yunebcf0c52021-01-08 18:00:19 +090060}
61
62func (ctx *moduleContext) DeviceSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090063 return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext()
Inseob Kime498dd92020-08-04 09:24:04 +090064}
65
66func (ctx *moduleContextImpl) inProduct() bool {
Ivan Lozanof9e21722020-12-02 09:00:51 -050067 return ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090068}
69
70func (ctx *moduleContextImpl) inVendor() bool {
Ivan Lozano3968d8f2020-12-14 11:27:52 -050071 return ctx.mod.InVendor()
Inseob Kime498dd92020-08-04 09:24:04 +090072}
73
74func (ctx *moduleContextImpl) inRamdisk() bool {
75 return ctx.mod.InRamdisk()
76}
77
Yifan Hong60e0cfb2020-10-21 15:17:56 -070078func (ctx *moduleContextImpl) inVendorRamdisk() bool {
79 return ctx.mod.InVendorRamdisk()
80}
81
Inseob Kime498dd92020-08-04 09:24:04 +090082func (ctx *moduleContextImpl) inRecovery() bool {
83 return ctx.mod.InRecovery()
84}
85
Justin Yun7f99ec72021-04-12 13:19:28 +090086func (c *Module) productSpecificModuleContext() bool {
87 // Additionally check if this module is inProduct() that means it is a "product" variant of a
88 // module. As well as product specific modules, product variants must be installed to /product.
89 return c.InProduct()
90}
91
92func (c *Module) socSpecificModuleContext() bool {
93 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a
94 // module. As well as SoC specific modules, vendor variants must be installed to /vendor
95 // unless they have "odm_available: true".
96 return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
97}
98
99func (c *Module) deviceSpecificModuleContext() bool {
100 // Some vendor variants want to be installed to /odm by setting "odm_available: true".
101 return c.InVendor() && c.VendorVariantToOdm()
102}
103
Justin Yun63e9ec72020-10-29 16:49:43 +0900104// Returns true when this module is configured to have core and vendor variants.
Inseob Kime498dd92020-08-04 09:24:04 +0900105func (c *Module) HasVendorVariant() bool {
Justin Yunebcf0c52021-01-08 18:00:19 +0900106 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
107}
108
109// Returns true when this module creates a vendor variant and wants to install the vendor variant
110// to the odm partition.
111func (c *Module) VendorVariantToOdm() bool {
112 return Bool(c.VendorProperties.Odm_available)
Inseob Kime498dd92020-08-04 09:24:04 +0900113}
114
Justin Yun63e9ec72020-10-29 16:49:43 +0900115// Returns true when this module is configured to have core and product variants.
116func (c *Module) HasProductVariant() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900117 return Bool(c.VendorProperties.Product_available)
Justin Yun63e9ec72020-10-29 16:49:43 +0900118}
119
120// Returns true when this module is configured to have core and either product or vendor variants.
121func (c *Module) HasNonSystemVariants() bool {
Justin Yun6977e8a2020-10-29 18:24:11 +0900122 return c.HasVendorVariant() || c.HasProductVariant()
Justin Yun63e9ec72020-10-29 16:49:43 +0900123}
124
Inseob Kime498dd92020-08-04 09:24:04 +0900125// Returns true if the module is "product" variant. Usually these modules are installed in /product
Ivan Lozanof9e21722020-12-02 09:00:51 -0500126func (c *Module) InProduct() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900127 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
128}
129
130// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500131func (c *Module) InVendor() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900132 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
133}
134
135func (c *Module) InRamdisk() bool {
136 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
137}
138
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700139func (c *Module) InVendorRamdisk() bool {
140 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
141}
142
Inseob Kime498dd92020-08-04 09:24:04 +0900143func (c *Module) InRecovery() bool {
144 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
145}
146
147func (c *Module) OnlyInRamdisk() bool {
148 return c.ModuleBase.InstallInRamdisk()
149}
150
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700151func (c *Module) OnlyInVendorRamdisk() bool {
152 return c.ModuleBase.InstallInVendorRamdisk()
153}
154
Inseob Kime498dd92020-08-04 09:24:04 +0900155func (c *Module) OnlyInRecovery() bool {
156 return c.ModuleBase.InstallInRecovery()
157}
158
Justin Yun6977e8a2020-10-29 18:24:11 +0900159func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
160 if v.Kind() != reflect.Struct {
161 return true
162 }
163 for i := 0; i < v.NumField(); i++ {
164 prop := v.Field(i)
165 if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
166 vendor_prop := prop.FieldByName("Vendor")
167 product_prop := prop.FieldByName("Product")
168 if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
169 // Neither Target.Vendor nor Target.Product is defined
170 continue
171 }
172 if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
173 !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
174 // If only one of either Target.Vendor or Target.Product is
175 // defined or they have different values, it fails the build
176 // since VNDK must have the same properties for both vendor
177 // and product variants.
178 return false
179 }
180 } else if !visitPropsAndCompareVendorAndProductProps(prop) {
181 // Visit the substructures to find Target.Vendor and Target.Product
182 return false
183 }
184 }
185 return true
186}
187
188// In the case of VNDK, vendor and product variants must have the same properties.
189// VNDK installs only one file and shares it for both vendor and product modules on
190// runtime. We may not define different versions of a VNDK lib for each partition.
191// This function is used only for the VNDK modules that is available to both vendor
192// and product partitions.
193func (c *Module) compareVendorAndProductProps() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900194 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
Justin Yun6977e8a2020-10-29 18:24:11 +0900195 panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
196 }
197 for _, properties := range c.GetProperties() {
198 if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
199 return false
200 }
201 }
202 return true
203}
204
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400205// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules.
206type ImageMutatableModule interface {
207 android.Module
208 LinkableInterface
209
210 // AndroidModuleBase returns the android.ModuleBase for this module
211 AndroidModuleBase() *android.ModuleBase
212
213 // VendorAvailable returns true if this module is available on the vendor image.
214 VendorAvailable() bool
215
216 // OdmAvailable returns true if this module is available on the odm image.
217 OdmAvailable() bool
218
219 // ProductAvailable returns true if this module is available on the product image.
220 ProductAvailable() bool
221
222 // RamdiskAvailable returns true if this module is available on the ramdisk image.
223 RamdiskAvailable() bool
224
225 // RecoveryAvailable returns true if this module is available on the recovery image.
226 RecoveryAvailable() bool
227
228 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
229 VendorRamdiskAvailable() bool
230
231 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
232 IsSnapshotPrebuilt() bool
233
234 // SnapshotVersion returns the snapshot version for this module.
235 SnapshotVersion(mctx android.BaseModuleContext) string
236
237 // SdkVersion returns the SDK version for this module.
238 SdkVersion() string
239
240 // ExtraVariants returns the list of extra variants this module requires.
241 ExtraVariants() []string
242
243 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
244 AppendExtraVariant(extraVariant string)
245
246 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
247 SetRamdiskVariantNeeded(b bool)
248
249 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
250 SetVendorRamdiskVariantNeeded(b bool)
251
252 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
253 SetRecoveryVariantNeeded(b bool)
254
255 // SetCoreVariantNeeded sets whether the Core Variant is needed.
256 SetCoreVariantNeeded(b bool)
257}
258
259var _ ImageMutatableModule = (*Module)(nil)
260
Inseob Kime498dd92020-08-04 09:24:04 +0900261func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400262 m.CheckVndkProperties(mctx)
263 MutateImage(mctx, m)
264}
265
266// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
267// If properties are not set correctly, results in a module context property error.
268func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
Inseob Kime498dd92020-08-04 09:24:04 +0900269 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
270 productSpecific := mctx.ProductSpecific()
271
Inseob Kime498dd92020-08-04 09:24:04 +0900272 if vndkdep := m.vndkdep; vndkdep != nil {
273 if vndkdep.isVndk() {
274 if vendorSpecific || productSpecific {
275 if !vndkdep.isVndkExt() {
276 mctx.PropertyErrorf("vndk",
277 "must set `extends: \"...\"` to vndk extension")
Justin Yunc0d8c492021-01-07 17:45:31 +0900278 } else if Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900279 mctx.PropertyErrorf("vendor_available",
280 "must not set at the same time as `vndk: {extends: \"...\"}`")
Justin Yunc0d8c492021-01-07 17:45:31 +0900281 } else if Bool(m.VendorProperties.Product_available) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900282 mctx.PropertyErrorf("product_available",
283 "must not set at the same time as `vndk: {extends: \"...\"}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900284 }
285 } else {
286 if vndkdep.isVndkExt() {
287 mctx.PropertyErrorf("vndk",
288 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
289 m.getVndkExtendsModuleName())
290 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900291 if !Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900292 mctx.PropertyErrorf("vndk",
Justin Yunc0d8c492021-01-07 17:45:31 +0900293 "vendor_available must be set to true when `vndk: {enabled: true}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900294 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900295 if Bool(m.VendorProperties.Product_available) {
Justin Yunfd9e8042020-12-23 18:23:14 +0900296 // If a VNDK module creates both product and vendor variants, they
297 // must have the same properties since they share a single VNDK
298 // library on runtime.
Justin Yun6977e8a2020-10-29 18:24:11 +0900299 if !m.compareVendorAndProductProps() {
300 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
301 }
302 }
Inseob Kime498dd92020-08-04 09:24:04 +0900303 }
304 } else {
305 if vndkdep.isVndkSp() {
306 mctx.PropertyErrorf("vndk",
307 "must set `enabled: true` to set `support_system_process: true`")
308 }
309 if vndkdep.isVndkExt() {
310 mctx.PropertyErrorf("vndk",
311 "must set `enabled: true` to set `extends: %q`",
312 m.getVndkExtendsModuleName())
313 }
314 }
315 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400316}
317
318func (m *Module) VendorAvailable() bool {
319 return Bool(m.VendorProperties.Vendor_available)
320}
321
322func (m *Module) OdmAvailable() bool {
323 return Bool(m.VendorProperties.Odm_available)
324}
325
326func (m *Module) ProductAvailable() bool {
327 return Bool(m.VendorProperties.Product_available)
328}
329
330func (m *Module) RamdiskAvailable() bool {
331 return Bool(m.Properties.Ramdisk_available)
332}
333
334func (m *Module) VendorRamdiskAvailable() bool {
335 return Bool(m.Properties.Vendor_ramdisk_available)
336}
337
338func (m *Module) AndroidModuleBase() *android.ModuleBase {
339 return &m.ModuleBase
340}
341
342func (m *Module) RecoveryAvailable() bool {
343 return Bool(m.Properties.Recovery_available)
344}
345
346func (m *Module) ExtraVariants() []string {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200347 return m.Properties.ExtraVersionedImageVariations
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400348}
349
350func (m *Module) AppendExtraVariant(extraVariant string) {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200351 m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant)
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400352}
353
354func (m *Module) SetRamdiskVariantNeeded(b bool) {
355 m.Properties.RamdiskVariantNeeded = b
356}
357
358func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
359 m.Properties.VendorRamdiskVariantNeeded = b
360}
361
362func (m *Module) SetRecoveryVariantNeeded(b bool) {
363 m.Properties.RecoveryVariantNeeded = b
364}
365
366func (m *Module) SetCoreVariantNeeded(b bool) {
367 m.Properties.CoreVariantNeeded = b
368}
369
370func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
Ivan Lozanod1dec542021-05-26 15:33:11 -0400371 if snapshot, ok := m.linker.(SnapshotInterface); ok {
372 return snapshot.Version()
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400373 } else {
374 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
375 // Should we be panicking here instead?
376 return ""
377 }
378}
379
380func (m *Module) KernelHeadersDecorator() bool {
381 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
382 return true
383 }
384 return false
385}
386
387// MutateImage handles common image mutations for ImageMutatableModule interfaces.
388func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
389 // Validation check
390 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
391 productSpecific := mctx.ProductSpecific()
392
393 if m.VendorAvailable() {
394 if vendorSpecific {
395 mctx.PropertyErrorf("vendor_available",
396 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
397 }
398 if m.OdmAvailable() {
399 mctx.PropertyErrorf("vendor_available",
400 "doesn't make sense at the same time as `odm_available: true`")
401 }
402 }
403
404 if m.OdmAvailable() {
405 if vendorSpecific {
406 mctx.PropertyErrorf("odm_available",
407 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
408 }
409 }
410
411 if m.ProductAvailable() {
412 if productSpecific {
413 mctx.PropertyErrorf("product_available",
414 "doesn't make sense at the same time as `product_specific: true`")
415 }
416 if vendorSpecific {
417 mctx.PropertyErrorf("product_available",
418 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
419 }
420 }
Inseob Kime498dd92020-08-04 09:24:04 +0900421
422 var coreVariantNeeded bool = false
423 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700424 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900425 var recoveryVariantNeeded bool = false
426
427 var vendorVariants []string
428 var productVariants []string
429
430 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
431 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
Jose Galmes6f843bc2020-12-11 13:36:29 -0800432 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
433 usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
434 recoverySnapshotVersion != ""
Justin Yundee806f2021-05-18 23:10:00 +0900435 needVndkVersionVendorVariantForLlndk := false
436 if boardVndkVersion != "" {
437 boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
438 if err == nil && !boardVndkApiLevel.IsPreview() {
439 // VNDK snapshot newer than v30 has LLNDK stub libraries.
440 // Only the VNDK version less than or equal to v30 requires generating the vendor
441 // variant of the VNDK version from the source tree.
442 needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
443 }
444 }
Inseob Kime498dd92020-08-04 09:24:04 +0900445 if boardVndkVersion == "current" {
446 boardVndkVersion = platformVndkVersion
447 }
Inseob Kime498dd92020-08-04 09:24:04 +0900448
Colin Cross203b4212021-04-26 17:19:41 -0700449 if m.NeedsLlndkVariants() {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800450 // This is an LLNDK library. The implementation of the library will be on /system,
451 // and vendor and product variants will be created with LLNDK stubs.
452 // The LLNDK libraries need vendor variants even if there is no VNDK.
Colin Cross203b4212021-04-26 17:19:41 -0700453 coreVariantNeeded = true
Colin Crossb5f6fa62021-01-06 17:05:04 -0800454 if platformVndkVersion != "" {
455 vendorVariants = append(vendorVariants, platformVndkVersion)
456 productVariants = append(productVariants, platformVndkVersion)
457 }
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)
468 if platformVndkVersion != "" {
469 productVariants = append(productVariants, platformVndkVersion)
470 }
Colin Crossb5f6fa62021-01-06 17:05:04 -0800471 } else if boardVndkVersion == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900472 // If the device isn't compiling against the VNDK, we always
473 // use the core mode.
474 coreVariantNeeded = true
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400475 } else if m.IsSnapshotPrebuilt() {
Inseob Kime498dd92020-08-04 09:24:04 +0900476 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
477 // PRODUCT_EXTRA_VNDK_VERSIONS.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400478 if m.InstallInRecovery() {
479 recoveryVariantNeeded = true
Inseob Kime498dd92020-08-04 09:24:04 +0900480 } else {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400481 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
Inseob Kime498dd92020-08-04 09:24:04 +0900482 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500483 } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
Justin Yun63e9ec72020-10-29 16:49:43 +0900484 // This will be available to /system unless it is product_specific
485 // which will be handled later.
Inseob Kime498dd92020-08-04 09:24:04 +0900486 coreVariantNeeded = true
487
488 // We assume that modules under proprietary paths are compatible for
489 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
490 // PLATFORM_VNDK_VERSION.
Justin Yun63e9ec72020-10-29 16:49:43 +0900491 if m.HasVendorVariant() {
Kiyoung Kim48f37782021-07-07 12:42:39 +0900492 if snapshot.IsVendorProprietaryModule(mctx) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900493 vendorVariants = append(vendorVariants, boardVndkVersion)
494 } else {
495 vendorVariants = append(vendorVariants, platformVndkVersion)
496 }
Inseob Kime498dd92020-08-04 09:24:04 +0900497 }
498
Justin Yun6977e8a2020-10-29 18:24:11 +0900499 // product_available modules are available to /product.
500 if m.HasProductVariant() {
501 productVariants = append(productVariants, platformVndkVersion)
Inseob Kime498dd92020-08-04 09:24:04 +0900502 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400503 } else if vendorSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900504 // This will be available in /vendor (or /odm) only
505
506 // kernel_headers is a special module type whose exported headers
507 // are coming from DeviceKernelHeaders() which is always vendor
508 // dependent. They'll always have both vendor variants.
509 // For other modules, we assume that modules under proprietary
510 // paths are compatible for BOARD_VNDK_VERSION. The other modules
511 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400512 if m.KernelHeadersDecorator() {
Inseob Kime498dd92020-08-04 09:24:04 +0900513 vendorVariants = append(vendorVariants,
514 platformVndkVersion,
515 boardVndkVersion,
516 )
Kiyoung Kim48f37782021-07-07 12:42:39 +0900517 } else if snapshot.IsVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900518 vendorVariants = append(vendorVariants, boardVndkVersion)
519 } else {
520 vendorVariants = append(vendorVariants, platformVndkVersion)
521 }
522 } else {
523 // This is either in /system (or similar: /data), or is a
jiajia tangcd1c27b2022-07-21 18:04:37 +0800524 // module built with the NDK. Modules built with the NDK
Inseob Kime498dd92020-08-04 09:24:04 +0900525 // will be restricted using the existing link type checks.
526 coreVariantNeeded = true
527 }
528
Justin Yunaf1fde42023-09-27 16:22:10 +0900529 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
530 // The module has "product_specific: true" that does not create core variant.
531 coreVariantNeeded = false
532 productVariants = append(productVariants, platformVndkVersion)
Inseob Kime498dd92020-08-04 09:24:04 +0900533 }
534
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400535 if m.RamdiskAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900536 ramdiskVariantNeeded = true
537 }
538
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400539 if m.AndroidModuleBase().InstallInRamdisk() {
Inseob Kime498dd92020-08-04 09:24:04 +0900540 ramdiskVariantNeeded = true
541 coreVariantNeeded = false
542 }
543
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400544 if m.VendorRamdiskAvailable() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700545 vendorRamdiskVariantNeeded = true
546 }
547
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400548 if m.AndroidModuleBase().InstallInVendorRamdisk() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700549 vendorRamdiskVariantNeeded = true
550 coreVariantNeeded = false
551 }
552
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400553 if m.RecoveryAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900554 recoveryVariantNeeded = true
555 }
556
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400557 if m.AndroidModuleBase().InstallInRecovery() {
Inseob Kime498dd92020-08-04 09:24:04 +0900558 recoveryVariantNeeded = true
559 coreVariantNeeded = false
560 }
561
Jose Galmes6f843bc2020-12-11 13:36:29 -0800562 // If using a snapshot, the recovery variant under AOSP directories is not needed,
563 // except for kernel headers, which needs all variants.
Jose Galmes737d0a12021-05-25 22:06:41 -0700564 if !m.KernelHeadersDecorator() &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400565 !m.IsSnapshotPrebuilt() &&
Jose Galmes6f843bc2020-12-11 13:36:29 -0800566 usingRecoverySnapshot &&
Kiyoung Kim48f37782021-07-07 12:42:39 +0900567 !snapshot.IsRecoveryProprietaryModule(mctx) {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800568 recoveryVariantNeeded = false
569 }
570
Inseob Kime498dd92020-08-04 09:24:04 +0900571 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400572 m.AppendExtraVariant(VendorVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900573 }
574
575 for _, variant := range android.FirstUniqueStrings(productVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400576 m.AppendExtraVariant(ProductVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900577 }
578
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400579 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
580 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
581 m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
582 m.SetCoreVariantNeeded(coreVariantNeeded)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800583
584 // Disable the module if no variants are needed.
585 if !ramdiskVariantNeeded &&
586 !recoveryVariantNeeded &&
587 !coreVariantNeeded &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400588 len(m.ExtraVariants()) == 0 {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800589 m.Disable()
590 }
Inseob Kime498dd92020-08-04 09:24:04 +0900591}
592
593func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
594 return c.Properties.CoreVariantNeeded
595}
596
597func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
598 return c.Properties.RamdiskVariantNeeded
599}
600
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700601func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
602 return c.Properties.VendorRamdiskVariantNeeded
603}
604
Inseob Kim08758f02021-04-08 21:13:22 +0900605func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
606 return false
607}
608
Inseob Kime498dd92020-08-04 09:24:04 +0900609func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
610 return c.Properties.RecoveryVariantNeeded
611}
612
613func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
Lukacs T. Berki2f5c3402021-06-15 11:27:56 +0200614 return c.Properties.ExtraVersionedImageVariations
Inseob Kime498dd92020-08-04 09:24:04 +0900615}
616
Justin Yun63e9ec72020-10-29 16:49:43 +0900617func squashVendorSrcs(m *Module) {
618 if lib, ok := m.compiler.(*libraryDecorator); ok {
619 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
620 lib.baseCompiler.Properties.Target.Vendor.Srcs...)
621
622 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
623 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
624
625 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
626 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
Jooyung Han85707de2023-12-01 14:21:13 +0900627
628 if lib.Properties.Target.Vendor.No_stubs {
629 proptools.Clear(&lib.Properties.Stubs)
630 }
Justin Yun63e9ec72020-10-29 16:49:43 +0900631 }
632}
633
634func squashProductSrcs(m *Module) {
635 if lib, ok := m.compiler.(*libraryDecorator); ok {
636 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
637 lib.baseCompiler.Properties.Target.Product.Srcs...)
638
639 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
640 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
641
642 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
643 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
Jooyung Han85707de2023-12-01 14:21:13 +0900644
645 if lib.Properties.Target.Product.No_stubs {
646 proptools.Clear(&lib.Properties.Stubs)
647 }
Justin Yun63e9ec72020-10-29 16:49:43 +0900648 }
649}
650
651func squashRecoverySrcs(m *Module) {
652 if lib, ok := m.compiler.(*libraryDecorator); ok {
653 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
654 lib.baseCompiler.Properties.Target.Recovery.Srcs...)
655
656 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
657 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
658
659 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
660 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
661 }
662}
663
664func squashVendorRamdiskSrcs(m *Module) {
665 if lib, ok := m.compiler.(*libraryDecorator); ok {
666 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
667 }
668}
669
Christopher Ferrise0202c42023-07-27 17:06:46 -0700670func squashRamdiskSrcs(m *Module) {
671 if lib, ok := m.compiler.(*libraryDecorator); ok {
672 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Ramdisk.Exclude_srcs...)
673 }
674}
675
Inseob Kime498dd92020-08-04 09:24:04 +0900676func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
677 m := module.(*Module)
Yifan Hong6da33c22020-10-27 15:01:21 -0700678 if variant == android.RamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900679 m.MakeAsPlatform()
Christopher Ferrise0202c42023-07-27 17:06:46 -0700680 squashRamdiskSrcs(m)
Yifan Hong6da33c22020-10-27 15:01:21 -0700681 } else if variant == android.VendorRamdiskVariation {
682 m.MakeAsPlatform()
683 squashVendorRamdiskSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900684 } else if variant == android.RecoveryVariation {
685 m.MakeAsPlatform()
686 squashRecoverySrcs(m)
687 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
688 m.Properties.ImageVariationPrefix = VendorVariationPrefix
689 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
690 squashVendorSrcs(m)
691
692 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
693 // Hide other vendor variants to avoid collision.
694 vndkVersion := ctx.DeviceConfig().VndkVersion()
695 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
696 m.Properties.HideFromMake = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800697 m.HideFromMake()
Inseob Kime498dd92020-08-04 09:24:04 +0900698 }
699 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
700 m.Properties.ImageVariationPrefix = ProductVariationPrefix
701 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
Justin Yun6977e8a2020-10-29 18:24:11 +0900702 squashProductSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900703 }
Colin Cross5271fea2021-04-27 13:06:04 -0700704
705 if c.NeedsVendorPublicLibraryVariants() &&
706 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) {
707 c.VendorProperties.IsVendorPublicLibrary = true
708 }
Inseob Kime498dd92020-08-04 09:24:04 +0900709}