1// 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. 14 15package rust 16 17import ( 18 "strings" 19 20 "android/soong/android" 21 "android/soong/cc" 22) 23 24var _ android.ImageInterface = (*Module)(nil) 25 26var _ cc.ImageMutatableModule = (*Module)(nil) 27 28func (mod *Module) VendorAvailable() bool { 29 return Bool(mod.VendorProperties.Vendor_available) 30} 31 32func (mod *Module) OdmAvailable() bool { 33 return Bool(mod.VendorProperties.Odm_available) 34} 35 36func (mod *Module) ProductAvailable() bool { 37 return Bool(mod.VendorProperties.Product_available) 38} 39 40func (mod *Module) RamdiskAvailable() bool { 41 return Bool(mod.Properties.Ramdisk_available) 42} 43 44func (mod *Module) VendorRamdiskAvailable() bool { 45 return Bool(mod.Properties.Vendor_ramdisk_available) 46} 47 48func (mod *Module) AndroidModuleBase() *android.ModuleBase { 49 return &mod.ModuleBase 50} 51 52func (mod *Module) RecoveryAvailable() bool { 53 return Bool(mod.Properties.Recovery_available) 54} 55 56func (mod *Module) ExtraVariants() []string { 57 return mod.Properties.ExtraVariants 58} 59 60func (mod *Module) AppendExtraVariant(extraVariant string) { 61 mod.Properties.ExtraVariants = append(mod.Properties.ExtraVariants, extraVariant) 62} 63 64func (mod *Module) SetRamdiskVariantNeeded(b bool) { 65 mod.Properties.RamdiskVariantNeeded = b 66} 67 68func (mod *Module) SetVendorRamdiskVariantNeeded(b bool) { 69 mod.Properties.VendorRamdiskVariantNeeded = b 70} 71 72func (mod *Module) SetRecoveryVariantNeeded(b bool) { 73 mod.Properties.RecoveryVariantNeeded = b 74} 75 76func (mod *Module) SetCoreVariantNeeded(b bool) { 77 mod.Properties.CoreVariantNeeded = b 78} 79 80func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string { 81 if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok { 82 return snapshot.Version() 83 } else { 84 mctx.ModuleErrorf("version is unknown for snapshot prebuilt") 85 return "" 86 } 87} 88 89func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 90 return mod.Properties.VendorRamdiskVariantNeeded 91} 92 93func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 94 return mod.Properties.CoreVariantNeeded 95} 96 97func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool { 98 return mod.Properties.RamdiskVariantNeeded 99} 100 101func (mod *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 102 return false 103} 104 105func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool { 106 return mod.Properties.RecoveryVariantNeeded 107} 108 109func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string { 110 return mod.Properties.ExtraVariants 111} 112 113func (mod *Module) IsSnapshotPrebuilt() bool { 114 if p, ok := mod.compiler.(cc.SnapshotInterface); ok { 115 return p.IsSnapshotPrebuilt() 116 } 117 return false 118} 119 120func (ctx *moduleContext) SocSpecific() bool { 121 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a 122 // module. As well as SoC specific modules, vendor variants must be installed to /vendor 123 // unless they have "odm_available: true". 124 return ctx.ModuleContext.SocSpecific() || (ctx.RustModule().InVendor() && !ctx.RustModule().VendorVariantToOdm()) 125} 126 127func (ctx *moduleContext) DeviceSpecific() bool { 128 // Some vendor variants want to be installed to /odm by setting "odm_available: true". 129 return ctx.ModuleContext.DeviceSpecific() || (ctx.RustModule().InVendor() && ctx.RustModule().VendorVariantToOdm()) 130} 131 132func (ctx *moduleContext) SystemExtSpecific() bool { 133 return ctx.ModuleContext.SystemExtSpecific() 134} 135 136// Returns true when this module creates a vendor variant and wants to install the vendor variant 137// to the odm partition. 138func (c *Module) VendorVariantToOdm() bool { 139 return Bool(c.VendorProperties.Odm_available) 140} 141 142func (ctx *moduleContext) ProductSpecific() bool { 143 return ctx.ModuleContext.ProductSpecific() || ctx.RustModule().productSpecificModuleContext() 144} 145 146func (c *Module) productSpecificModuleContext() bool { 147 // Additionally check if this module is inProduct() that means it is a "product" variant of a 148 // module. As well as product specific modules, product variants must be installed to /product. 149 return c.InProduct() 150} 151 152func (mod *Module) InRecovery() bool { 153 return mod.ModuleBase.InRecovery() || mod.ModuleBase.InstallInRecovery() 154} 155 156func (mod *Module) InRamdisk() bool { 157 return mod.ModuleBase.InRamdisk() || mod.ModuleBase.InstallInRamdisk() 158} 159 160func (mod *Module) InVendorRamdisk() bool { 161 return mod.ModuleBase.InVendorRamdisk() || mod.ModuleBase.InstallInVendorRamdisk() 162} 163 164func (mod *Module) OnlyInRamdisk() bool { 165 return mod.ModuleBase.InstallInRamdisk() 166} 167 168func (mod *Module) OnlyInRecovery() bool { 169 return mod.ModuleBase.InstallInRecovery() 170} 171 172func (mod *Module) OnlyInVendorRamdisk() bool { 173 return mod.ModuleBase.InstallInVendorRamdisk() 174} 175 176// Returns true when this module is configured to have core and vendor variants. 177func (mod *Module) HasVendorVariant() bool { 178 return Bool(mod.VendorProperties.Vendor_available) || Bool(mod.VendorProperties.Odm_available) 179} 180 181// Always returns false because rust modules do not support product variant. 182func (mod *Module) HasProductVariant() bool { 183 return Bool(mod.VendorProperties.Product_available) 184} 185 186func (mod *Module) HasNonSystemVariants() bool { 187 return mod.HasVendorVariant() || mod.HasProductVariant() 188} 189 190func (mod *Module) InProduct() bool { 191 return mod.Properties.ImageVariationPrefix == cc.ProductVariationPrefix 192} 193 194// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor 195func (mod *Module) InVendor() bool { 196 return mod.Properties.ImageVariationPrefix == cc.VendorVariationPrefix 197} 198 199func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { 200 m := module.(*Module) 201 if variant == android.VendorRamdiskVariation { 202 m.MakeAsPlatform() 203 } else if variant == android.RecoveryVariation { 204 m.MakeAsPlatform() 205 } else if strings.HasPrefix(variant, cc.VendorVariationPrefix) { 206 m.Properties.ImageVariationPrefix = cc.VendorVariationPrefix 207 m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix) 208 209 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION. 210 // Hide other vendor variants to avoid collision. 211 vndkVersion := ctx.DeviceConfig().VndkVersion() 212 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion { 213 m.Properties.HideFromMake = true 214 m.HideFromMake() 215 } 216 } else if strings.HasPrefix(variant, cc.ProductVariationPrefix) { 217 m.Properties.ImageVariationPrefix = cc.ProductVariationPrefix 218 m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.ProductVariationPrefix) 219 } 220} 221 222func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { 223 // Rust does not support installing to the product image yet. 224 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() 225 226 if Bool(mod.VendorProperties.Double_loadable) { 227 mctx.PropertyErrorf("double_loadable", 228 "Rust modules do not yet support double loading") 229 } 230 if Bool(mod.Properties.Vendor_ramdisk_available) { 231 if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && lib.buildShared()) { 232 mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.") 233 } 234 } 235 if vendorSpecific { 236 if lib, ok := mod.compiler.(libraryInterface); ok && lib.buildDylib() { 237 mctx.PropertyErrorf("vendor", "Vendor-only dylibs are not yet supported, use rust_library_rlib.") 238 } 239 } 240 if mctx.ProductSpecific() { 241 if lib, ok := mod.compiler.(libraryInterface); ok && lib.buildDylib() { 242 mctx.PropertyErrorf("product", "Product-only dylibs are not yet supported, use rust_library_rlib.") 243 } 244 } 245 246 cc.MutateImage(mctx, mod) 247 248 if !mod.Properties.CoreVariantNeeded || mod.HasNonSystemVariants() { 249 250 if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok { 251 // Rust does not support prebuilt libraries on non-System images. 252 mctx.ModuleErrorf("Rust prebuilt modules not supported for non-system images.") 253 } 254 } 255} 256