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. 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 ( 20 "strings" 21 22 "android/soong/android" 23 24 "github.com/google/blueprint/proptools" 25) 26 27var _ android.ImageInterface = (*Module)(nil) 28 29type ImageVariantType string 30 31const ( 32 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" 39) 40 41const ( 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 *moduleContextImpl) inProduct() bool { 52 return ctx.mod.InProduct() 53} 54 55func (ctx *moduleContextImpl) inVendor() bool { 56 return ctx.mod.InVendor() 57} 58 59func (ctx *moduleContextImpl) inRamdisk() bool { 60 return ctx.mod.InRamdisk() 61} 62 63func (ctx *moduleContextImpl) inVendorRamdisk() bool { 64 return ctx.mod.InVendorRamdisk() 65} 66 67func (ctx *moduleContextImpl) inRecovery() bool { 68 return ctx.mod.InRecovery() 69} 70 71func (c *Module) InstallInProduct() bool { 72 // Additionally check if this module is inProduct() that means it is a "product" variant of a 73 // module. As well as product specific modules, product variants must be installed to /product. 74 return c.InProduct() 75} 76 77func (c *Module) InstallInVendor() bool { 78 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a 79 // module. As well as SoC specific modules, vendor variants must be installed to /vendor 80 // unless they have "odm_available: true". 81 return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm() 82} 83 84func (c *Module) InstallInOdm() bool { 85 // Some vendor variants want to be installed to /odm by setting "odm_available: true". 86 return c.InVendor() && c.VendorVariantToOdm() 87} 88 89// Returns true when this module is configured to have core and vendor variants. 90func (c *Module) HasVendorVariant() bool { 91 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available) 92} 93 94// Returns true when this module creates a vendor variant and wants to install the vendor variant 95// to the odm partition. 96func (c *Module) VendorVariantToOdm() bool { 97 return Bool(c.VendorProperties.Odm_available) 98} 99 100// Returns true when this module is configured to have core and product variants. 101func (c *Module) HasProductVariant() bool { 102 return Bool(c.VendorProperties.Product_available) 103} 104 105// Returns true when this module is configured to have core and either product or vendor variants. 106func (c *Module) HasNonSystemVariants() bool { 107 return c.HasVendorVariant() || c.HasProductVariant() 108} 109 110// Returns true if the module is "product" variant. Usually these modules are installed in /product 111func (c *Module) InProduct() bool { 112 return c.Properties.ImageVariation == android.ProductVariation 113} 114 115// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor 116func (c *Module) InVendor() bool { 117 return c.Properties.ImageVariation == android.VendorVariation 118} 119 120// Returns true if the module is "vendor" or "product" variant. This replaces previous UseVndk usages 121// which were misused to check if the module variant is vendor or product. 122func (c *Module) InVendorOrProduct() bool { 123 return c.InVendor() || c.InProduct() 124} 125 126func (c *Module) InRamdisk() bool { 127 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk() 128} 129 130func (c *Module) InVendorRamdisk() bool { 131 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk() 132} 133 134func (c *Module) InRecovery() bool { 135 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery() 136} 137 138func (c *Module) OnlyInRamdisk() bool { 139 return c.ModuleBase.InstallInRamdisk() 140} 141 142func (c *Module) OnlyInVendorRamdisk() bool { 143 return c.ModuleBase.InstallInVendorRamdisk() 144} 145 146func (c *Module) OnlyInRecovery() bool { 147 return c.ModuleBase.InstallInRecovery() 148} 149 150// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules. 151type ImageMutatableModule interface { 152 android.Module 153 LinkableInterface 154 155 // AndroidModuleBase returns the android.ModuleBase for this module 156 AndroidModuleBase() *android.ModuleBase 157 158 // VendorAvailable returns true if this module is available on the vendor image. 159 VendorAvailable() bool 160 161 // OdmAvailable returns true if this module is available on the odm image. 162 OdmAvailable() bool 163 164 // ProductAvailable returns true if this module is available on the product image. 165 ProductAvailable() bool 166 167 // RamdiskAvailable returns true if this module is available on the ramdisk image. 168 RamdiskAvailable() bool 169 170 // RecoveryAvailable returns true if this module is available on the recovery image. 171 RecoveryAvailable() bool 172 173 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image. 174 VendorRamdiskAvailable() bool 175 176 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt. 177 IsSnapshotPrebuilt() bool 178 179 // SnapshotVersion returns the snapshot version for this module. 180 SnapshotVersion(mctx android.ImageInterfaceContext) string 181 182 // ExtraVariants returns the list of extra variants this module requires. 183 ExtraVariants() []string 184 185 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires. 186 AppendExtraVariant(extraVariant string) 187 188 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed. 189 SetRamdiskVariantNeeded(b bool) 190 191 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed. 192 SetVendorRamdiskVariantNeeded(b bool) 193 194 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed. 195 SetRecoveryVariantNeeded(b bool) 196 197 // SetCoreVariantNeeded sets whether the Core Variant is needed. 198 SetCoreVariantNeeded(b bool) 199 200 // SetProductVariantNeeded sets whether the Product Variant is needed. 201 SetProductVariantNeeded(b bool) 202 203 // SetVendorVariantNeeded sets whether the Vendor Variant is needed. 204 SetVendorVariantNeeded(b bool) 205} 206 207var _ ImageMutatableModule = (*Module)(nil) 208 209func (m *Module) ImageMutatorBegin(mctx android.ImageInterfaceContext) { 210 MutateImage(mctx, m) 211} 212 213func (m *Module) VendorAvailable() bool { 214 return Bool(m.VendorProperties.Vendor_available) 215} 216 217func (m *Module) OdmAvailable() bool { 218 return Bool(m.VendorProperties.Odm_available) 219} 220 221func (m *Module) ProductAvailable() bool { 222 return Bool(m.VendorProperties.Product_available) 223} 224 225func (m *Module) RamdiskAvailable() bool { 226 return Bool(m.Properties.Ramdisk_available) 227} 228 229func (m *Module) VendorRamdiskAvailable() bool { 230 return Bool(m.Properties.Vendor_ramdisk_available) 231} 232 233func (m *Module) AndroidModuleBase() *android.ModuleBase { 234 return &m.ModuleBase 235} 236 237func (m *Module) RecoveryAvailable() bool { 238 return Bool(m.Properties.Recovery_available) 239} 240 241func (m *Module) ExtraVariants() []string { 242 return m.Properties.ExtraVersionedImageVariations 243} 244 245func (m *Module) AppendExtraVariant(extraVariant string) { 246 m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant) 247} 248 249func (m *Module) SetRamdiskVariantNeeded(b bool) { 250 m.Properties.RamdiskVariantNeeded = b 251} 252 253func (m *Module) SetVendorRamdiskVariantNeeded(b bool) { 254 m.Properties.VendorRamdiskVariantNeeded = b 255} 256 257func (m *Module) SetRecoveryVariantNeeded(b bool) { 258 m.Properties.RecoveryVariantNeeded = b 259} 260 261func (m *Module) SetCoreVariantNeeded(b bool) { 262 m.Properties.CoreVariantNeeded = b 263} 264 265func (m *Module) SetProductVariantNeeded(b bool) { 266 m.Properties.ProductVariantNeeded = b 267} 268 269func (m *Module) SetVendorVariantNeeded(b bool) { 270 m.Properties.VendorVariantNeeded = b 271} 272 273func (m *Module) SnapshotVersion(mctx android.ImageInterfaceContext) string { 274 if snapshot, ok := m.linker.(SnapshotInterface); ok { 275 return snapshot.Version() 276 } else { 277 mctx.ModuleErrorf("version is unknown for snapshot prebuilt") 278 // Should we be panicking here instead? 279 return "" 280 } 281} 282 283func (m *Module) KernelHeadersDecorator() bool { 284 if _, ok := m.linker.(*kernelHeadersDecorator); ok { 285 return true 286 } 287 return false 288} 289 290// MutateImage handles common image mutations for ImageMutatableModule interfaces. 291func MutateImage(mctx android.ImageInterfaceContext, m ImageMutatableModule) { 292 // Validation check 293 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() 294 productSpecific := mctx.ProductSpecific() 295 296 if m.VendorAvailable() { 297 if vendorSpecific { 298 mctx.PropertyErrorf("vendor_available", 299 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`") 300 } 301 if m.OdmAvailable() { 302 mctx.PropertyErrorf("vendor_available", 303 "doesn't make sense at the same time as `odm_available: true`") 304 } 305 } 306 307 if m.OdmAvailable() { 308 if vendorSpecific { 309 mctx.PropertyErrorf("odm_available", 310 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`") 311 } 312 } 313 314 if m.ProductAvailable() { 315 if productSpecific { 316 mctx.PropertyErrorf("product_available", 317 "doesn't make sense at the same time as `product_specific: true`") 318 } 319 if vendorSpecific { 320 mctx.PropertyErrorf("product_available", 321 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`") 322 } 323 } 324 325 var vendorVariantNeeded bool = false 326 var productVariantNeeded bool = false 327 var coreVariantNeeded bool = false 328 var ramdiskVariantNeeded bool = false 329 var vendorRamdiskVariantNeeded bool = false 330 var recoveryVariantNeeded bool = false 331 332 if m.NeedsLlndkVariants() { 333 // This is an LLNDK library. The implementation of the library will be on /system, 334 // and vendor and product variants will be created with LLNDK stubs. 335 // The LLNDK libraries need vendor variants even if there is no VNDK. 336 coreVariantNeeded = true 337 vendorVariantNeeded = true 338 productVariantNeeded = true 339 340 } else if m.NeedsVendorPublicLibraryVariants() { 341 // A vendor public library has the implementation on /vendor, with stub variants 342 // for system and product. 343 coreVariantNeeded = true 344 vendorVariantNeeded = true 345 productVariantNeeded = true 346 } else if m.IsSnapshotPrebuilt() { 347 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and 348 // PRODUCT_EXTRA_VNDK_VERSIONS. 349 if m.InstallInRecovery() { 350 recoveryVariantNeeded = true 351 } else { 352 m.AppendExtraVariant(VendorVariationPrefix + m.SnapshotVersion(mctx)) 353 } 354 } else if m.HasNonSystemVariants() { 355 // This will be available to /system unless it is product_specific 356 // which will be handled later. 357 coreVariantNeeded = true 358 359 // We assume that modules under proprietary paths are compatible for 360 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or 361 // PLATFORM_VNDK_VERSION. 362 if m.HasVendorVariant() { 363 vendorVariantNeeded = true 364 } 365 366 // product_available modules are available to /product. 367 if m.HasProductVariant() { 368 productVariantNeeded = true 369 } 370 } else if vendorSpecific { 371 // This will be available in /vendor (or /odm) only 372 vendorVariantNeeded = true 373 } else { 374 // This is either in /system (or similar: /data), or is a 375 // module built with the NDK. Modules built with the NDK 376 // will be restricted using the existing link type checks. 377 coreVariantNeeded = true 378 } 379 380 if coreVariantNeeded && productSpecific { 381 // The module has "product_specific: true" that does not create core variant. 382 coreVariantNeeded = false 383 productVariantNeeded = true 384 } 385 386 if m.RamdiskAvailable() { 387 ramdiskVariantNeeded = true 388 } 389 390 if m.AndroidModuleBase().InstallInRamdisk() { 391 ramdiskVariantNeeded = true 392 coreVariantNeeded = false 393 } 394 395 if m.VendorRamdiskAvailable() { 396 vendorRamdiskVariantNeeded = true 397 } 398 399 if m.AndroidModuleBase().InstallInVendorRamdisk() { 400 vendorRamdiskVariantNeeded = true 401 coreVariantNeeded = false 402 } 403 404 if m.RecoveryAvailable() { 405 recoveryVariantNeeded = true 406 } 407 408 if m.AndroidModuleBase().InstallInRecovery() { 409 recoveryVariantNeeded = true 410 coreVariantNeeded = false 411 } 412 413 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded) 414 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded) 415 m.SetRecoveryVariantNeeded(recoveryVariantNeeded) 416 m.SetCoreVariantNeeded(coreVariantNeeded) 417 m.SetProductVariantNeeded(productVariantNeeded) 418 m.SetVendorVariantNeeded(vendorVariantNeeded) 419 420 // Disable the module if no variants are needed. 421 if !ramdiskVariantNeeded && 422 !recoveryVariantNeeded && 423 !coreVariantNeeded && 424 !productVariantNeeded && 425 !vendorVariantNeeded && 426 len(m.ExtraVariants()) == 0 { 427 m.Disable() 428 } 429} 430 431func (c *Module) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool { 432 return c.Properties.VendorVariantNeeded 433} 434 435func (c *Module) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool { 436 return c.Properties.ProductVariantNeeded 437} 438 439func (c *Module) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool { 440 return c.Properties.CoreVariantNeeded 441} 442 443func (c *Module) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool { 444 return c.Properties.RamdiskVariantNeeded 445} 446 447func (c *Module) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool { 448 return c.Properties.VendorRamdiskVariantNeeded 449} 450 451func (c *Module) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool { 452 return false 453} 454 455func (c *Module) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool { 456 return c.Properties.RecoveryVariantNeeded 457} 458 459func (c *Module) ExtraImageVariations(ctx android.ImageInterfaceContext) []string { 460 return c.Properties.ExtraVersionedImageVariations 461} 462 463func squashVendorSrcs(m *Module) { 464 if lib, ok := m.compiler.(*libraryDecorator); ok { 465 lib.baseCompiler.Properties.Srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Vendor.Srcs) 466 lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs) 467 468 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, 469 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...) 470 471 if lib.Properties.Target.Vendor.No_stubs { 472 proptools.Clear(&lib.Properties.Stubs) 473 } 474 } 475} 476 477func squashProductSrcs(m *Module) { 478 if lib, ok := m.compiler.(*libraryDecorator); ok { 479 lib.baseCompiler.Properties.Srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Product.Srcs) 480 lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Product.Exclude_srcs) 481 482 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, 483 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...) 484 485 if lib.Properties.Target.Product.No_stubs { 486 proptools.Clear(&lib.Properties.Stubs) 487 } 488 } 489} 490 491func squashRecoverySrcs(m *Module) { 492 if lib, ok := m.compiler.(*libraryDecorator); ok { 493 lib.baseCompiler.Properties.Srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Recovery.Srcs) 494 lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs) 495 496 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, 497 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...) 498 } 499} 500 501func squashVendorRamdiskSrcs(m *Module) { 502 if lib, ok := m.compiler.(*libraryDecorator); ok { 503 lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs) 504 } 505} 506 507func squashRamdiskSrcs(m *Module) { 508 if lib, ok := m.compiler.(*libraryDecorator); ok { 509 lib.baseCompiler.Properties.Exclude_srcs.AppendSimpleValue(lib.baseCompiler.Properties.Target.Ramdisk.Exclude_srcs) 510 } 511} 512 513func (c *Module) SetImageVariation(ctx android.ImageInterfaceContext, variant string) { 514 if variant == android.RamdiskVariation { 515 c.MakeAsPlatform() 516 squashRamdiskSrcs(c) 517 } else if variant == android.VendorRamdiskVariation { 518 c.MakeAsPlatform() 519 squashVendorRamdiskSrcs(c) 520 } else if variant == android.RecoveryVariation { 521 c.MakeAsPlatform() 522 squashRecoverySrcs(c) 523 } else if strings.HasPrefix(variant, android.VendorVariation) { 524 c.Properties.ImageVariation = android.VendorVariation 525 526 if strings.HasPrefix(variant, VendorVariationPrefix) { 527 c.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix) 528 } 529 squashVendorSrcs(c) 530 } else if strings.HasPrefix(variant, android.ProductVariation) { 531 c.Properties.ImageVariation = android.ProductVariation 532 if strings.HasPrefix(variant, ProductVariationPrefix) { 533 c.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) 534 } 535 squashProductSrcs(c) 536 } 537 538 if c.NeedsVendorPublicLibraryVariants() && 539 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) { 540 c.VendorProperties.IsVendorPublicLibrary = true 541 } 542} 543