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 "android/soong/snapshot" 26) 27 28var _ android.ImageInterface = (*Module)(nil) 29 30type ImageVariantType string 31 32const ( 33 coreImageVariant ImageVariantType = "core" 34 vendorImageVariant ImageVariantType = "vendor" 35 productImageVariant ImageVariantType = "product" 36 ramdiskImageVariant ImageVariantType = "ramdisk" 37 vendorRamdiskImageVariant ImageVariantType = "vendor_ramdisk" 38 recoveryImageVariant ImageVariantType = "recovery" 39 hostImageVariant ImageVariantType = "host" 40) 41 42const ( 43 // VendorVariationPrefix is the variant prefix used for /vendor code that compiles 44 // against the VNDK. 45 VendorVariationPrefix = "vendor." 46 47 // ProductVariationPrefix is the variant prefix used for /product code that compiles 48 // against the VNDK. 49 ProductVariationPrefix = "product." 50) 51 52func (ctx *moduleContext) ProductSpecific() bool { 53 return ctx.ModuleContext.ProductSpecific() || ctx.mod.productSpecificModuleContext() 54} 55 56func (ctx *moduleContext) SocSpecific() bool { 57 return ctx.ModuleContext.SocSpecific() || ctx.mod.socSpecificModuleContext() 58} 59 60func (ctx *moduleContext) DeviceSpecific() bool { 61 return ctx.ModuleContext.DeviceSpecific() || ctx.mod.deviceSpecificModuleContext() 62} 63 64func (ctx *moduleContextImpl) inProduct() bool { 65 return ctx.mod.InProduct() 66} 67 68func (ctx *moduleContextImpl) inVendor() bool { 69 return ctx.mod.InVendor() 70} 71 72func (ctx *moduleContextImpl) inRamdisk() bool { 73 return ctx.mod.InRamdisk() 74} 75 76func (ctx *moduleContextImpl) inVendorRamdisk() bool { 77 return ctx.mod.InVendorRamdisk() 78} 79 80func (ctx *moduleContextImpl) inRecovery() bool { 81 return ctx.mod.InRecovery() 82} 83 84func (c *Module) productSpecificModuleContext() bool { 85 // Additionally check if this module is inProduct() that means it is a "product" variant of a 86 // module. As well as product specific modules, product variants must be installed to /product. 87 return c.InProduct() 88} 89 90func (c *Module) socSpecificModuleContext() bool { 91 // Additionally check if this module is inVendor() that means it is a "vendor" variant of a 92 // module. As well as SoC specific modules, vendor variants must be installed to /vendor 93 // unless they have "odm_available: true". 94 return c.HasVendorVariant() && c.InVendor() && !c.VendorVariantToOdm() 95} 96 97func (c *Module) deviceSpecificModuleContext() bool { 98 // Some vendor variants want to be installed to /odm by setting "odm_available: true". 99 return c.InVendor() && c.VendorVariantToOdm() 100} 101 102// Returns true when this module is configured to have core and vendor variants. 103func (c *Module) HasVendorVariant() bool { 104 return Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Odm_available) 105} 106 107// Returns true when this module creates a vendor variant and wants to install the vendor variant 108// to the odm partition. 109func (c *Module) VendorVariantToOdm() bool { 110 return Bool(c.VendorProperties.Odm_available) 111} 112 113// Returns true when this module is configured to have core and product variants. 114func (c *Module) HasProductVariant() bool { 115 return Bool(c.VendorProperties.Product_available) 116} 117 118// Returns true when this module is configured to have core and either product or vendor variants. 119func (c *Module) HasNonSystemVariants() bool { 120 return c.HasVendorVariant() || c.HasProductVariant() 121} 122 123// Returns true if the module is "product" variant. Usually these modules are installed in /product 124func (c *Module) InProduct() bool { 125 return c.Properties.ImageVariationPrefix == ProductVariationPrefix 126} 127 128// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor 129func (c *Module) InVendor() bool { 130 return c.Properties.ImageVariationPrefix == VendorVariationPrefix 131} 132 133func (c *Module) InRamdisk() bool { 134 return c.ModuleBase.InRamdisk() || c.ModuleBase.InstallInRamdisk() 135} 136 137func (c *Module) InVendorRamdisk() bool { 138 return c.ModuleBase.InVendorRamdisk() || c.ModuleBase.InstallInVendorRamdisk() 139} 140 141func (c *Module) InRecovery() bool { 142 return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery() 143} 144 145func (c *Module) OnlyInRamdisk() bool { 146 return c.ModuleBase.InstallInRamdisk() 147} 148 149func (c *Module) OnlyInVendorRamdisk() bool { 150 return c.ModuleBase.InstallInVendorRamdisk() 151} 152 153func (c *Module) OnlyInRecovery() bool { 154 return c.ModuleBase.InstallInRecovery() 155} 156 157func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool { 158 if v.Kind() != reflect.Struct { 159 return true 160 } 161 for i := 0; i < v.NumField(); i++ { 162 prop := v.Field(i) 163 if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" { 164 vendor_prop := prop.FieldByName("Vendor") 165 product_prop := prop.FieldByName("Product") 166 if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct { 167 // Neither Target.Vendor nor Target.Product is defined 168 continue 169 } 170 if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct || 171 !reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) { 172 // If only one of either Target.Vendor or Target.Product is 173 // defined or they have different values, it fails the build 174 // since VNDK must have the same properties for both vendor 175 // and product variants. 176 return false 177 } 178 } else if !visitPropsAndCompareVendorAndProductProps(prop) { 179 // Visit the substructures to find Target.Vendor and Target.Product 180 return false 181 } 182 } 183 return true 184} 185 186// In the case of VNDK, vendor and product variants must have the same properties. 187// VNDK installs only one file and shares it for both vendor and product modules on 188// runtime. We may not define different versions of a VNDK lib for each partition. 189// This function is used only for the VNDK modules that is available to both vendor 190// and product partitions. 191func (c *Module) compareVendorAndProductProps() bool { 192 if !c.IsVndk() && !Bool(c.VendorProperties.Product_available) { 193 panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name())) 194 } 195 for _, properties := range c.GetProperties() { 196 if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) { 197 return false 198 } 199 } 200 return true 201} 202 203// ImageMutatableModule provides a common image mutation interface for LinkableInterface modules. 204type ImageMutatableModule interface { 205 android.Module 206 LinkableInterface 207 208 // AndroidModuleBase returns the android.ModuleBase for this module 209 AndroidModuleBase() *android.ModuleBase 210 211 // VendorAvailable returns true if this module is available on the vendor image. 212 VendorAvailable() bool 213 214 // OdmAvailable returns true if this module is available on the odm image. 215 OdmAvailable() bool 216 217 // ProductAvailable returns true if this module is available on the product image. 218 ProductAvailable() bool 219 220 // RamdiskAvailable returns true if this module is available on the ramdisk image. 221 RamdiskAvailable() bool 222 223 // RecoveryAvailable returns true if this module is available on the recovery image. 224 RecoveryAvailable() bool 225 226 // VendorRamdiskAvailable returns true if this module is available on the vendor ramdisk image. 227 VendorRamdiskAvailable() bool 228 229 // IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt. 230 IsSnapshotPrebuilt() bool 231 232 // SnapshotVersion returns the snapshot version for this module. 233 SnapshotVersion(mctx android.BaseModuleContext) string 234 235 // SdkVersion returns the SDK version for this module. 236 SdkVersion() string 237 238 // ExtraVariants returns the list of extra variants this module requires. 239 ExtraVariants() []string 240 241 // AppendExtraVariant returns an extra variant to the list of extra variants this module requires. 242 AppendExtraVariant(extraVariant string) 243 244 // SetRamdiskVariantNeeded sets whether the Ramdisk Variant is needed. 245 SetRamdiskVariantNeeded(b bool) 246 247 // SetVendorRamdiskVariantNeeded sets whether the Vendor Ramdisk Variant is needed. 248 SetVendorRamdiskVariantNeeded(b bool) 249 250 // SetRecoveryVariantNeeded sets whether the Recovery Variant is needed. 251 SetRecoveryVariantNeeded(b bool) 252 253 // SetCoreVariantNeeded sets whether the Core Variant is needed. 254 SetCoreVariantNeeded(b bool) 255} 256 257var _ ImageMutatableModule = (*Module)(nil) 258 259func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { 260 m.CheckVndkProperties(mctx) 261 MutateImage(mctx, m) 262} 263 264// CheckVndkProperties checks whether the VNDK-related properties are set correctly. 265// If properties are not set correctly, results in a module context property error. 266func (m *Module) CheckVndkProperties(mctx android.BaseModuleContext) { 267 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() 268 productSpecific := mctx.ProductSpecific() 269 270 if vndkdep := m.vndkdep; vndkdep != nil { 271 if vndkdep.isVndk() { 272 if vendorSpecific || productSpecific { 273 if !vndkdep.isVndkExt() { 274 mctx.PropertyErrorf("vndk", 275 "must set `extends: \"...\"` to vndk extension") 276 } else if Bool(m.VendorProperties.Vendor_available) { 277 mctx.PropertyErrorf("vendor_available", 278 "must not set at the same time as `vndk: {extends: \"...\"}`") 279 } else if Bool(m.VendorProperties.Product_available) { 280 mctx.PropertyErrorf("product_available", 281 "must not set at the same time as `vndk: {extends: \"...\"}`") 282 } 283 } else { 284 if vndkdep.isVndkExt() { 285 mctx.PropertyErrorf("vndk", 286 "must set `vendor: true` or `product_specific: true` to set `extends: %q`", 287 m.getVndkExtendsModuleName()) 288 } 289 if !Bool(m.VendorProperties.Vendor_available) { 290 mctx.PropertyErrorf("vndk", 291 "vendor_available must be set to true when `vndk: {enabled: true}`") 292 } 293 if Bool(m.VendorProperties.Product_available) { 294 // If a VNDK module creates both product and vendor variants, they 295 // must have the same properties since they share a single VNDK 296 // library on runtime. 297 if !m.compareVendorAndProductProps() { 298 mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules") 299 } 300 } 301 } 302 } else { 303 if vndkdep.isVndkSp() { 304 mctx.PropertyErrorf("vndk", 305 "must set `enabled: true` to set `support_system_process: true`") 306 } 307 if vndkdep.isVndkExt() { 308 mctx.PropertyErrorf("vndk", 309 "must set `enabled: true` to set `extends: %q`", 310 m.getVndkExtendsModuleName()) 311 } 312 } 313 } 314} 315 316func (m *Module) VendorAvailable() bool { 317 return Bool(m.VendorProperties.Vendor_available) 318} 319 320func (m *Module) OdmAvailable() bool { 321 return Bool(m.VendorProperties.Odm_available) 322} 323 324func (m *Module) ProductAvailable() bool { 325 return Bool(m.VendorProperties.Product_available) 326} 327 328func (m *Module) RamdiskAvailable() bool { 329 return Bool(m.Properties.Ramdisk_available) 330} 331 332func (m *Module) VendorRamdiskAvailable() bool { 333 return Bool(m.Properties.Vendor_ramdisk_available) 334} 335 336func (m *Module) AndroidModuleBase() *android.ModuleBase { 337 return &m.ModuleBase 338} 339 340func (m *Module) RecoveryAvailable() bool { 341 return Bool(m.Properties.Recovery_available) 342} 343 344func (m *Module) ExtraVariants() []string { 345 return m.Properties.ExtraVersionedImageVariations 346} 347 348func (m *Module) AppendExtraVariant(extraVariant string) { 349 m.Properties.ExtraVersionedImageVariations = append(m.Properties.ExtraVersionedImageVariations, extraVariant) 350} 351 352func (m *Module) SetRamdiskVariantNeeded(b bool) { 353 m.Properties.RamdiskVariantNeeded = b 354} 355 356func (m *Module) SetVendorRamdiskVariantNeeded(b bool) { 357 m.Properties.VendorRamdiskVariantNeeded = b 358} 359 360func (m *Module) SetRecoveryVariantNeeded(b bool) { 361 m.Properties.RecoveryVariantNeeded = b 362} 363 364func (m *Module) SetCoreVariantNeeded(b bool) { 365 m.Properties.CoreVariantNeeded = b 366} 367 368func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string { 369 if snapshot, ok := m.linker.(SnapshotInterface); ok { 370 return snapshot.Version() 371 } else { 372 mctx.ModuleErrorf("version is unknown for snapshot prebuilt") 373 // Should we be panicking here instead? 374 return "" 375 } 376} 377 378func (m *Module) KernelHeadersDecorator() bool { 379 if _, ok := m.linker.(*kernelHeadersDecorator); ok { 380 return true 381 } 382 return false 383} 384 385// MutateImage handles common image mutations for ImageMutatableModule interfaces. 386func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) { 387 // Validation check 388 vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() 389 productSpecific := mctx.ProductSpecific() 390 391 if m.VendorAvailable() { 392 if vendorSpecific { 393 mctx.PropertyErrorf("vendor_available", 394 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`") 395 } 396 if m.OdmAvailable() { 397 mctx.PropertyErrorf("vendor_available", 398 "doesn't make sense at the same time as `odm_available: true`") 399 } 400 } 401 402 if m.OdmAvailable() { 403 if vendorSpecific { 404 mctx.PropertyErrorf("odm_available", 405 "doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific: true`") 406 } 407 } 408 409 if m.ProductAvailable() { 410 if productSpecific { 411 mctx.PropertyErrorf("product_available", 412 "doesn't make sense at the same time as `product_specific: true`") 413 } 414 if vendorSpecific { 415 mctx.PropertyErrorf("product_available", 416 "cannot provide product variant from a vendor module. Please use `product_specific: true` with `vendor_available: true`") 417 } 418 } 419 420 var coreVariantNeeded bool = false 421 var ramdiskVariantNeeded bool = false 422 var vendorRamdiskVariantNeeded bool = false 423 var recoveryVariantNeeded bool = false 424 425 var vendorVariants []string 426 var productVariants []string 427 428 platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion() 429 boardVndkVersion := mctx.DeviceConfig().VndkVersion() 430 productVndkVersion := mctx.DeviceConfig().ProductVndkVersion() 431 recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion() 432 usingRecoverySnapshot := recoverySnapshotVersion != "current" && 433 recoverySnapshotVersion != "" 434 needVndkVersionVendorVariantForLlndk := false 435 if boardVndkVersion != "" { 436 boardVndkApiLevel, err := android.ApiLevelFromUser(mctx, boardVndkVersion) 437 if err == nil && !boardVndkApiLevel.IsPreview() { 438 // VNDK snapshot newer than v30 has LLNDK stub libraries. 439 // Only the VNDK version less than or equal to v30 requires generating the vendor 440 // variant of the VNDK version from the source tree. 441 needVndkVersionVendorVariantForLlndk = boardVndkApiLevel.LessThanOrEqualTo(android.ApiLevelOrPanic(mctx, "30")) 442 } 443 } 444 if boardVndkVersion == "current" { 445 boardVndkVersion = platformVndkVersion 446 } 447 if productVndkVersion == "current" { 448 productVndkVersion = platformVndkVersion 449 } 450 451 if m.NeedsLlndkVariants() { 452 // This is an LLNDK library. The implementation of the library will be on /system, 453 // and vendor and product variants will be created with LLNDK stubs. 454 // The LLNDK libraries need vendor variants even if there is no VNDK. 455 coreVariantNeeded = true 456 if platformVndkVersion != "" { 457 vendorVariants = append(vendorVariants, platformVndkVersion) 458 productVariants = append(productVariants, platformVndkVersion) 459 } 460 // Generate vendor variants for boardVndkVersion only if the VNDK snapshot does not 461 // provide the LLNDK stub libraries. 462 if needVndkVersionVendorVariantForLlndk { 463 vendorVariants = append(vendorVariants, boardVndkVersion) 464 } 465 if productVndkVersion != "" { 466 productVariants = append(productVariants, productVndkVersion) 467 } 468 } else if m.NeedsVendorPublicLibraryVariants() { 469 // A vendor public library has the implementation on /vendor, with stub variants 470 // for system and product. 471 coreVariantNeeded = true 472 vendorVariants = append(vendorVariants, boardVndkVersion) 473 if platformVndkVersion != "" { 474 productVariants = append(productVariants, platformVndkVersion) 475 } 476 if productVndkVersion != "" { 477 productVariants = append(productVariants, productVndkVersion) 478 } 479 } else if boardVndkVersion == "" { 480 // If the device isn't compiling against the VNDK, we always 481 // use the core mode. 482 coreVariantNeeded = true 483 } else if m.IsSnapshotPrebuilt() { 484 // Make vendor variants only for the versions in BOARD_VNDK_VERSION and 485 // PRODUCT_EXTRA_VNDK_VERSIONS. 486 if m.InstallInRecovery() { 487 recoveryVariantNeeded = true 488 } else { 489 vendorVariants = append(vendorVariants, m.SnapshotVersion(mctx)) 490 } 491 } else if m.HasNonSystemVariants() && !m.IsVndkExt() { 492 // This will be available to /system unless it is product_specific 493 // which will be handled later. 494 coreVariantNeeded = true 495 496 // We assume that modules under proprietary paths are compatible for 497 // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or 498 // PLATFORM_VNDK_VERSION. 499 if m.HasVendorVariant() { 500 if snapshot.IsVendorProprietaryModule(mctx) { 501 vendorVariants = append(vendorVariants, boardVndkVersion) 502 } else { 503 vendorVariants = append(vendorVariants, platformVndkVersion) 504 } 505 } 506 507 // product_available modules are available to /product. 508 if m.HasProductVariant() { 509 productVariants = append(productVariants, platformVndkVersion) 510 // VNDK is always PLATFORM_VNDK_VERSION 511 if !m.IsVndk() { 512 productVariants = append(productVariants, productVndkVersion) 513 } 514 } 515 } else if vendorSpecific && m.SdkVersion() == "" { 516 // This will be available in /vendor (or /odm) only 517 518 // kernel_headers is a special module type whose exported headers 519 // are coming from DeviceKernelHeaders() which is always vendor 520 // dependent. They'll always have both vendor variants. 521 // For other modules, we assume that modules under proprietary 522 // paths are compatible for BOARD_VNDK_VERSION. The other modules 523 // are regarded as AOSP, which is PLATFORM_VNDK_VERSION. 524 if m.KernelHeadersDecorator() { 525 vendorVariants = append(vendorVariants, 526 platformVndkVersion, 527 boardVndkVersion, 528 ) 529 } else if snapshot.IsVendorProprietaryModule(mctx) { 530 vendorVariants = append(vendorVariants, boardVndkVersion) 531 } else { 532 vendorVariants = append(vendorVariants, platformVndkVersion) 533 } 534 } else { 535 // This is either in /system (or similar: /data), or is a 536 // modules built with the NDK. Modules built with the NDK 537 // will be restricted using the existing link type checks. 538 coreVariantNeeded = true 539 } 540 541 if boardVndkVersion != "" && productVndkVersion != "" { 542 if coreVariantNeeded && productSpecific && m.SdkVersion() == "" { 543 // The module has "product_specific: true" that does not create core variant. 544 coreVariantNeeded = false 545 productVariants = append(productVariants, productVndkVersion) 546 } 547 } else { 548 // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no 549 // restriction to use system libs. 550 // No product variants defined in this case. 551 productVariants = []string{} 552 } 553 554 if m.RamdiskAvailable() { 555 ramdiskVariantNeeded = true 556 } 557 558 if m.AndroidModuleBase().InstallInRamdisk() { 559 ramdiskVariantNeeded = true 560 coreVariantNeeded = false 561 } 562 563 if m.VendorRamdiskAvailable() { 564 vendorRamdiskVariantNeeded = true 565 } 566 567 if m.AndroidModuleBase().InstallInVendorRamdisk() { 568 vendorRamdiskVariantNeeded = true 569 coreVariantNeeded = false 570 } 571 572 if m.RecoveryAvailable() { 573 recoveryVariantNeeded = true 574 } 575 576 if m.AndroidModuleBase().InstallInRecovery() { 577 recoveryVariantNeeded = true 578 coreVariantNeeded = false 579 } 580 581 // If using a snapshot, the recovery variant under AOSP directories is not needed, 582 // except for kernel headers, which needs all variants. 583 if !m.KernelHeadersDecorator() && 584 !m.IsSnapshotPrebuilt() && 585 usingRecoverySnapshot && 586 !snapshot.IsRecoveryProprietaryModule(mctx) { 587 recoveryVariantNeeded = false 588 } 589 590 for _, variant := range android.FirstUniqueStrings(vendorVariants) { 591 m.AppendExtraVariant(VendorVariationPrefix + variant) 592 } 593 594 for _, variant := range android.FirstUniqueStrings(productVariants) { 595 m.AppendExtraVariant(ProductVariationPrefix + variant) 596 } 597 598 m.SetRamdiskVariantNeeded(ramdiskVariantNeeded) 599 m.SetVendorRamdiskVariantNeeded(vendorRamdiskVariantNeeded) 600 m.SetRecoveryVariantNeeded(recoveryVariantNeeded) 601 m.SetCoreVariantNeeded(coreVariantNeeded) 602 603 // Disable the module if no variants are needed. 604 if !ramdiskVariantNeeded && 605 !recoveryVariantNeeded && 606 !coreVariantNeeded && 607 len(m.ExtraVariants()) == 0 { 608 m.Disable() 609 } 610} 611 612func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 613 return c.Properties.CoreVariantNeeded 614} 615 616func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 617 return c.Properties.RamdiskVariantNeeded 618} 619 620func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 621 return c.Properties.VendorRamdiskVariantNeeded 622} 623 624func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 625 return false 626} 627 628func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { 629 return c.Properties.RecoveryVariantNeeded 630} 631 632func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string { 633 return c.Properties.ExtraVersionedImageVariations 634} 635 636func squashVendorSrcs(m *Module) { 637 if lib, ok := m.compiler.(*libraryDecorator); ok { 638 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, 639 lib.baseCompiler.Properties.Target.Vendor.Srcs...) 640 641 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, 642 lib.baseCompiler.Properties.Target.Vendor.Exclude_srcs...) 643 644 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, 645 lib.baseCompiler.Properties.Target.Vendor.Exclude_generated_sources...) 646 } 647} 648 649func squashProductSrcs(m *Module) { 650 if lib, ok := m.compiler.(*libraryDecorator); ok { 651 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, 652 lib.baseCompiler.Properties.Target.Product.Srcs...) 653 654 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, 655 lib.baseCompiler.Properties.Target.Product.Exclude_srcs...) 656 657 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, 658 lib.baseCompiler.Properties.Target.Product.Exclude_generated_sources...) 659 } 660} 661 662func squashRecoverySrcs(m *Module) { 663 if lib, ok := m.compiler.(*libraryDecorator); ok { 664 lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs, 665 lib.baseCompiler.Properties.Target.Recovery.Srcs...) 666 667 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, 668 lib.baseCompiler.Properties.Target.Recovery.Exclude_srcs...) 669 670 lib.baseCompiler.Properties.Exclude_generated_sources = append(lib.baseCompiler.Properties.Exclude_generated_sources, 671 lib.baseCompiler.Properties.Target.Recovery.Exclude_generated_sources...) 672 } 673} 674 675func squashVendorRamdiskSrcs(m *Module) { 676 if lib, ok := m.compiler.(*libraryDecorator); ok { 677 lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...) 678 } 679} 680 681func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { 682 m := module.(*Module) 683 if variant == android.RamdiskVariation { 684 m.MakeAsPlatform() 685 } else if variant == android.VendorRamdiskVariation { 686 m.MakeAsPlatform() 687 squashVendorRamdiskSrcs(m) 688 } else if variant == android.RecoveryVariation { 689 m.MakeAsPlatform() 690 squashRecoverySrcs(m) 691 } else if strings.HasPrefix(variant, VendorVariationPrefix) { 692 m.Properties.ImageVariationPrefix = VendorVariationPrefix 693 m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix) 694 squashVendorSrcs(m) 695 696 // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION. 697 // Hide other vendor variants to avoid collision. 698 vndkVersion := ctx.DeviceConfig().VndkVersion() 699 if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion { 700 m.Properties.HideFromMake = true 701 m.HideFromMake() 702 } 703 } else if strings.HasPrefix(variant, ProductVariationPrefix) { 704 m.Properties.ImageVariationPrefix = ProductVariationPrefix 705 m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix) 706 squashProductSrcs(m) 707 } 708 709 if c.NeedsVendorPublicLibraryVariants() && 710 (variant == android.CoreVariation || strings.HasPrefix(variant, ProductVariationPrefix)) { 711 c.VendorProperties.IsVendorPublicLibrary = true 712 } 713} 714