| // Copyright 2020 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package cc |
| |
| // This file contains image variant related things, including image mutator functions, utility |
| // functions to determine where a module is installed, etc. |
| |
| import ( |
| "fmt" |
| "reflect" |
| "strings" |
| |
| "android/soong/android" |
| "android/soong/snapshot" |
| ) |
| |
| var _ android.ImageInterface = (*Module)(nil) |
| |
| type ImageVariantType string |
| |
| const ( |
| coreImageVariant ImageVariantType = "core" |
| vendorImageVariant ImageVariantType = "vendor" |
| productImageVariant ImageVariantType = "product" |
| ramdiskImageVariant ImageVariantType = "ramdisk" |
| vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk" |
| recoveryImageVariant ImageVariantType = "recovery" |
| hostImageVariant ImageVariantType = "host" |
| ) |
| |
| const ( |
| // VendorVariationPrefix is the variant prefix used for /vendor code that compiles |
| // against the VNDK. |
| VendorVariationPrefix = "vendor." |
| |
| // ProductVariationPrefix is the variant prefix used for /product code that compiles |
| // against the VNDK. |
| ProductVariationPrefix = "product." |
| ) |
| |
| func (ctx *moduleContext) ProductSpecific() bool { |
| return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext() |
| } |
| |
| func (ctx *moduleContext) SocSpecific() bool { |
| return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext() |
| } |
| |
| func (ctx *moduleContext) DeviceSpecific() bool { |
| return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext() |
| } |
| |
| func (ctx *moduleContextImpl) inProduct() bool { |
| return ctx.mod.InProduct() |
| } |
| |
| func (ctx *moduleContextImpl) inVendor() bool { |
| return ctx.mod.InVendor() |
| } |
| |
| func (ctx *moduleContextImpl) inRamdisk() bool { |
| return ctx.mod.InRamdisk() |
| } |
| |
| func (ctx *moduleContextImpl) inVendorRamdisk() bool { |
| return ctx.mod.InVendorRamdisk() |
| } |
| |
| func (ctx *moduleContextImpl) inRecovery() bool { |
| return ctx.mod.InRecovery() |
| } |
| |
| func (c *Module) productSpecificModuleContext() bool { |
| // Additionally check if this module is inProduct() that means it is a "product" variant of a |
| // module. As well as product specific modules, product variants must be installed to /product. |
| return c.InProduct() |
| } |
| |
| func (c *Module) socSpecificModuleContext() bool { |
| // Additionally check if this module is inVendor() that means it is a "vendor" variant of a |
| // module. As well as SoC specific modules, vendor variants must be installed to /vendor |
| // unless they have "odm_available: true". |
| return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm() |
| } |
| |
| func (c *Module) deviceSpecificModuleContext() bool { |
| // Some vendor variants want to be installed to /odm by setting "odm_available: true". |
| return c.InVendor() && c.VendorVariantToOdm() |
| } |
| |
| // Returns true when this module is configured to have core and vendor variants. |
| func (c *Module) HasVendorVariant() bool { |
| return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available) |
| } |
| |
| // Returns true when this module creates a vendor variant and wants to install the vendor variant |
| // to the odm partition. |
| func (c *Module) VendorVariantToOdm() bool { |
| return Bool(c.VendorProperties.Odm_available) |
| } |
| |
| // Returns true when this module is configured to have core and product variants. |
| func (c *Module) HasProductVariant() bool { |
| return Bool(c.VendorProperties.Product_available) |
| } |
| |
| // Returns true when this module is configured to have core and either product or vendor variants. |
| func (c *Module) HasNonSystemVariants() bool { |
| return c.HasVendorVariant() || c.HasProductVariant() |
| } |
| |
| // Returns true if the module is "product" variant. Usually these modules are installed in /product |
| func (c *Module) InProduct() bool { |
| return c.Properties.ImageVariationPrefix == ProductVariationPrefix |
| } |
| |
| // Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor |
| func (c *Module) InVendor() bool { |
| return c.Properties.ImageVariationPrefix == VendorVariationPrefix |
| } |
| |
| func (c *Module) InRamdisk() bool { |
| return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk() |
| } |
| |
| func (c *Module) InVendorRamdisk() bool { |
| return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk() |
| } |
| |
| func (c *Module) InRecovery() bool { |
| return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery() |
| } |
| |
| func (c *Module) OnlyInRamdisk() bool { |
| return c.ModuleBase.InstallInRamdisk() |
| } |
| |
| func (c *Module) OnlyInVendorRamdisk() bool { |
| return c.ModuleBase.InstallInVendorRamdisk() |
| } |
| |
| func (c *Module) OnlyInRecovery() bool { |
| return c.ModuleBase.InstallInRecovery() |
| } |
| |
| func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool { |
| if v.Kind() != reflect.Struct { |
| return true |
| } |
| for i := 0; i < v.NumField(); i++ { |
| prop := v.Field(i) |
| if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" { |
| vendor_prop := prop.FieldByName("Vendor") |
| product_prop := prop.FieldByName("Product") |
| if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct { |
| // Neither Target.Vendor nor Target.Product is defined |
| continue |
| } |
| if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct || |
| !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) { |
| // If only one of either Target.Vendor or Target.Product is |
| // defined or they have different values, it fails the build |
| // since VNDK must have the same properties for both vendor |
| // and product variants. |
| return false |
| } |
| } else if !visitPropsAndCompareVendorAndProductProps(prop) { |
| // Visit the substructures to find Target.Vendor and Target.Product |
| return false |
| } |
| } |
| return true |
| } |
| |
| // In the case of VNDK, vendor and product variants must have the same properties. |
| // VNDK installs only one file and shares it for both vendor and product modules on |
| // runtime. We may not define different versions of a VNDK lib for each partition. |
| // This function is used only for the VNDK modules that is available to both vendor |
| // and product partitions. |
| func (c *Module) compareVendorAndProductProps() bool { |
| if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) { |
| panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name())) |
| } |
| for _, properties := range c.GetProperties() { |
| if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) { |
| return false |
| } |
| } |
| return true |
| } |
| |
| // ImageMutatableModule provides a common image mutation interface for LinkableInterface modules. |
| type ImageMutatableModule interface { |
| android.Module |
| LinkableInterface |
| |
| // AndroidModuleBase returns the android.ModuleBase for this module |
| AndroidModuleBase() *android.ModuleBase |
| |
| // VendorAvailable returns true if this module is available on the vendor image. |
| VendorAvailable() bool |
| |
| // OdmAvailable returns true if this module is available on the odm image. |
| OdmAvailable() bool |
| |
| // ProductAvailable returns true if this module is available on the product image. |
| ProductAvailable() bool |
| |
| // RamdiskAvailable returns true if this module is available on the ramdisk image. |
| RamdiskAvailable() bool |
| |
| // RecoveryAvailable returns true if this module is available on the recovery image. |
| RecoveryAvailable() bool |
| |
| // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image. |
| VendorRamdiskAvailable() bool |
| |
| // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt. |
| IsSnapshotPrebuilt() bool |
| |
| // SnapshotVersion returns the snapshot version for this module. |
| SnapshotVersion(mctx android.BaseModuleContext) string |
| |
| // SdkVersion returns the SDK version for this module. |
| SdkVersion() string |
| |
| // ExtraVariants returns the list of extra variants this module requires. |
| ExtraVariants() []string |
| |
| // AppendExtraVariant returns an extra variant to the list of extra variants this module requires. |
| AppendExtraVariant(extraVariant string) |
| |
| // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed. |
| SetRamdiskVariantNeeded(b bool) |
| |
| // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed. |
| SetVendorRamdiskVariantNeeded(b bool) |
| |
| // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed. |
| SetRecoveryVariantNeeded(b bool) |
| |
| // SetCoreVariantNeeded sets whether the Core Variant is needed. |
| SetCoreVariantNeeded(b bool) |
| } |
| |
| var _ ImageMutatableModule = (*Module)(nil) |
| |
| func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { |
| m.CheckVndkProperties(mctx) |
| MutateImage(mctx, m) |
| } |
| |
| // CheckVndkProperties checks whether the VNDK-related properties are set correctly. |
| // If properties are not set correctly, results in a module context property error. |
| func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) { |
| vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() |
| productSpecific := mctx.ProductSpecific() |
| |
| if vndkdep := m.vndkdep; vndkdep != nil { |
| if vndkdep.isVndk() { |
| if vendorSpecific || productSpecific { |
| if !vndkdep.isVndkExt() { |
| mctx.PropertyErrorf("vndk", |
| "must set `extends: \"...\"` to vndk extension") |
| } else if Bool(m.VendorProperties.Vendor_available) { |
| mctx.PropertyErrorf("vendor_available", |
| "must not set at the same time as `vndk: {extends: \"...\"}`") |
| } else if Bool(m.VendorProperties.Product_available) { |
| mctx.PropertyErrorf("product_available", |
| "must not set at the same time as `vndk: {extends: \"...\"}`") |
| } |
| } else { |
| if vndkdep.isVndkExt() { |
| mctx.PropertyErrorf("vndk", |
| "must set `vendor: true` or `product_specific: true` to set `extends: %q`", |
| m.getVndkExtendsModuleName()) |
| } |
| if !Bool(m.VendorProperties.Vendor_available) { |
| mctx.PropertyErrorf("vndk", |
| "vendor_available must be set to true when `vndk: {enabled: true}`") |
| } |
| if Bool(m.VendorProperties.Product_available) { |
| // If a VNDK module creates both product and vendor variants, they |
| // must have the same properties since they share a single VNDK |
| // library on runtime. |
| if !m.compareVendorAndProductProps() { |
| mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules") |
| } |
| } |
| } |
| } else { |
| if vndkdep.isVndkSp() { |
| mctx.PropertyErrorf("vndk", |
| "must set `enabled: true` to set `support_system_process: true`") |
| } |
| if vndkdep.isVndkExt() { |
| mctx.PropertyErrorf("vndk", |
| "must set `enabled: true` to set `extends: %q`", |
| m.getVndkExtendsModuleName()) |
| } |
| } |
| } |
| } |
| |
| func (m *Module) VendorAvailable() bool { |
| return Bool(m.VendorProperties.Vendor_available) |
| } |
| |
| func (m *Module) OdmAvailable() bool { |
| return Bool(m.VendorProperties.Odm_available) |
| } |
| |
| func (m *Module) ProductAvailable() bool { |
| return Bool(m.VendorProperties.Product_available) |
| } |
| |
| func (m *Module) RamdiskAvailable() bool { |
| return Bool(m.Properties.Ramdisk_available) |
| } |
| |
| func (m *Module) VendorRamdiskAvailable() bool { |
| return Bool(m.Properties.Vendor_ramdisk_available) |
| } |
| |
| func (m *Module) AndroidModuleBase() *android.ModuleBase { |
| return &m.ModuleBase |
| } |
| |
| func (m *Module) RecoveryAvailable() bool { |
| return Bool(m.Properties.Recovery_available) |
| } |
| |
| func (m *Module) ExtraVariants() []string { |
| return m.Properties.ExtraVersionedImageVariations |
| } |
| |
| func (m *Module) AppendExtraVariant(extraVariant string) { |
| m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant) |
| } |
| |
| func (m *Module) SetRamdiskVariantNeeded(b bool) { |
| m.Properties.RamdiskVariantNeeded = b |
| } |
| |
| func (m *Module) SetVendorRamdiskVariantNeeded(b bool) { |
| m.Properties.VendorRamdiskVariantNeeded = b |
| } |
| |
| func (m *Module) SetRecoveryVariantNeeded(b bool) { |
| m.Properties.RecoveryVariantNeeded = b |
| } |
| |
| func (m *Module) SetCoreVariantNeeded(b bool) { |
| m.Properties.CoreVariantNeeded = b |
| } |
| |
| func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string { |
| if snapshot, ok := m.linker.(SnapshotInterface); ok { |
| return snapshot.Version() |
| } else { |
| mctx.ModuleErrorf("version is unknown for snapshot prebuilt") |
| // Should we be panicking here instead? |
| return "" |
| } |
| } |
| |
| func (m *Module) KernelHeadersDecorator() bool { |
| if _, ok := m.linker.(*kernelHeadersDecorator); ok { |
| return true |
| } |
| return false |
| } |
| |
| // MutateImage handles common image mutations for ImageMutatableModule interfaces. |
| func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) { |
| // Validation check |
| vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() |
| productSpecific := mctx.ProductSpecific() |
| |
| if m.VendorAvailable() { |
| if vendorSpecific { |
| mctx.PropertyErrorf("vendor_available", |
| "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`") |
| } |
| if m.OdmAvailable() { |
| mctx.PropertyErrorf("vendor_available", |
| "doesn't make sense at the same time as `odm_available: true`") |
| } |
| } |
| |
| if m.OdmAvailable() { |
| if vendorSpecific { |
| mctx.PropertyErrorf("odm_available", |
| "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`") |
| } |
| } |
| |
| if m.ProductAvailable() { |
| if productSpecific { |
| mctx.PropertyErrorf("product_available", |
| "doesn't make sense at the same time as `product_specific: true`") |
| } |
| if vendorSpecific { |
| mctx.PropertyErrorf("product_available", |
| "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`") |
| } |
| } |
| |
| var coreVariantNeeded bool = false |
| var ramdiskVariantNeeded bool = false |
| var vendorRamdiskVariantNeeded bool = false |
| var recoveryVariantNeeded bool = false |
| |
| var vendorVariants []string |
| var productVariants []string |
| |
| platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion() |
| boardVndkVersion := mctx.DeviceConfig().VndkVersion() |
| productVndkVersion := mctx.DeviceConfig().ProductVndkVersion() |
| recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion() |
| usingRecoverySnapshot := recoverySnapshotVersion != "current" && |
| recoverySnapshotVersion != "" |
| needVndkVersionVendorVariantForLlndk := false |
| if boardVndkVersion != "" { |
| boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion) |
| if err == nil && !boardVndkApiLevel.IsPreview() { |
| // VNDK snapshot newer than v30 has LLNDK stub libraries. |
| // Only the VNDK version less than or equal to v30 requires generating the vendor |
| // variant of the VNDK version from the source tree. |
| needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30")) |
| } |
| } |
| if boardVndkVersion == "current" { |
| boardVndkVersion = platformVndkVersion |
| } |
| if productVndkVersion == "current" { |
| productVndkVersion = platformVndkVersion |
| } |
| |
| if m.NeedsLlndkVariants() { |
| // This is an LLNDK library. The implementation of the library will be on /system, |
| // and vendor and product variants will be created with LLNDK stubs. |
| // The LLNDK libraries need vendor variants even if there is no VNDK. |
| coreVariantNeeded = true |
| if platformVndkVersion != "" { |
| vendorVariants = append(vendorVariants, platformVndkVersion) |
| productVariants = append(productVariants, platformVndkVersion) |
| } |
| // Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not |
| // provide the LLNDK stub libraries. |
| if needVndkVersionVendorVariantForLlndk { |
| vendorVariants = append(vendorVariants, boardVndkVersion) |
| } |
| if productVndkVersion != "" { |
| productVariants = append(productVariants, productVndkVersion) |
| } |
| } else if m.NeedsVendorPublicLibraryVariants() { |
| // A vendor public library has the implementation on /vendor, with stub variants |
| // for system and product. |
| coreVariantNeeded = true |
| vendorVariants = append(vendorVariants, boardVndkVersion) |
| if platformVndkVersion != "" { |
| productVariants = append(productVariants, platformVndkVersion) |
| } |
| if productVndkVersion != "" { |
| productVariants = append(productVariants, productVndkVersion) |
| } |
| } else if boardVndkVersion == "" { |
| // If the device isn't compiling against the VNDK, we always |
| // use the core mode. |
| coreVariantNeeded = true |
| } else if m.IsSnapshotPrebuilt() { |
| // Make vendor variants only for the versions in BOARD_VNDK_VERSION and |
| // PRODUCT_EXTRA_VNDK_VERSIONS. |
| if m.InstallInRecovery() { |
| recoveryVariantNeeded = true |
| } else { |
| vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx)) |
| } |
| } else if m.HasNonSystemVariants() && !m.IsVndkExt() { |
| // This will be available to /system unless it is product_specific |
| // which will be handled later. |
| coreVariantNeeded = true |
| |
| // We assume that modules under proprietary paths are compatible for |
| // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or |
| // PLATFORM_VNDK_VERSION. |
| if m.HasVendorVariant() { |
| if snapshot.IsVendorProprietaryModule(mctx) { |
| vendorVariants = append(vendorVariants, boardVndkVersion) |
| } else { |
| vendorVariants = append(vendorVariants, platformVndkVersion) |
| } |
| } |
| |
| // product_available modules are available to /product. |
| if m.HasProductVariant() { |
| productVariants = append(productVariants, platformVndkVersion) |
| // VNDK is always PLATFORM_VNDK_VERSION |
| if !m.IsVndk() { |
| productVariants = append(productVariants, productVndkVersion) |
| } |
| } |
| } else if vendorSpecific && m.SdkVersion() == "" { |
| // This will be available in /vendor (or /odm) only |
| |
| // kernel_headers is a special module type whose exported headers |
| // are coming from DeviceKernelHeaders() which is always vendor |
| // dependent. They'll always have both vendor variants. |
| // For other modules, we assume that modules under proprietary |
| // paths are compatible for BOARD_VNDK_VERSION. The other modules |
| // are regarded as AOSP, which is PLATFORM_VNDK_VERSION. |
| if m.KernelHeadersDecorator() { |
| vendorVariants = append(vendorVariants, |
| platformVndkVersion, |
| boardVndkVersion, |
| ) |
| } else if snapshot.IsVendorProprietaryModule(mctx) { |
| vendorVariants = append(vendorVariants, boardVndkVersion) |
| } else { |
| vendorVariants = append(vendorVariants, platformVndkVersion) |
| } |
| } else { |
| // This is either in /system (or similar: /data), or is a |
| // modules built with the NDK. Modules built with the NDK |
| // will be restricted using the existing link type checks. |
| coreVariantNeeded = true |
| } |
| |
| if boardVndkVersion != "" && productVndkVersion != "" { |
| if coreVariantNeeded && productSpecific && m.SdkVersion() == "" { |
| // The module has "product_specific: true" that does not create core variant. |
| coreVariantNeeded = false |
| productVariants = append(productVariants, productVndkVersion) |
| } |
| } else { |
| // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no |
| // restriction to use system libs. |
| // No product variants defined in this case. |
| productVariants = []string{} |
| } |
| |
| if m.RamdiskAvailable() { |
| ramdiskVariantNeeded = true |
| } |
| |
| if m.AndroidModuleBase().InstallInRamdisk() { |
| ramdiskVariantNeeded = true |
| coreVariantNeeded = false |
| } |
| |
| if m.VendorRamdiskAvailable() { |
| vendorRamdiskVariantNeeded = true |
| } |
| |
| if m.AndroidModuleBase().InstallInVendorRamdisk() { |
| vendorRamdiskVariantNeeded = true |
| coreVariantNeeded = false |
| } |
| |
| if m.RecoveryAvailable() { |
| recoveryVariantNeeded = true |
| } |
| |
| if m.AndroidModuleBase().InstallInRecovery() { |
| recoveryVariantNeeded = true |
| coreVariantNeeded = false |
| } |
| |
| // If using a snapshot, the recovery variant under AOSP directories is not needed, |
| // except for kernel headers, which needs all variants. |
| if !m.KernelHeadersDecorator() && |
| !m.IsSnapshotPrebuilt() && |
| usingRecoverySnapshot && |
| !snapshot.IsRecoveryProprietaryModule(mctx) { |
| recoveryVariantNeeded = false |
| } |
| |
| for _, variant := range android.FirstUniqueStrings(vendorVariants) { |
| m.AppendExtraVariant(VendorVariationPrefix + variant) |
| } |
| |
| for _, variant := range android.FirstUniqueStrings(productVariants) { |
| m.AppendExtraVariant(ProductVariationPrefix + variant) |
| } |
| |
| m.SetRamdiskVariantNeeded(ramdiskVariantNeeded) |
| m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded) |
| m.SetRecoveryVariantNeeded(recoveryVariantNeeded) |
| m.SetCoreVariantNeeded(coreVariantNeeded) |
| |
| // Disable the module if no variants are needed. |
| if !ramdiskVariantNeeded && |
| !recoveryVariantNeeded && |
| !coreVariantNeeded && |
| len(m.ExtraVariants()) == 0 { |
| m.Disable() |
| } |
| } |
| |
| func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { |
| return c.Properties.CoreVariantNeeded |
| } |
| |
| func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { |
| return c.Properties.RamdiskVariantNeeded |
| } |
| |
| func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { |
| return c.Properties.VendorRamdiskVariantNeeded |
| } |
| |
| func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { |
| return false |
| } |
| |
| func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { |
| return c.Properties.RecoveryVariantNeeded |
| } |
| |
| func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string { |
| return c.Properties.ExtraVersionedImageVariations |
| } |
| |
| func squashVendorSrcs(m *Module) { |
| if lib, ok := m.compiler.(*libraryDecorator); ok { |
| lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, |
| lib.baseCompiler.Properties.Target.Vendor.Srcs...) |
| |
| lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, |
| lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...) |
| |
| lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, |
| lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...) |
| } |
| } |
| |
| func squashProductSrcs(m *Module) { |
| if lib, ok := m.compiler.(*libraryDecorator); ok { |
| lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, |
| lib.baseCompiler.Properties.Target.Product.Srcs...) |
| |
| lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, |
| lib.baseCompiler.Properties.Target.Product.Exclude_srcs...) |
| |
| lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, |
| lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...) |
| } |
| } |
| |
| func squashRecoverySrcs(m *Module) { |
| if lib, ok := m.compiler.(*libraryDecorator); ok { |
| lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, |
| lib.baseCompiler.Properties.Target.Recovery.Srcs...) |
| |
| lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, |
| lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...) |
| |
| lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, |
| lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...) |
| } |
| } |
| |
| func squashVendorRamdiskSrcs(m *Module) { |
| if lib, ok := m.compiler.(*libraryDecorator); ok { |
| lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...) |
| } |
| } |
| |
| func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { |
| m := module.(*Module) |
| if variant == android.RamdiskVariation { |
| m.MakeAsPlatform() |
| } else if variant == android.VendorRamdiskVariation { |
| m.MakeAsPlatform() |
| squashVendorRamdiskSrcs(m) |
| } else if variant == android.RecoveryVariation { |
| m.MakeAsPlatform() |
| squashRecoverySrcs(m) |
| } else if strings.HasPrefix(variant, VendorVariationPrefix) { |
| m.Properties.ImageVariationPrefix = VendorVariationPrefix |
| m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix) |
| squashVendorSrcs(m) |
| |
| // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION. |
| // Hide other vendor variants to avoid collision. |
| vndkVersion := ctx.DeviceConfig().VndkVersion() |
| if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion { |
| m.Properties.HideFromMake = true |
| m.HideFromMake() |
| } |
| } else if strings.HasPrefix(variant, ProductVariationPrefix) { |
| m.Properties.ImageVariationPrefix = ProductVariationPrefix |
| m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) |
| squashProductSrcs(m) |
| } |
| |
| if c.NeedsVendorPublicLibraryVariants() && |
| (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) { |
| c.VendorProperties.IsVendorPublicLibrary = true |
| } |
| } |