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 defines snapshot prebuilt modules, e.g. vendor snapshot and recovery snapshot. Such 17// snapshot modules will override original source modules with setting BOARD_VNDK_VERSION, with 18// snapshot mutators and snapshot information maps which are also defined in this file. 19 20import ( 21 "path/filepath" 22 "strings" 23 24 "android/soong/android" 25 26 "github.com/google/blueprint" 27) 28 29// Defines the specifics of different images to which the snapshot process is applicable, e.g., 30// vendor, recovery, ramdisk. 31type snapshotImage interface { 32 // Returns true if a snapshot should be generated for this image. 33 shouldGenerateSnapshot(ctx android.SingletonContext) bool 34 35 // Function that returns true if the module is included in this image. 36 // Using a function return instead of a value to prevent early 37 // evalution of a function that may be not be defined. 38 inImage(m LinkableInterface) func() bool 39 40 // Returns true if the module is private and must not be included in the 41 // snapshot. For example VNDK-private modules must return true for the 42 // vendor snapshots. But false for the recovery snapshots. 43 private(m LinkableInterface) bool 44 45 // Returns true if a dir under source tree is an SoC-owned proprietary 46 // directory, such as device/, vendor/, etc. 47 // 48 // For a given snapshot (e.g., vendor, recovery, etc.) if 49 // isProprietaryPath(dir, deviceConfig) returns true, then the module in dir 50 // will be built from sources. 51 isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool 52 53 // Whether to include VNDK in the snapshot for this image. 54 includeVndk() bool 55 56 // Whether a given module has been explicitly excluded from the 57 // snapshot, e.g., using the exclude_from_vendor_snapshot or 58 // exclude_from_recovery_snapshot properties. 59 excludeFromSnapshot(m LinkableInterface) bool 60 61 // Returns true if the build is using a snapshot for this image. 62 isUsingSnapshot(cfg android.DeviceConfig) bool 63 64 // Returns a version of which the snapshot should be used in this target. 65 // This will only be meaningful when isUsingSnapshot is true. 66 targetSnapshotVersion(cfg android.DeviceConfig) string 67 68 // Whether to exclude a given module from the directed snapshot or not. 69 // If the makefile variable DIRECTED_{IMAGE}_SNAPSHOT is true, directed snapshot is turned on, 70 // and only modules listed in {IMAGE}_SNAPSHOT_MODULES will be captured. 71 excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool 72 73 // The image variant name for this snapshot image. 74 // For example, recovery snapshot image will return "recovery", and vendor snapshot image will 75 // return "vendor." + version. 76 imageVariantName(cfg android.DeviceConfig) string 77 78 // The variant suffix for snapshot modules. For example, vendor snapshot modules will have 79 // ".vendor" as their suffix. 80 moduleNameSuffix() string 81} 82 83type vendorSnapshotImage struct{} 84type recoverySnapshotImage struct{} 85 86type directoryMap map[string]bool 87 88var ( 89 // Modules under following directories are ignored. They are OEM's and vendor's 90 // proprietary modules(device/, kernel/, vendor/, and hardware/). 91 defaultDirectoryExcludedMap = directoryMap{ 92 "device": true, 93 "hardware": true, 94 "kernel": true, 95 "vendor": true, 96 } 97 98 // Modules under following directories are included as they are in AOSP, 99 // although hardware/ and kernel/ are normally for vendor's own. 100 defaultDirectoryIncludedMap = directoryMap{ 101 "kernel/configs": true, 102 "kernel/prebuilts": true, 103 "kernel/tests": true, 104 "hardware/interfaces": true, 105 "hardware/libhardware": true, 106 "hardware/libhardware_legacy": true, 107 "hardware/ril": true, 108 } 109) 110 111func (vendorSnapshotImage) init(ctx android.RegistrationContext) { 112 ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) 113 ctx.RegisterModuleType("vendor_snapshot", vendorSnapshotFactory) 114 ctx.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) 115 ctx.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) 116 ctx.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) 117 ctx.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) 118 ctx.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) 119 120 ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton) 121} 122 123func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { 124 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a snapshot. 125 return ctx.DeviceConfig().VndkVersion() == "current" 126} 127 128func (vendorSnapshotImage) inImage(m LinkableInterface) func() bool { 129 return m.InVendor 130} 131 132func (vendorSnapshotImage) private(m LinkableInterface) bool { 133 return m.IsVndkPrivate() 134} 135 136func isDirectoryExcluded(dir string, excludedMap directoryMap, includedMap directoryMap) bool { 137 if dir == "." || dir == "/" { 138 return false 139 } 140 if includedMap[dir] { 141 return false 142 } else if excludedMap[dir] { 143 return true 144 } else if defaultDirectoryIncludedMap[dir] { 145 return false 146 } else if defaultDirectoryExcludedMap[dir] { 147 return true 148 } else { 149 return isDirectoryExcluded(filepath.Dir(dir), excludedMap, includedMap) 150 } 151} 152 153func (vendorSnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { 154 return isDirectoryExcluded(dir, deviceConfig.VendorSnapshotDirsExcludedMap(), deviceConfig.VendorSnapshotDirsIncludedMap()) 155} 156 157// vendor snapshot includes static/header libraries with vndk: {enabled: true}. 158func (vendorSnapshotImage) includeVndk() bool { 159 return true 160} 161 162func (vendorSnapshotImage) excludeFromSnapshot(m LinkableInterface) bool { 163 return m.ExcludeFromVendorSnapshot() 164} 165 166func (vendorSnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool { 167 vndkVersion := cfg.VndkVersion() 168 return vndkVersion != "current" && vndkVersion != "" 169} 170 171func (vendorSnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string { 172 return cfg.VndkVersion() 173} 174 175// returns true iff a given module SHOULD BE EXCLUDED, false if included 176func (vendorSnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { 177 // If we're using full snapshot, not directed snapshot, capture every module 178 if !cfg.DirectedVendorSnapshot() { 179 return false 180 } 181 // Else, checks if name is in VENDOR_SNAPSHOT_MODULES. 182 return !cfg.VendorSnapshotModules()[name] 183} 184 185func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string { 186 return VendorVariationPrefix + cfg.VndkVersion() 187} 188 189func (vendorSnapshotImage) moduleNameSuffix() string { 190 return VendorSuffix 191} 192 193func (recoverySnapshotImage) init(ctx android.RegistrationContext) { 194 ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton) 195 ctx.RegisterModuleType("recovery_snapshot", recoverySnapshotFactory) 196 ctx.RegisterModuleType("recovery_snapshot_shared", RecoverySnapshotSharedFactory) 197 ctx.RegisterModuleType("recovery_snapshot_static", RecoverySnapshotStaticFactory) 198 ctx.RegisterModuleType("recovery_snapshot_header", RecoverySnapshotHeaderFactory) 199 ctx.RegisterModuleType("recovery_snapshot_binary", RecoverySnapshotBinaryFactory) 200 ctx.RegisterModuleType("recovery_snapshot_object", RecoverySnapshotObjectFactory) 201} 202 203func (recoverySnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool { 204 // RECOVERY_SNAPSHOT_VERSION must be set to 'current' in order to generate a 205 // snapshot. 206 return ctx.DeviceConfig().RecoverySnapshotVersion() == "current" 207} 208 209func (recoverySnapshotImage) inImage(m LinkableInterface) func() bool { 210 return m.InRecovery 211} 212 213// recovery snapshot does not have private libraries. 214func (recoverySnapshotImage) private(m LinkableInterface) bool { 215 return false 216} 217 218func (recoverySnapshotImage) isProprietaryPath(dir string, deviceConfig android.DeviceConfig) bool { 219 return isDirectoryExcluded(dir, deviceConfig.RecoverySnapshotDirsExcludedMap(), deviceConfig.RecoverySnapshotDirsIncludedMap()) 220} 221 222// recovery snapshot does NOT treat vndk specially. 223func (recoverySnapshotImage) includeVndk() bool { 224 return false 225} 226 227func (recoverySnapshotImage) excludeFromSnapshot(m LinkableInterface) bool { 228 return m.ExcludeFromRecoverySnapshot() 229} 230 231func (recoverySnapshotImage) isUsingSnapshot(cfg android.DeviceConfig) bool { 232 recoverySnapshotVersion := cfg.RecoverySnapshotVersion() 233 return recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" 234} 235 236func (recoverySnapshotImage) targetSnapshotVersion(cfg android.DeviceConfig) string { 237 return cfg.RecoverySnapshotVersion() 238} 239 240func (recoverySnapshotImage) excludeFromDirectedSnapshot(cfg android.DeviceConfig, name string) bool { 241 // If we're using full snapshot, not directed snapshot, capture every module 242 if !cfg.DirectedRecoverySnapshot() { 243 return false 244 } 245 // Else, checks if name is in RECOVERY_SNAPSHOT_MODULES. 246 return !cfg.RecoverySnapshotModules()[name] 247} 248 249func (recoverySnapshotImage) imageVariantName(cfg android.DeviceConfig) string { 250 return android.RecoveryVariation 251} 252 253func (recoverySnapshotImage) moduleNameSuffix() string { 254 return recoverySuffix 255} 256 257var vendorSnapshotImageSingleton vendorSnapshotImage 258var recoverySnapshotImageSingleton recoverySnapshotImage 259 260func init() { 261 vendorSnapshotImageSingleton.init(android.InitRegistrationContext) 262 recoverySnapshotImageSingleton.init(android.InitRegistrationContext) 263} 264 265const ( 266 snapshotHeaderSuffix = "_header." 267 snapshotSharedSuffix = "_shared." 268 snapshotStaticSuffix = "_static." 269 snapshotBinarySuffix = "_binary." 270 snapshotObjectSuffix = "_object." 271) 272 273type SnapshotProperties struct { 274 Header_libs []string `android:"arch_variant"` 275 Static_libs []string `android:"arch_variant"` 276 Shared_libs []string `android:"arch_variant"` 277 Vndk_libs []string `android:"arch_variant"` 278 Binaries []string `android:"arch_variant"` 279 Objects []string `android:"arch_variant"` 280} 281 282type snapshot struct { 283 android.ModuleBase 284 285 properties SnapshotProperties 286 287 baseSnapshot baseSnapshotDecorator 288 289 image snapshotImage 290} 291 292func (s *snapshot) ImageMutatorBegin(ctx android.BaseModuleContext) { 293 cfg := ctx.DeviceConfig() 294 if !s.image.isUsingSnapshot(cfg) || s.image.targetSnapshotVersion(cfg) != s.baseSnapshot.version() { 295 s.Disable() 296 } 297} 298 299func (s *snapshot) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 300 return false 301} 302 303func (s *snapshot) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 304 return false 305} 306 307func (s *snapshot) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 308 return false 309} 310 311func (s *snapshot) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { 312 return false 313} 314 315func (s *snapshot) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { 316 return false 317} 318 319func (s *snapshot) ExtraImageVariations(ctx android.BaseModuleContext) []string { 320 return []string{s.image.imageVariantName(ctx.DeviceConfig())} 321} 322 323func (s *snapshot) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { 324} 325 326func (s *snapshot) GenerateAndroidBuildActions(ctx android.ModuleContext) { 327 // Nothing, the snapshot module is only used to forward dependency information in DepsMutator. 328} 329 330func getSnapshotNameSuffix(moduleSuffix, version, arch string) string { 331 versionSuffix := version 332 if arch != "" { 333 versionSuffix += "." + arch 334 } 335 return moduleSuffix + versionSuffix 336} 337 338func (s *snapshot) DepsMutator(ctx android.BottomUpMutatorContext) { 339 collectSnapshotMap := func(names []string, snapshotSuffix, moduleSuffix string) map[string]string { 340 snapshotMap := make(map[string]string) 341 for _, name := range names { 342 snapshotMap[name] = name + 343 getSnapshotNameSuffix(snapshotSuffix+moduleSuffix, 344 s.baseSnapshot.version(), 345 ctx.DeviceConfig().Arches()[0].ArchType.String()) 346 } 347 return snapshotMap 348 } 349 350 snapshotSuffix := s.image.moduleNameSuffix() 351 headers := collectSnapshotMap(s.properties.Header_libs, snapshotSuffix, snapshotHeaderSuffix) 352 binaries := collectSnapshotMap(s.properties.Binaries, snapshotSuffix, snapshotBinarySuffix) 353 objects := collectSnapshotMap(s.properties.Objects, snapshotSuffix, snapshotObjectSuffix) 354 staticLibs := collectSnapshotMap(s.properties.Static_libs, snapshotSuffix, snapshotStaticSuffix) 355 sharedLibs := collectSnapshotMap(s.properties.Shared_libs, snapshotSuffix, snapshotSharedSuffix) 356 vndkLibs := collectSnapshotMap(s.properties.Vndk_libs, "", vndkSuffix) 357 for k, v := range vndkLibs { 358 sharedLibs[k] = v 359 } 360 361 ctx.SetProvider(SnapshotInfoProvider, SnapshotInfo{ 362 HeaderLibs: headers, 363 Binaries: binaries, 364 Objects: objects, 365 StaticLibs: staticLibs, 366 SharedLibs: sharedLibs, 367 }) 368} 369 370type SnapshotInfo struct { 371 HeaderLibs, Binaries, Objects, StaticLibs, SharedLibs map[string]string 372} 373 374var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps") 375 376var _ android.ImageInterface = (*snapshot)(nil) 377 378func vendorSnapshotFactory() android.Module { 379 return snapshotFactory(vendorSnapshotImageSingleton) 380} 381 382func recoverySnapshotFactory() android.Module { 383 return snapshotFactory(recoverySnapshotImageSingleton) 384} 385 386func snapshotFactory(image snapshotImage) android.Module { 387 snapshot := &snapshot{} 388 snapshot.image = image 389 snapshot.AddProperties( 390 &snapshot.properties, 391 &snapshot.baseSnapshot.baseProperties) 392 android.InitAndroidArchModule(snapshot, android.DeviceSupported, android.MultilibBoth) 393 return snapshot 394} 395 396type baseSnapshotDecoratorProperties struct { 397 // snapshot version. 398 Version string 399 400 // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64') 401 Target_arch string 402 403 // Suffix to be added to the module name when exporting to Android.mk, e.g. ".vendor". 404 Androidmk_suffix string `blueprint:"mutated"` 405 406 // Suffix to be added to the module name, e.g., vendor_shared, 407 // recovery_shared, etc. 408 ModuleSuffix string `blueprint:"mutated"` 409} 410 411// baseSnapshotDecorator provides common basic functions for all snapshot modules, such as snapshot 412// version, snapshot arch, etc. It also adds a special suffix to Soong module name, so it doesn't 413// collide with source modules. e.g. the following example module, 414// 415// vendor_snapshot_static { 416// name: "libbase", 417// arch: "arm64", 418// version: 30, 419// ... 420// } 421// 422// will be seen as "libbase.vendor_static.30.arm64" by Soong. 423type baseSnapshotDecorator struct { 424 baseProperties baseSnapshotDecoratorProperties 425 image snapshotImage 426} 427 428func (p *baseSnapshotDecorator) Name(name string) string { 429 return name + p.NameSuffix() 430} 431 432func (p *baseSnapshotDecorator) NameSuffix() string { 433 return getSnapshotNameSuffix(p.moduleSuffix(), p.version(), p.arch()) 434} 435 436func (p *baseSnapshotDecorator) version() string { 437 return p.baseProperties.Version 438} 439 440func (p *baseSnapshotDecorator) arch() string { 441 return p.baseProperties.Target_arch 442} 443 444func (p *baseSnapshotDecorator) moduleSuffix() string { 445 return p.baseProperties.ModuleSuffix 446} 447 448func (p *baseSnapshotDecorator) isSnapshotPrebuilt() bool { 449 return true 450} 451 452func (p *baseSnapshotDecorator) snapshotAndroidMkSuffix() string { 453 return p.baseProperties.Androidmk_suffix 454} 455 456func (p *baseSnapshotDecorator) setSnapshotAndroidMkSuffix(ctx android.ModuleContext) { 457 coreVariations := append(ctx.Target().Variations(), blueprint.Variation{ 458 Mutator: "image", 459 Variation: android.CoreVariation}) 460 461 if ctx.OtherModuleFarDependencyVariantExists(coreVariations, ctx.Module().(*Module).BaseModuleName()) { 462 p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix() 463 return 464 } 465 466 // If there is no matching core variation, there could still be a 467 // product variation, for example if a module is product specific and 468 // vendor available. In that case, we also want to add the androidmk 469 // suffix. 470 471 productVariations := append(ctx.Target().Variations(), blueprint.Variation{ 472 Mutator: "image", 473 Variation: ProductVariationPrefix + ctx.DeviceConfig().PlatformVndkVersion()}) 474 475 if ctx.OtherModuleFarDependencyVariantExists(productVariations, ctx.Module().(*Module).BaseModuleName()) { 476 p.baseProperties.Androidmk_suffix = p.image.moduleNameSuffix() 477 return 478 } 479 480 p.baseProperties.Androidmk_suffix = "" 481} 482 483// Call this with a module suffix after creating a snapshot module, such as 484// vendorSnapshotSharedSuffix, recoverySnapshotBinarySuffix, etc. 485func (p *baseSnapshotDecorator) init(m *Module, image snapshotImage, moduleSuffix string) { 486 p.image = image 487 p.baseProperties.ModuleSuffix = image.moduleNameSuffix() + moduleSuffix 488 m.AddProperties(&p.baseProperties) 489 android.AddLoadHook(m, func(ctx android.LoadHookContext) { 490 vendorSnapshotLoadHook(ctx, p) 491 }) 492} 493 494// vendorSnapshotLoadHook disables snapshots if it's not BOARD_VNDK_VERSION. 495// As vendor snapshot is only for vendor, such modules won't be used at all. 496func vendorSnapshotLoadHook(ctx android.LoadHookContext, p *baseSnapshotDecorator) { 497 if p.version() != ctx.DeviceConfig().VndkVersion() { 498 ctx.Module().Disable() 499 return 500 } 501} 502 503// 504// Module definitions for snapshots of libraries (shared, static, header). 505// 506// Modules (vendor|recovery)_snapshot_(shared|static|header) are defined here. Shared libraries and 507// static libraries have their prebuilt library files (.so for shared, .a for static) as their src, 508// which can be installed or linked against. Also they export flags needed when linked, such as 509// include directories, c flags, sanitize dependency information, etc. 510// 511// These modules are auto-generated by development/vendor_snapshot/update.py. 512type snapshotLibraryProperties struct { 513 // Prebuilt file for each arch. 514 Src *string `android:"arch_variant"` 515 516 // list of directories that will be added to the include path (using -I). 517 Export_include_dirs []string `android:"arch_variant"` 518 519 // list of directories that will be added to the system path (using -isystem). 520 Export_system_include_dirs []string `android:"arch_variant"` 521 522 // list of flags that will be used for any module that links against this module. 523 Export_flags []string `android:"arch_variant"` 524 525 // Whether this prebuilt needs to depend on sanitize ubsan runtime or not. 526 Sanitize_ubsan_dep *bool `android:"arch_variant"` 527 528 // Whether this prebuilt needs to depend on sanitize minimal runtime or not. 529 Sanitize_minimal_dep *bool `android:"arch_variant"` 530} 531 532type snapshotSanitizer interface { 533 isSanitizerEnabled(t SanitizerType) bool 534 setSanitizerVariation(t SanitizerType, enabled bool) 535} 536 537type snapshotLibraryDecorator struct { 538 baseSnapshotDecorator 539 *libraryDecorator 540 properties snapshotLibraryProperties 541 sanitizerProperties struct { 542 CfiEnabled bool `blueprint:"mutated"` 543 544 // Library flags for cfi variant. 545 Cfi snapshotLibraryProperties `android:"arch_variant"` 546 } 547} 548 549func (p *snapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { 550 p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix()) 551 return p.libraryDecorator.linkerFlags(ctx, flags) 552} 553 554func (p *snapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool { 555 arches := config.Arches() 556 if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { 557 return false 558 } 559 if !p.header() && p.properties.Src == nil { 560 return false 561 } 562 return true 563} 564 565// cc modules' link functions are to link compiled objects into final binaries. 566// As snapshots are prebuilts, this just returns the prebuilt binary after doing things which are 567// done by normal library decorator, e.g. exporting flags. 568func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { 569 p.setSnapshotAndroidMkSuffix(ctx) 570 571 if p.header() { 572 return p.libraryDecorator.link(ctx, flags, deps, objs) 573 } 574 575 if p.sanitizerProperties.CfiEnabled { 576 p.properties = p.sanitizerProperties.Cfi 577 } 578 579 if !p.matchesWithDevice(ctx.DeviceConfig()) { 580 return nil 581 } 582 583 // Flags specified directly to this module. 584 p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...) 585 p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...) 586 p.libraryDecorator.reexportFlags(p.properties.Export_flags...) 587 588 // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared) 589 p.libraryDecorator.reexportDirs(deps.ReexportedDirs...) 590 p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...) 591 p.libraryDecorator.reexportFlags(deps.ReexportedFlags...) 592 p.libraryDecorator.reexportDeps(deps.ReexportedDeps...) 593 p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) 594 595 in := android.PathForModuleSrc(ctx, *p.properties.Src) 596 p.unstrippedOutputFile = in 597 598 if p.shared() { 599 libName := in.Base() 600 builderFlags := flagsToBuilderFlags(flags) 601 602 // Optimize out relinking against shared libraries whose interface hasn't changed by 603 // depending on a table of contents file instead of the library itself. 604 tocFile := android.PathForModuleOut(ctx, libName+".toc") 605 p.tocFile = android.OptionalPathForPath(tocFile) 606 transformSharedObjectToToc(ctx, in, tocFile, builderFlags) 607 608 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ 609 SharedLibrary: in, 610 UnstrippedSharedLibrary: p.unstrippedOutputFile, 611 Target: ctx.Target(), 612 613 TableOfContents: p.tocFile, 614 }) 615 } 616 617 if p.static() { 618 depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build() 619 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{ 620 StaticLibrary: in, 621 622 TransitiveStaticLibrariesForOrdering: depSet, 623 }) 624 } 625 626 p.libraryDecorator.flagExporter.setProvider(ctx) 627 628 return in 629} 630 631func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) { 632 if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) { 633 p.baseInstaller.install(ctx, file) 634 } 635} 636 637func (p *snapshotLibraryDecorator) nativeCoverage() bool { 638 return false 639} 640 641func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool { 642 switch t { 643 case cfi: 644 return p.sanitizerProperties.Cfi.Src != nil 645 default: 646 return false 647 } 648} 649 650func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enabled bool) { 651 if !enabled { 652 return 653 } 654 switch t { 655 case cfi: 656 p.sanitizerProperties.CfiEnabled = true 657 default: 658 return 659 } 660} 661 662func snapshotLibraryFactory(image snapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) { 663 module, library := NewLibrary(android.DeviceSupported) 664 665 module.stl = nil 666 module.sanitize = nil 667 library.disableStripping() 668 669 prebuilt := &snapshotLibraryDecorator{ 670 libraryDecorator: library, 671 } 672 673 prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true) 674 prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true) 675 676 // Prevent default system libs (libc, libm, and libdl) from being linked 677 if prebuilt.baseLinker.Properties.System_shared_libs == nil { 678 prebuilt.baseLinker.Properties.System_shared_libs = []string{} 679 } 680 681 module.compiler = nil 682 module.linker = prebuilt 683 module.installer = prebuilt 684 685 prebuilt.init(module, image, moduleSuffix) 686 module.AddProperties( 687 &prebuilt.properties, 688 &prebuilt.sanitizerProperties, 689 ) 690 691 return module, prebuilt 692} 693 694// vendor_snapshot_shared is a special prebuilt shared library which is auto-generated by 695// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_shared 696// overrides the vendor variant of the cc shared library with the same name, if BOARD_VNDK_VERSION 697// is set. 698func VendorSnapshotSharedFactory() android.Module { 699 module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotSharedSuffix) 700 prebuilt.libraryDecorator.BuildOnlyShared() 701 return module.Init() 702} 703 704// recovery_snapshot_shared is a special prebuilt shared library which is auto-generated by 705// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_shared 706// overrides the recovery variant of the cc shared library with the same name, if BOARD_VNDK_VERSION 707// is set. 708func RecoverySnapshotSharedFactory() android.Module { 709 module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotSharedSuffix) 710 prebuilt.libraryDecorator.BuildOnlyShared() 711 return module.Init() 712} 713 714// vendor_snapshot_static is a special prebuilt static library which is auto-generated by 715// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_static 716// overrides the vendor variant of the cc static library with the same name, if BOARD_VNDK_VERSION 717// is set. 718func VendorSnapshotStaticFactory() android.Module { 719 module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotStaticSuffix) 720 prebuilt.libraryDecorator.BuildOnlyStatic() 721 return module.Init() 722} 723 724// recovery_snapshot_static is a special prebuilt static library which is auto-generated by 725// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_static 726// overrides the recovery variant of the cc static library with the same name, if BOARD_VNDK_VERSION 727// is set. 728func RecoverySnapshotStaticFactory() android.Module { 729 module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotStaticSuffix) 730 prebuilt.libraryDecorator.BuildOnlyStatic() 731 return module.Init() 732} 733 734// vendor_snapshot_header is a special header library which is auto-generated by 735// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_header 736// overrides the vendor variant of the cc header library with the same name, if BOARD_VNDK_VERSION 737// is set. 738func VendorSnapshotHeaderFactory() android.Module { 739 module, prebuilt := snapshotLibraryFactory(vendorSnapshotImageSingleton, snapshotHeaderSuffix) 740 prebuilt.libraryDecorator.HeaderOnly() 741 return module.Init() 742} 743 744// recovery_snapshot_header is a special header library which is auto-generated by 745// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_header 746// overrides the recovery variant of the cc header library with the same name, if BOARD_VNDK_VERSION 747// is set. 748func RecoverySnapshotHeaderFactory() android.Module { 749 module, prebuilt := snapshotLibraryFactory(recoverySnapshotImageSingleton, snapshotHeaderSuffix) 750 prebuilt.libraryDecorator.HeaderOnly() 751 return module.Init() 752} 753 754var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil) 755 756// 757// Module definitions for snapshots of executable binaries. 758// 759// Modules (vendor|recovery)_snapshot_binary are defined here. They have their prebuilt executable 760// binaries (e.g. toybox, sh) as their src, which can be installed. 761// 762// These modules are auto-generated by development/vendor_snapshot/update.py. 763type snapshotBinaryProperties struct { 764 // Prebuilt file for each arch. 765 Src *string `android:"arch_variant"` 766} 767 768type snapshotBinaryDecorator struct { 769 baseSnapshotDecorator 770 *binaryDecorator 771 properties snapshotBinaryProperties 772} 773 774func (p *snapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool { 775 if config.DeviceArch() != p.arch() { 776 return false 777 } 778 if p.properties.Src == nil { 779 return false 780 } 781 return true 782} 783 784// cc modules' link functions are to link compiled objects into final binaries. 785// As snapshots are prebuilts, this just returns the prebuilt binary 786func (p *snapshotBinaryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { 787 p.setSnapshotAndroidMkSuffix(ctx) 788 789 if !p.matchesWithDevice(ctx.DeviceConfig()) { 790 return nil 791 } 792 793 in := android.PathForModuleSrc(ctx, *p.properties.Src) 794 p.unstrippedOutputFile = in 795 binName := in.Base() 796 797 // use cpExecutable to make it executable 798 outputFile := android.PathForModuleOut(ctx, binName) 799 ctx.Build(pctx, android.BuildParams{ 800 Rule: android.CpExecutable, 801 Description: "prebuilt", 802 Output: outputFile, 803 Input: in, 804 }) 805 806 return outputFile 807} 808 809func (p *snapshotBinaryDecorator) nativeCoverage() bool { 810 return false 811} 812 813// vendor_snapshot_binary is a special prebuilt executable binary which is auto-generated by 814// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_binary 815// overrides the vendor variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set. 816func VendorSnapshotBinaryFactory() android.Module { 817 return snapshotBinaryFactory(vendorSnapshotImageSingleton, snapshotBinarySuffix) 818} 819 820// recovery_snapshot_binary is a special prebuilt executable binary which is auto-generated by 821// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_binary 822// overrides the recovery variant of the cc binary with the same name, if BOARD_VNDK_VERSION is set. 823func RecoverySnapshotBinaryFactory() android.Module { 824 return snapshotBinaryFactory(recoverySnapshotImageSingleton, snapshotBinarySuffix) 825} 826 827func snapshotBinaryFactory(image snapshotImage, moduleSuffix string) android.Module { 828 module, binary := NewBinary(android.DeviceSupported) 829 binary.baseLinker.Properties.No_libcrt = BoolPtr(true) 830 binary.baseLinker.Properties.Nocrt = BoolPtr(true) 831 832 // Prevent default system libs (libc, libm, and libdl) from being linked 833 if binary.baseLinker.Properties.System_shared_libs == nil { 834 binary.baseLinker.Properties.System_shared_libs = []string{} 835 } 836 837 prebuilt := &snapshotBinaryDecorator{ 838 binaryDecorator: binary, 839 } 840 841 module.compiler = nil 842 module.sanitize = nil 843 module.stl = nil 844 module.linker = prebuilt 845 846 prebuilt.init(module, image, moduleSuffix) 847 module.AddProperties(&prebuilt.properties) 848 return module.Init() 849} 850 851// 852// Module definitions for snapshots of object files (*.o). 853// 854// Modules (vendor|recovery)_snapshot_object are defined here. They have their prebuilt object 855// files (*.o) as their src. 856// 857// These modules are auto-generated by development/vendor_snapshot/update.py. 858type vendorSnapshotObjectProperties struct { 859 // Prebuilt file for each arch. 860 Src *string `android:"arch_variant"` 861} 862 863type snapshotObjectLinker struct { 864 baseSnapshotDecorator 865 objectLinker 866 properties vendorSnapshotObjectProperties 867} 868 869func (p *snapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool { 870 if config.DeviceArch() != p.arch() { 871 return false 872 } 873 if p.properties.Src == nil { 874 return false 875 } 876 return true 877} 878 879// cc modules' link functions are to link compiled objects into final binaries. 880// As snapshots are prebuilts, this just returns the prebuilt binary 881func (p *snapshotObjectLinker) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { 882 p.setSnapshotAndroidMkSuffix(ctx) 883 884 if !p.matchesWithDevice(ctx.DeviceConfig()) { 885 return nil 886 } 887 888 return android.PathForModuleSrc(ctx, *p.properties.Src) 889} 890 891func (p *snapshotObjectLinker) nativeCoverage() bool { 892 return false 893} 894 895// vendor_snapshot_object is a special prebuilt compiled object file which is auto-generated by 896// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_object 897// overrides the vendor variant of the cc object with the same name, if BOARD_VNDK_VERSION is set. 898func VendorSnapshotObjectFactory() android.Module { 899 module := newObject() 900 901 prebuilt := &snapshotObjectLinker{ 902 objectLinker: objectLinker{ 903 baseLinker: NewBaseLinker(nil), 904 }, 905 } 906 module.linker = prebuilt 907 908 prebuilt.init(module, vendorSnapshotImageSingleton, snapshotObjectSuffix) 909 module.AddProperties(&prebuilt.properties) 910 return module.Init() 911} 912 913// recovery_snapshot_object is a special prebuilt compiled object file which is auto-generated by 914// development/vendor_snapshot/update.py. As a part of recovery snapshot, recovery_snapshot_object 915// overrides the recovery variant of the cc object with the same name, if BOARD_VNDK_VERSION is set. 916func RecoverySnapshotObjectFactory() android.Module { 917 module := newObject() 918 919 prebuilt := &snapshotObjectLinker{ 920 objectLinker: objectLinker{ 921 baseLinker: NewBaseLinker(nil), 922 }, 923 } 924 module.linker = prebuilt 925 926 prebuilt.init(module, recoverySnapshotImageSingleton, snapshotObjectSuffix) 927 module.AddProperties(&prebuilt.properties) 928 return module.Init() 929} 930 931type snapshotInterface interface { 932 matchesWithDevice(config android.DeviceConfig) bool 933 isSnapshotPrebuilt() bool 934 version() string 935 snapshotAndroidMkSuffix() string 936} 937 938var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil) 939var _ snapshotInterface = (*snapshotLibraryDecorator)(nil) 940var _ snapshotInterface = (*snapshotBinaryDecorator)(nil) 941var _ snapshotInterface = (*snapshotObjectLinker)(nil) 942