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 "fmt" 21 "reflect" 22 "strings" 23 24 "android/soong/android" 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 *moduleContext) ProductSpecific() bool { 52 return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext() 53} 54 55func (ctx *moduleContext) SocSpecific() bool { 56 return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext() 57} 58 59func (ctx *moduleContext) DeviceSpecific() bool { 60 return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext() 61} 62 63func (ctx *moduleContextImpl) inProduct() bool { 64 return ctx.mod.InProduct() 65} 66 67func (ctx *moduleContextImpl) inVendor() bool { 68 return ctx.mod.InVendor() 69} 70 71func (ctx *moduleContextImpl) inRamdisk() bool { 72 return ctx.mod.InRamdisk() 73} 74 75func (ctx *moduleContextImpl) inVendorRamdisk() bool { 76 return ctx.mod.InVendorRamdisk() 77} 78 79func (ctx *moduleContextImpl) inRecovery() bool { 80 return ctx.mod.InRecovery() 81} 82 83func (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 101// Returns true when this module is configured to have core and vendor variants. 102func (c *Module) HasVendorVariant() bool { 103 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) 110} 111 112// Returns true when this module is configured to have core and product variants. 113func (c *Module) HasProductVariant() bool { 114 return Bool(c.VendorProperties.Product_available) 115} 116 117// Returns true when this module is configured to have core and either product or vendor variants. 118func (c *Module) HasNonSystemVariants() bool { 119 return c.HasVendorVariant() || c.HasProductVariant() 120} 121 122// Returns true if the module is "product" variant. Usually these modules are installed in /product 123func (c *Module) InProduct() bool { 124 return c.Properties.ImageVariationPrefix == ProductVariationPrefix 125} 126 127// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor 128func (c *Module) InVendor() bool { 129 return c.Properties.ImageVariationPrefix == VendorVariationPrefix 130} 131 132func (c *Module) InRamdisk() bool { 133 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk() 134} 135 136func (c *Module) InVendorRamdisk() bool { 137 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk() 138} 139 140func (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 148func (c *Module) OnlyInVendorRamdisk() bool { 149 return c.ModuleBase.InstallInVendorRamdisk() 150} 151 152func (c *Module) OnlyInRecovery() bool { 153 return c.ModuleBase.InstallInRecovery() 154} 155 156func 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 { 191 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) { 192 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 202// 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 258func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { 259 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) { 266 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() 267 productSpecific := mctx.ProductSpecific() 268 269 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") 275 } else if Bool(m.VendorProperties.Vendor_available) { 276 mctx.PropertyErrorf("vendor_available", 277 "must not set at the same time as `vndk: {extends: \"...\"}`") 278 } else if Bool(m.VendorProperties.Product_available) { 279 mctx.PropertyErrorf("product_available", 280 "must not set at the same time as `vndk: {extends: \"...\"}`") 281 } 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 } 288 if !Bool(m.VendorProperties.Vendor_available) { 289 mctx.PropertyErrorf("vndk", 290 "vendor_available must be set to true when `vndk: {enabled: true}`") 291 } 292 if Bool(m.VendorProperties.Product_available) { 293 // 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. 296 if !m.compareVendorAndProductProps() { 297 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules") 298 } 299 } 300 } 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 } 313} 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 } 418 419 var coreVariantNeeded bool = false 420 var ramdiskVariantNeeded bool = false 421 var vendorRamdiskVariantNeeded bool = false 422 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() 430 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion() 431 usingRecoverySnapshot := recoverySnapshotVersion != "current" && 432 recoverySnapshotVersion != "" 433 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 } 443 if boardVndkVersion == "current" { 444 boardVndkVersion = platformVndkVersion 445 } 446 if productVndkVersion == "current" { 447 productVndkVersion = platformVndkVersion 448 } 449 450 if m.NeedsLlndkVariants() { 451 // 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. 454 coreVariantNeeded = true 455 if platformVndkVersion != "" { 456 vendorVariants = append(vendorVariants, platformVndkVersion) 457 productVariants = append(productVariants, platformVndkVersion) 458 } 459 // Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not 460 // provide the LLNDK stub libraries. 461 if needVndkVersionVendorVariantForLlndk { 462 vendorVariants = append(vendorVariants, boardVndkVersion) 463 } 464 if productVndkVersion != "" { 465 productVariants = append(productVariants, productVndkVersion) 466 } 467 } 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 } 478 } else if boardVndkVersion == "" { 479 // If the device isn't compiling against the VNDK, we always 480 // use the core mode. 481 coreVariantNeeded = true 482 } else if m.IsSnapshotPrebuilt() { 483 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and 484 // PRODUCT_EXTRA_VNDK_VERSIONS. 485 if m.InstallInRecovery() { 486 recoveryVariantNeeded = true 487 } else { 488 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx)) 489 } 490 } else if m.HasNonSystemVariants() && !m.IsVndkExt() { 491 // This will be available to /system unless it is product_specific 492 // which will be handled later. 493 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. 498 if m.HasVendorVariant() { 499 if isVendorProprietaryModule(mctx) { 500 vendorVariants = append(vendorVariants, boardVndkVersion) 501 } else { 502 vendorVariants = append(vendorVariants, platformVndkVersion) 503 } 504 } 505 506 // 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 } 513 } 514 } else if vendorSpecific && m.SdkVersion() == "" { 515 // 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. 523 if m.KernelHeadersDecorator() { 524 vendorVariants = append(vendorVariants, 525 platformVndkVersion, 526 boardVndkVersion, 527 ) 528 } else if isVendorProprietaryModule(mctx) { 529 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 != "" { 541 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" { 542 // 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 553 if m.RamdiskAvailable() { 554 ramdiskVariantNeeded = true 555 } 556 557 if m.AndroidModuleBase().InstallInRamdisk() { 558 ramdiskVariantNeeded = true 559 coreVariantNeeded = false 560 } 561 562 if m.VendorRamdiskAvailable() { 563 vendorRamdiskVariantNeeded = true 564 } 565 566 if m.AndroidModuleBase().InstallInVendorRamdisk() { 567 vendorRamdiskVariantNeeded = true 568 coreVariantNeeded = false 569 } 570 571 if m.RecoveryAvailable() { 572 recoveryVariantNeeded = true 573 } 574 575 if m.AndroidModuleBase().InstallInRecovery() { 576 recoveryVariantNeeded = true 577 coreVariantNeeded = false 578 } 579 580 // If using a snapshot, the recovery variant under AOSP directories is not needed, 581 // except for kernel headers, which needs all variants. 582 if m.KernelHeadersDecorator() && 583 !m.IsSnapshotPrebuilt() && 584 usingRecoverySnapshot && 585 !isRecoveryProprietaryModule(mctx) { 586 recoveryVariantNeeded = false 587 } 588 589 for _, variant := range android.FirstUniqueStrings(vendorVariants) { 590 m.AppendExtraVariant(VendorVariationPrefix + variant) 591 } 592 593 for _, variant := range android.FirstUniqueStrings(productVariants) { 594 m.AppendExtraVariant(ProductVariationPrefix + variant) 595 } 596 597 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded) 598 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded) 599 m.SetRecoveryVariantNeeded(recoveryVariantNeeded) 600 m.SetCoreVariantNeeded(coreVariantNeeded) 601 602 // Disable the module if no variants are needed. 603 if !ramdiskVariantNeeded && 604 !recoveryVariantNeeded && 605 !coreVariantNeeded && 606 len(m.ExtraVariants()) == 0 { 607 m.Disable() 608 } 609} 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 619func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 620 return c.Properties.VendorRamdiskVariantNeeded 621} 622 623func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 624 return false 625} 626 627func (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 635func 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 680func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { 681 m := module.(*Module) 682 if variant == android.RamdiskVariation { 683 m.MakeAsPlatform() 684 } else if variant == android.VendorRamdiskVariation { 685 m.MakeAsPlatform() 686 squashVendorRamdiskSrcs(m) 687 } 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 700 m.HideFromMake() 701 } 702 } else if strings.HasPrefix(variant, ProductVariationPrefix) { 703 m.Properties.ImageVariationPrefix = ProductVariationPrefix 704 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) 705 squashProductSrcs(m) 706 } 707 708 if c.NeedsVendorPublicLibraryVariants() && 709 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) { 710 c.VendorProperties.IsVendorPublicLibrary = true 711 } 712} 713