blob: c6b209f083527f1d78b0c2baca5192c9aa33b943 [file] [log] [blame]
Inseob Kime498dd92020-08-04 09:24:04 +09001// Copyright 2020 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package cc
15
16// This file contains image variant related things, including image mutator functions, utility
17// functions to determine where a module is installed, etc.
18
19import (
Justin Yun6977e8a2020-10-29 18:24:11 +090020 "fmt"
21 "reflect"
Inseob Kime498dd92020-08-04 09:24:04 +090022 "strings"
23
24 "android/soong/android"
25)
26
27var _ android.ImageInterface = (*Module)(nil)
28
Ivan Lozano3968d8f2020-12-14 11:27:52 -050029type ImageVariantType string
Inseob Kim74d25562020-08-04 00:41:38 +090030
31const (
Ivan Lozano3968d8f2020-12-14 11:27:52 -050032 coreImageVariant ImageVariantType = "core"
33 vendorImageVariant ImageVariantType = "vendor"
34 productImageVariant ImageVariantType = "product"
35 ramdiskImageVariant ImageVariantType = "ramdisk"
36 vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk"
37 recoveryImageVariant ImageVariantType = "recovery"
38 hostImageVariant ImageVariantType = "host"
Inseob Kim74d25562020-08-04 00:41:38 +090039)
40
Inseob Kime498dd92020-08-04 09:24:04 +090041const (
42 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
43 // against the VNDK.
44 VendorVariationPrefix = "vendor."
45
46 // ProductVariationPrefix is the variant prefix used for /product code that compiles
47 // against the VNDK.
48 ProductVariationPrefix = "product."
49)
50
51func (ctx *moduleContext) ProductSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090052 return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext()
Inseob Kime498dd92020-08-04 09:24:04 +090053}
54
55func (ctx *moduleContext) SocSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090056 return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext()
Justin Yunebcf0c52021-01-08 18:00:19 +090057}
58
59func (ctx *moduleContext) DeviceSpecific() bool {
Justin Yun7f99ec72021-04-12 13:19:28 +090060 return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext()
Inseob Kime498dd92020-08-04 09:24:04 +090061}
62
63func (ctx *moduleContextImpl) inProduct() bool {
Ivan Lozanof9e21722020-12-02 09:00:51 -050064 return ctx.mod.InProduct()
Inseob Kime498dd92020-08-04 09:24:04 +090065}
66
67func (ctx *moduleContextImpl) inVendor() bool {
Ivan Lozano3968d8f2020-12-14 11:27:52 -050068 return ctx.mod.InVendor()
Inseob Kime498dd92020-08-04 09:24:04 +090069}
70
71func (ctx *moduleContextImpl) inRamdisk() bool {
72 return ctx.mod.InRamdisk()
73}
74
Yifan Hong60e0cfb2020-10-21 15:17:56 -070075func (ctx *moduleContextImpl) inVendorRamdisk() bool {
76 return ctx.mod.InVendorRamdisk()
77}
78
Inseob Kime498dd92020-08-04 09:24:04 +090079func (ctx *moduleContextImpl) inRecovery() bool {
80 return ctx.mod.InRecovery()
81}
82
Justin Yun7f99ec72021-04-12 13:19:28 +090083func (c *Module) productSpecificModuleContext() bool {
84 // Additionally check if this module is inProduct() that means it is a "product" variant of a
85 // module. As well as product specific modules, product variants must be installed to /product.
86 return c.InProduct()
87}
88
89func (c *Module) socSpecificModuleContext() bool {
90 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a
91 // module. As well as SoC specific modules, vendor variants must be installed to /vendor
92 // unless they have "odm_available: true".
93 return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm()
94}
95
96func (c *Module) deviceSpecificModuleContext() bool {
97 // Some vendor variants want to be installed to /odm by setting "odm_available: true".
98 return c.InVendor() && c.VendorVariantToOdm()
99}
100
Justin Yun63e9ec72020-10-29 16:49:43 +0900101// Returns true when this module is configured to have core and vendor variants.
Inseob Kime498dd92020-08-04 09:24:04 +0900102func (c *Module) HasVendorVariant() bool {
Justin Yunebcf0c52021-01-08 18:00:19 +0900103 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available)
104}
105
106// Returns true when this module creates a vendor variant and wants to install the vendor variant
107// to the odm partition.
108func (c *Module) VendorVariantToOdm() bool {
109 return Bool(c.VendorProperties.Odm_available)
Inseob Kime498dd92020-08-04 09:24:04 +0900110}
111
Justin Yun63e9ec72020-10-29 16:49:43 +0900112// Returns true when this module is configured to have core and product variants.
113func (c *Module) HasProductVariant() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900114 return Bool(c.VendorProperties.Product_available)
Justin Yun63e9ec72020-10-29 16:49:43 +0900115}
116
117// Returns true when this module is configured to have core and either product or vendor variants.
118func (c *Module) HasNonSystemVariants() bool {
Justin Yun6977e8a2020-10-29 18:24:11 +0900119 return c.HasVendorVariant() || c.HasProductVariant()
Justin Yun63e9ec72020-10-29 16:49:43 +0900120}
121
Inseob Kime498dd92020-08-04 09:24:04 +0900122// Returns true if the module is "product" variant. Usually these modules are installed in /product
Ivan Lozanof9e21722020-12-02 09:00:51 -0500123func (c *Module) InProduct() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900124 return c.Properties.ImageVariationPrefix == ProductVariationPrefix
125}
126
127// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500128func (c *Module) InVendor() bool {
Inseob Kime498dd92020-08-04 09:24:04 +0900129 return c.Properties.ImageVariationPrefix == VendorVariationPrefix
130}
131
132func (c *Module) InRamdisk() bool {
133 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk()
134}
135
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700136func (c *Module) InVendorRamdisk() bool {
137 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk()
138}
139
Inseob Kime498dd92020-08-04 09:24:04 +0900140func (c *Module) InRecovery() bool {
141 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
142}
143
144func (c *Module) OnlyInRamdisk() bool {
145 return c.ModuleBase.InstallInRamdisk()
146}
147
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700148func (c *Module) OnlyInVendorRamdisk() bool {
149 return c.ModuleBase.InstallInVendorRamdisk()
150}
151
Inseob Kime498dd92020-08-04 09:24:04 +0900152func (c *Module) OnlyInRecovery() bool {
153 return c.ModuleBase.InstallInRecovery()
154}
155
Justin Yun6977e8a2020-10-29 18:24:11 +0900156func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
157 if v.Kind() != reflect.Struct {
158 return true
159 }
160 for i := 0; i < v.NumField(); i++ {
161 prop := v.Field(i)
162 if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
163 vendor_prop := prop.FieldByName("Vendor")
164 product_prop := prop.FieldByName("Product")
165 if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
166 // Neither Target.Vendor nor Target.Product is defined
167 continue
168 }
169 if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
170 !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
171 // If only one of either Target.Vendor or Target.Product is
172 // defined or they have different values, it fails the build
173 // since VNDK must have the same properties for both vendor
174 // and product variants.
175 return false
176 }
177 } else if !visitPropsAndCompareVendorAndProductProps(prop) {
178 // Visit the substructures to find Target.Vendor and Target.Product
179 return false
180 }
181 }
182 return true
183}
184
185// In the case of VNDK, vendor and product variants must have the same properties.
186// VNDK installs only one file and shares it for both vendor and product modules on
187// runtime. We may not define different versions of a VNDK lib for each partition.
188// This function is used only for the VNDK modules that is available to both vendor
189// and product partitions.
190func (c *Module) compareVendorAndProductProps() bool {
Justin Yunc0d8c492021-01-07 17:45:31 +0900191 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) {
Justin Yun6977e8a2020-10-29 18:24:11 +0900192 panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
193 }
194 for _, properties := range c.GetProperties() {
195 if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
196 return false
197 }
198 }
199 return true
200}
201
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400202// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules.
203type ImageMutatableModule interface {
204 android.Module
205 LinkableInterface
206
207 // AndroidModuleBase returns the android.ModuleBase for this module
208 AndroidModuleBase() *android.ModuleBase
209
210 // VendorAvailable returns true if this module is available on the vendor image.
211 VendorAvailable() bool
212
213 // OdmAvailable returns true if this module is available on the odm image.
214 OdmAvailable() bool
215
216 // ProductAvailable returns true if this module is available on the product image.
217 ProductAvailable() bool
218
219 // RamdiskAvailable returns true if this module is available on the ramdisk image.
220 RamdiskAvailable() bool
221
222 // RecoveryAvailable returns true if this module is available on the recovery image.
223 RecoveryAvailable() bool
224
225 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image.
226 VendorRamdiskAvailable() bool
227
228 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
229 IsSnapshotPrebuilt() bool
230
231 // SnapshotVersion returns the snapshot version for this module.
232 SnapshotVersion(mctx android.BaseModuleContext) string
233
234 // SdkVersion returns the SDK version for this module.
235 SdkVersion() string
236
237 // ExtraVariants returns the list of extra variants this module requires.
238 ExtraVariants() []string
239
240 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires.
241 AppendExtraVariant(extraVariant string)
242
243 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed.
244 SetRamdiskVariantNeeded(b bool)
245
246 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed.
247 SetVendorRamdiskVariantNeeded(b bool)
248
249 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed.
250 SetRecoveryVariantNeeded(b bool)
251
252 // SetCoreVariantNeeded sets whether the Core Variant is needed.
253 SetCoreVariantNeeded(b bool)
254}
255
256var _ ImageMutatableModule = (*Module)(nil)
257
Inseob Kime498dd92020-08-04 09:24:04 +0900258func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400259 m.CheckVndkProperties(mctx)
260 MutateImage(mctx, m)
261}
262
263// CheckVndkProperties checks whether the VNDK-related properties are set correctly.
264// If properties are not set correctly, results in a module context property error.
265func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) {
Inseob Kime498dd92020-08-04 09:24:04 +0900266 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
267 productSpecific := mctx.ProductSpecific()
268
Inseob Kime498dd92020-08-04 09:24:04 +0900269 if vndkdep := m.vndkdep; vndkdep != nil {
270 if vndkdep.isVndk() {
271 if vendorSpecific || productSpecific {
272 if !vndkdep.isVndkExt() {
273 mctx.PropertyErrorf("vndk",
274 "must set `extends: \"...\"` to vndk extension")
Justin Yunc0d8c492021-01-07 17:45:31 +0900275 } else if Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900276 mctx.PropertyErrorf("vendor_available",
277 "must not set at the same time as `vndk: {extends: \"...\"}`")
Justin Yunc0d8c492021-01-07 17:45:31 +0900278 } else if Bool(m.VendorProperties.Product_available) {
Justin Yun63e9ec72020-10-29 16:49:43 +0900279 mctx.PropertyErrorf("product_available",
280 "must not set at the same time as `vndk: {extends: \"...\"}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900281 }
282 } else {
283 if vndkdep.isVndkExt() {
284 mctx.PropertyErrorf("vndk",
285 "must set `vendor: true` or `product_specific: true` to set `extends: %q`",
286 m.getVndkExtendsModuleName())
287 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900288 if !Bool(m.VendorProperties.Vendor_available) {
Inseob Kime498dd92020-08-04 09:24:04 +0900289 mctx.PropertyErrorf("vndk",
Justin Yunc0d8c492021-01-07 17:45:31 +0900290 "vendor_available must be set to true when `vndk: {enabled: true}`")
Inseob Kime498dd92020-08-04 09:24:04 +0900291 }
Justin Yunc0d8c492021-01-07 17:45:31 +0900292 if Bool(m.VendorProperties.Product_available) {
Justin Yunfd9e8042020-12-23 18:23:14 +0900293 // If a VNDK module creates both product and vendor variants, they
294 // must have the same properties since they share a single VNDK
295 // library on runtime.
Justin Yun6977e8a2020-10-29 18:24:11 +0900296 if !m.compareVendorAndProductProps() {
297 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
298 }
299 }
Inseob Kime498dd92020-08-04 09:24:04 +0900300 }
301 } else {
302 if vndkdep.isVndkSp() {
303 mctx.PropertyErrorf("vndk",
304 "must set `enabled: true` to set `support_system_process: true`")
305 }
306 if vndkdep.isVndkExt() {
307 mctx.PropertyErrorf("vndk",
308 "must set `enabled: true` to set `extends: %q`",
309 m.getVndkExtendsModuleName())
310 }
311 }
312 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400313}
314
315func (m *Module) VendorAvailable() bool {
316 return Bool(m.VendorProperties.Vendor_available)
317}
318
319func (m *Module) OdmAvailable() bool {
320 return Bool(m.VendorProperties.Odm_available)
321}
322
323func (m *Module) ProductAvailable() bool {
324 return Bool(m.VendorProperties.Product_available)
325}
326
327func (m *Module) RamdiskAvailable() bool {
328 return Bool(m.Properties.Ramdisk_available)
329}
330
331func (m *Module) VendorRamdiskAvailable() bool {
332 return Bool(m.Properties.Vendor_ramdisk_available)
333}
334
335func (m *Module) AndroidModuleBase() *android.ModuleBase {
336 return &m.ModuleBase
337}
338
339func (m *Module) RecoveryAvailable() bool {
340 return Bool(m.Properties.Recovery_available)
341}
342
343func (m *Module) ExtraVariants() []string {
344 return m.Properties.ExtraVariants
345}
346
347func (m *Module) AppendExtraVariant(extraVariant string) {
348 m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, extraVariant)
349}
350
351func (m *Module) SetRamdiskVariantNeeded(b bool) {
352 m.Properties.RamdiskVariantNeeded = b
353}
354
355func (m *Module) SetVendorRamdiskVariantNeeded(b bool) {
356 m.Properties.VendorRamdiskVariantNeeded = b
357}
358
359func (m *Module) SetRecoveryVariantNeeded(b bool) {
360 m.Properties.RecoveryVariantNeeded = b
361}
362
363func (m *Module) SetCoreVariantNeeded(b bool) {
364 m.Properties.CoreVariantNeeded = b
365}
366
367func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
368 if snapshot, ok := m.linker.(snapshotInterface); ok {
369 return snapshot.version()
370 } else {
371 mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
372 // Should we be panicking here instead?
373 return ""
374 }
375}
376
377func (m *Module) KernelHeadersDecorator() bool {
378 if _, ok := m.linker.(*kernelHeadersDecorator); ok {
379 return true
380 }
381 return false
382}
383
384// MutateImage handles common image mutations for ImageMutatableModule interfaces.
385func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
386 // Validation check
387 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
388 productSpecific := mctx.ProductSpecific()
389
390 if m.VendorAvailable() {
391 if vendorSpecific {
392 mctx.PropertyErrorf("vendor_available",
393 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
394 }
395 if m.OdmAvailable() {
396 mctx.PropertyErrorf("vendor_available",
397 "doesn't make sense at the same time as `odm_available: true`")
398 }
399 }
400
401 if m.OdmAvailable() {
402 if vendorSpecific {
403 mctx.PropertyErrorf("odm_available",
404 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`")
405 }
406 }
407
408 if m.ProductAvailable() {
409 if productSpecific {
410 mctx.PropertyErrorf("product_available",
411 "doesn't make sense at the same time as `product_specific: true`")
412 }
413 if vendorSpecific {
414 mctx.PropertyErrorf("product_available",
415 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`")
416 }
417 }
Inseob Kime498dd92020-08-04 09:24:04 +0900418
419 var coreVariantNeeded bool = false
420 var ramdiskVariantNeeded bool = false
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700421 var vendorRamdiskVariantNeeded bool = false
Inseob Kime498dd92020-08-04 09:24:04 +0900422 var recoveryVariantNeeded bool = false
423
424 var vendorVariants []string
425 var productVariants []string
426
427 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
428 boardVndkVersion := mctx.DeviceConfig().VndkVersion()
429 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
Jose Galmes6f843bc2020-12-11 13:36:29 -0800430 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
431 usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
432 recoverySnapshotVersion != ""
Justin Yundee806f2021-05-18 23:10:00 +0900433 needVndkVersionVendorVariantForLlndk := false
434 if boardVndkVersion != "" {
435 boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion)
436 if err == nil && !boardVndkApiLevel.IsPreview() {
437 // VNDK snapshot newer than v30 has LLNDK stub libraries.
438 // Only the VNDK version less than or equal to v30 requires generating the vendor
439 // variant of the VNDK version from the source tree.
440 needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30"))
441 }
442 }
Inseob Kime498dd92020-08-04 09:24:04 +0900443 if boardVndkVersion == "current" {
444 boardVndkVersion = platformVndkVersion
445 }
446 if productVndkVersion == "current" {
447 productVndkVersion = platformVndkVersion
448 }
449
Colin Cross203b4212021-04-26 17:19:41 -0700450 if m.NeedsLlndkVariants() {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800451 // This is an LLNDK library. The implementation of the library will be on /system,
452 // and vendor and product variants will be created with LLNDK stubs.
453 // The LLNDK libraries need vendor variants even if there is no VNDK.
Colin Cross203b4212021-04-26 17:19:41 -0700454 coreVariantNeeded = true
Colin Crossb5f6fa62021-01-06 17:05:04 -0800455 if platformVndkVersion != "" {
456 vendorVariants = append(vendorVariants, platformVndkVersion)
457 productVariants = append(productVariants, platformVndkVersion)
458 }
Justin Yundee806f2021-05-18 23:10:00 +0900459 // Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not
460 // provide the LLNDK stub libraries.
461 if needVndkVersionVendorVariantForLlndk {
Colin Crossb5f6fa62021-01-06 17:05:04 -0800462 vendorVariants = append(vendorVariants, boardVndkVersion)
463 }
464 if productVndkVersion != "" {
465 productVariants = append(productVariants, productVndkVersion)
466 }
Colin Cross5271fea2021-04-27 13:06:04 -0700467 } else if m.NeedsVendorPublicLibraryVariants() {
468 // A vendor public library has the implementation on /vendor, with stub variants
469 // for system and product.
470 coreVariantNeeded = true
471 vendorVariants = append(vendorVariants, boardVndkVersion)
472 if platformVndkVersion != "" {
473 productVariants = append(productVariants, platformVndkVersion)
474 }
475 if productVndkVersion != "" {
476 productVariants = append(productVariants, productVndkVersion)
477 }
Colin Crossb5f6fa62021-01-06 17:05:04 -0800478 } else if boardVndkVersion == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900479 // If the device isn't compiling against the VNDK, we always
480 // use the core mode.
481 coreVariantNeeded = true
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400482 } else if m.IsSnapshotPrebuilt() {
Inseob Kime498dd92020-08-04 09:24:04 +0900483 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and
484 // PRODUCT_EXTRA_VNDK_VERSIONS.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400485 if m.InstallInRecovery() {
486 recoveryVariantNeeded = true
Inseob Kime498dd92020-08-04 09:24:04 +0900487 } else {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400488 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx))
Inseob Kime498dd92020-08-04 09:24:04 +0900489 }
Ivan Lozanof9e21722020-12-02 09:00:51 -0500490 } else if m.HasNonSystemVariants() && !m.IsVndkExt() {
Justin Yun63e9ec72020-10-29 16:49:43 +0900491 // This will be available to /system unless it is product_specific
492 // which will be handled later.
Inseob Kime498dd92020-08-04 09:24:04 +0900493 coreVariantNeeded = true
494
495 // We assume that modules under proprietary paths are compatible for
496 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or
497 // PLATFORM_VNDK_VERSION.
Justin Yun63e9ec72020-10-29 16:49:43 +0900498 if m.HasVendorVariant() {
499 if isVendorProprietaryModule(mctx) {
500 vendorVariants = append(vendorVariants, boardVndkVersion)
501 } else {
502 vendorVariants = append(vendorVariants, platformVndkVersion)
503 }
Inseob Kime498dd92020-08-04 09:24:04 +0900504 }
505
Justin Yun6977e8a2020-10-29 18:24:11 +0900506 // product_available modules are available to /product.
507 if m.HasProductVariant() {
508 productVariants = append(productVariants, platformVndkVersion)
509 // VNDK is always PLATFORM_VNDK_VERSION
510 if !m.IsVndk() {
511 productVariants = append(productVariants, productVndkVersion)
512 }
Inseob Kime498dd92020-08-04 09:24:04 +0900513 }
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400514 } else if vendorSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900515 // This will be available in /vendor (or /odm) only
516
517 // kernel_headers is a special module type whose exported headers
518 // are coming from DeviceKernelHeaders() which is always vendor
519 // dependent. They'll always have both vendor variants.
520 // For other modules, we assume that modules under proprietary
521 // paths are compatible for BOARD_VNDK_VERSION. The other modules
522 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION.
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400523 if m.KernelHeadersDecorator() {
Inseob Kime498dd92020-08-04 09:24:04 +0900524 vendorVariants = append(vendorVariants,
525 platformVndkVersion,
526 boardVndkVersion,
527 )
Bill Peckham945441c2020-08-31 16:07:58 -0700528 } else if isVendorProprietaryModule(mctx) {
Inseob Kime498dd92020-08-04 09:24:04 +0900529 vendorVariants = append(vendorVariants, boardVndkVersion)
530 } else {
531 vendorVariants = append(vendorVariants, platformVndkVersion)
532 }
533 } else {
534 // This is either in /system (or similar: /data), or is a
535 // modules built with the NDK. Modules built with the NDK
536 // will be restricted using the existing link type checks.
537 coreVariantNeeded = true
538 }
539
540 if boardVndkVersion != "" && productVndkVersion != "" {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400541 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
Inseob Kime498dd92020-08-04 09:24:04 +0900542 // The module has "product_specific: true" that does not create core variant.
543 coreVariantNeeded = false
544 productVariants = append(productVariants, productVndkVersion)
545 }
546 } else {
547 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
548 // restriction to use system libs.
549 // No product variants defined in this case.
550 productVariants = []string{}
551 }
552
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400553 if m.RamdiskAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900554 ramdiskVariantNeeded = true
555 }
556
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400557 if m.AndroidModuleBase().InstallInRamdisk() {
Inseob Kime498dd92020-08-04 09:24:04 +0900558 ramdiskVariantNeeded = true
559 coreVariantNeeded = false
560 }
561
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400562 if m.VendorRamdiskAvailable() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700563 vendorRamdiskVariantNeeded = true
564 }
565
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400566 if m.AndroidModuleBase().InstallInVendorRamdisk() {
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700567 vendorRamdiskVariantNeeded = true
568 coreVariantNeeded = false
569 }
570
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400571 if m.RecoveryAvailable() {
Inseob Kime498dd92020-08-04 09:24:04 +0900572 recoveryVariantNeeded = true
573 }
574
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400575 if m.AndroidModuleBase().InstallInRecovery() {
Inseob Kime498dd92020-08-04 09:24:04 +0900576 recoveryVariantNeeded = true
577 coreVariantNeeded = false
578 }
579
Jose Galmes6f843bc2020-12-11 13:36:29 -0800580 // If using a snapshot, the recovery variant under AOSP directories is not needed,
581 // except for kernel headers, which needs all variants.
Jose Galmes737d0a12021-05-25 22:06:41 -0700582 if !m.KernelHeadersDecorator() &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400583 !m.IsSnapshotPrebuilt() &&
Jose Galmes6f843bc2020-12-11 13:36:29 -0800584 usingRecoverySnapshot &&
585 !isRecoveryProprietaryModule(mctx) {
586 recoveryVariantNeeded = false
587 }
588
Inseob Kime498dd92020-08-04 09:24:04 +0900589 for _, variant := range android.FirstUniqueStrings(vendorVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400590 m.AppendExtraVariant(VendorVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900591 }
592
593 for _, variant := range android.FirstUniqueStrings(productVariants) {
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400594 m.AppendExtraVariant(ProductVariationPrefix + variant)
Inseob Kime498dd92020-08-04 09:24:04 +0900595 }
596
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400597 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded)
598 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded)
599 m.SetRecoveryVariantNeeded(recoveryVariantNeeded)
600 m.SetCoreVariantNeeded(coreVariantNeeded)
Jose Galmes6f843bc2020-12-11 13:36:29 -0800601
602 // Disable the module if no variants are needed.
603 if !ramdiskVariantNeeded &&
604 !recoveryVariantNeeded &&
605 !coreVariantNeeded &&
Ivan Lozano3a7d0002021-03-30 12:19:36 -0400606 len(m.ExtraVariants()) == 0 {
Jose Galmes6f843bc2020-12-11 13:36:29 -0800607 m.Disable()
608 }
Inseob Kime498dd92020-08-04 09:24:04 +0900609}
610
611func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
612 return c.Properties.CoreVariantNeeded
613}
614
615func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
616 return c.Properties.RamdiskVariantNeeded
617}
618
Yifan Hong60e0cfb2020-10-21 15:17:56 -0700619func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
620 return c.Properties.VendorRamdiskVariantNeeded
621}
622
Inseob Kim08758f02021-04-08 21:13:22 +0900623func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
624 return false
625}
626
Inseob Kime498dd92020-08-04 09:24:04 +0900627func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
628 return c.Properties.RecoveryVariantNeeded
629}
630
631func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
632 return c.Properties.ExtraVariants
633}
634
Justin Yun63e9ec72020-10-29 16:49:43 +0900635func squashVendorSrcs(m *Module) {
636 if lib, ok := m.compiler.(*libraryDecorator); ok {
637 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
638 lib.baseCompiler.Properties.Target.Vendor.Srcs...)
639
640 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
641 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...)
642
643 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
644 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...)
645 }
646}
647
648func squashProductSrcs(m *Module) {
649 if lib, ok := m.compiler.(*libraryDecorator); ok {
650 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
651 lib.baseCompiler.Properties.Target.Product.Srcs...)
652
653 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
654 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...)
655
656 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
657 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...)
658 }
659}
660
661func squashRecoverySrcs(m *Module) {
662 if lib, ok := m.compiler.(*libraryDecorator); ok {
663 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
664 lib.baseCompiler.Properties.Target.Recovery.Srcs...)
665
666 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs,
667 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...)
668
669 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources,
670 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...)
671 }
672}
673
674func squashVendorRamdiskSrcs(m *Module) {
675 if lib, ok := m.compiler.(*libraryDecorator); ok {
676 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
677 }
678}
679
Inseob Kime498dd92020-08-04 09:24:04 +0900680func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
681 m := module.(*Module)
Yifan Hong6da33c22020-10-27 15:01:21 -0700682 if variant == android.RamdiskVariation {
Inseob Kime498dd92020-08-04 09:24:04 +0900683 m.MakeAsPlatform()
Yifan Hong6da33c22020-10-27 15:01:21 -0700684 } else if variant == android.VendorRamdiskVariation {
685 m.MakeAsPlatform()
686 squashVendorRamdiskSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900687 } else if variant == android.RecoveryVariation {
688 m.MakeAsPlatform()
689 squashRecoverySrcs(m)
690 } else if strings.HasPrefix(variant, VendorVariationPrefix) {
691 m.Properties.ImageVariationPrefix = VendorVariationPrefix
692 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
693 squashVendorSrcs(m)
694
695 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
696 // Hide other vendor variants to avoid collision.
697 vndkVersion := ctx.DeviceConfig().VndkVersion()
698 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
699 m.Properties.HideFromMake = true
Colin Crossa9c8c9f2020-12-16 10:20:23 -0800700 m.HideFromMake()
Inseob Kime498dd92020-08-04 09:24:04 +0900701 }
702 } else if strings.HasPrefix(variant, ProductVariationPrefix) {
703 m.Properties.ImageVariationPrefix = ProductVariationPrefix
704 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
Justin Yun6977e8a2020-10-29 18:24:11 +0900705 squashProductSrcs(m)
Inseob Kime498dd92020-08-04 09:24:04 +0900706 }
Colin Cross5271fea2021-04-27 13:06:04 -0700707
708 if c.NeedsVendorPublicLibraryVariants() &&
709 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) {
710 c.VendorProperties.IsVendorPublicLibrary = true
711 }
Inseob Kime498dd92020-08-04 09:24:04 +0900712}