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 false 38} 39 40func (mod *Module) RamdiskAvailable() bool { 41 return false 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 false 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 if b { 66 panic("Setting ramdisk variant needed for Rust module is unsupported: " + mod.BaseModuleName()) 67 } 68} 69 70func (mod *Module) SetVendorRamdiskVariantNeeded(b bool) { 71 mod.Properties.VendorRamdiskVariantNeeded = b 72} 73 74func (mod *Module) SetRecoveryVariantNeeded(b bool) { 75 if b { 76 panic("Setting recovery variant needed for Rust module is unsupported: " + mod.BaseModuleName()) 77 } 78} 79 80func (mod *Module) SetCoreVariantNeeded(b bool) { 81 mod.Properties.CoreVariantNeeded = b 82} 83 84func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string { 85 panic("Rust modules do not support snapshotting: " + mod.BaseModuleName()) 86} 87 88func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 89 return mod.Properties.VendorRamdiskVariantNeeded 90} 91 92func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 93 return mod.Properties.CoreVariantNeeded 94} 95 96func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool { 97 return mod.InRamdisk() 98} 99 100func (mod *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 101 return false 102} 103 104func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool { 105 return mod.InRecovery() 106} 107 108func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string { 109 return mod.Properties.ExtraVariants 110} 111 112func (mod *Module) IsSnapshotPrebuilt() bool { 113 // Rust does not support prebuilts in its snapshots 114 return false 115} 116 117func (ctx *moduleContext) SocSpecific() bool { 118 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a 119 // module. As well as SoC specific modules, vendor variants must be installed to /vendor 120 // unless they have "odm_available: true". 121 return ctx.ModuleContext.SocSpecific() || (ctx.RustModule().InVendor() && !ctx.RustModule().VendorVariantToOdm()) 122} 123 124func (ctx *moduleContext) DeviceSpecific() bool { 125 // Some vendor variants want to be installed to /odm by setting "odm_available: true". 126 return ctx.ModuleContext.DeviceSpecific() || (ctx.RustModule().InVendor() && ctx.RustModule().VendorVariantToOdm()) 127} 128 129// Returns true when this module creates a vendor variant and wants to install the vendor variant 130// to the odm partition. 131func (c *Module) VendorVariantToOdm() bool { 132 return Bool(c.VendorProperties.Odm_available) 133} 134 135func (ctx *moduleContext) ProductSpecific() bool { 136 return false 137} 138 139func (mod *Module) InRecovery() bool { 140 // TODO(b/165791368) 141 return false 142} 143 144func (mod *Module) InVendorRamdisk() bool { 145 return mod.ModuleBase.InVendorRamdisk() || mod.ModuleBase.InstallInVendorRamdisk() 146} 147 148func (mod *Module) OnlyInRamdisk() bool { 149 // TODO(b/165791368) 150 return false 151} 152 153func (mod *Module) OnlyInRecovery() bool { 154 // TODO(b/165791368) 155 return false 156} 157 158func (mod *Module) OnlyInVendorRamdisk() bool { 159 return false 160} 161 162// Returns true when this module is configured to have core and vendor variants. 163func (mod *Module) HasVendorVariant() bool { 164 return Bool(mod.VendorProperties.Vendor_available) || Bool(mod.VendorProperties.Odm_available) 165} 166 167// Always returns false because rust modules do not support product variant. 168func (mod *Module) HasProductVariant() bool { 169 return Bool(mod.VendorProperties.Product_available) 170} 171 172func (mod *Module) HasNonSystemVariants() bool { 173 return mod.HasVendorVariant() || mod.HasProductVariant() 174} 175 176func (mod *Module) InProduct() bool { 177 return false 178} 179 180// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor 181func (mod *Module) InVendor() bool { 182 return mod.Properties.ImageVariationPrefix == cc.VendorVariationPrefix 183} 184 185func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { 186 m := module.(*Module) 187 if variant == android.VendorRamdiskVariation { 188 m.MakeAsPlatform() 189 } else if strings.HasPrefix(variant, cc.VendorVariationPrefix) { 190 m.Properties.ImageVariationPrefix = cc.VendorVariationPrefix 191 m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix) 192 193 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION. 194 // Hide other vendor variants to avoid collision. 195 vndkVersion := ctx.DeviceConfig().VndkVersion() 196 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion { 197 m.Properties.HideFromMake = true 198 m.HideFromMake() 199 } 200 } 201} 202 203func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { 204 // Rust does not support installing to the product image yet. 205 if Bool(mod.VendorProperties.Product_available) { 206 mctx.PropertyErrorf("product_available", 207 "Rust modules do not yet support being available to the product image") 208 } else if mctx.ProductSpecific() { 209 mctx.PropertyErrorf("product_specific", 210 "Rust modules do not yet support installing to the product image.") 211 } else if Bool(mod.VendorProperties.Double_loadable) { 212 mctx.PropertyErrorf("double_loadable", 213 "Rust modules do not yet support double loading") 214 } 215 if Bool(mod.Properties.Vendor_ramdisk_available) { 216 if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && lib.buildShared()) { 217 mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.") 218 } 219 } 220 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() 221 if vendorSpecific { 222 mctx.PropertyErrorf("vendor or soc_specific", 223 "Rust modules do not yet support soc-specific modules") 224 225 } 226 227 cc.MutateImage(mctx, mod) 228 229 if !mod.Properties.CoreVariantNeeded || mod.HasNonSystemVariants() { 230 231 if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok { 232 // Rust does not support prebuilt libraries on non-System images. 233 mctx.ModuleErrorf("Rust prebuilt modules not supported for non-system images.") 234 } 235 } 236} 237