1// Copyright 2019 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package rust 16 17import ( 18 "fmt" 19 "strings" 20 21 "github.com/google/blueprint" 22 "github.com/google/blueprint/proptools" 23 24 "android/soong/android" 25 "android/soong/bloaty" 26 "android/soong/cc" 27 cc_config "android/soong/cc/config" 28 "android/soong/fuzz" 29 "android/soong/rust/config" 30 "android/soong/snapshot" 31) 32 33var pctx = android.NewPackageContext("android/soong/rust") 34 35func init() { 36 // Only allow rust modules to be defined for certain projects 37 38 android.AddNeverAllowRules( 39 android.NeverAllow(). 40 NotIn(append(config.RustAllowedPaths, config.DownstreamRustAllowedPaths...)...). 41 ModuleType(config.RustModuleTypes...)) 42 43 android.RegisterModuleType("rust_defaults", defaultsFactory) 44 android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { 45 ctx.BottomUp("rust_libraries", LibraryMutator).Parallel() 46 ctx.BottomUp("rust_stdlinkage", LibstdMutator).Parallel() 47 ctx.BottomUp("rust_begin", BeginMutator).Parallel() 48 49 }) 50 android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) { 51 ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel() 52 }) 53 pctx.Import("android/soong/rust/config") 54 pctx.ImportAs("cc_config", "android/soong/cc/config") 55} 56 57type Flags struct { 58 GlobalRustFlags []string // Flags that apply globally to rust 59 GlobalLinkFlags []string // Flags that apply globally to linker 60 RustFlags []string // Flags that apply to rust 61 LinkFlags []string // Flags that apply to linker 62 ClippyFlags []string // Flags that apply to clippy-driver, during the linting 63 RustdocFlags []string // Flags that apply to rustdoc 64 Toolchain config.Toolchain 65 Coverage bool 66 Clippy bool 67} 68 69type BaseProperties struct { 70 AndroidMkRlibs []string 71 AndroidMkDylibs []string 72 AndroidMkProcMacroLibs []string 73 AndroidMkSharedLibs []string 74 AndroidMkStaticLibs []string 75 76 ImageVariationPrefix string `blueprint:"mutated"` 77 VndkVersion string `blueprint:"mutated"` 78 SubName string `blueprint:"mutated"` 79 80 // SubName is used by CC for tracking image variants / SDK versions. RustSubName is used for Rust-specific 81 // subnaming which shouldn't be visible to CC modules (such as the rlib stdlinkage subname). This should be 82 // appended before SubName. 83 RustSubName string `blueprint:"mutated"` 84 85 // Set by imageMutator 86 CoreVariantNeeded bool `blueprint:"mutated"` 87 VendorRamdiskVariantNeeded bool `blueprint:"mutated"` 88 RamdiskVariantNeeded bool `blueprint:"mutated"` 89 RecoveryVariantNeeded bool `blueprint:"mutated"` 90 ExtraVariants []string `blueprint:"mutated"` 91 92 // Allows this module to use non-APEX version of libraries. Useful 93 // for building binaries that are started before APEXes are activated. 94 Bootstrap *bool 95 96 // Used by vendor snapshot to record dependencies from snapshot modules. 97 SnapshotSharedLibs []string `blueprint:"mutated"` 98 SnapshotStaticLibs []string `blueprint:"mutated"` 99 100 // Make this module available when building for ramdisk. 101 // On device without a dedicated recovery partition, the module is only 102 // available after switching root into 103 // /first_stage_ramdisk. To expose the module before switching root, install 104 // the recovery variant instead. 105 Ramdisk_available *bool 106 107 // Make this module available when building for vendor ramdisk. 108 // On device without a dedicated recovery partition, the module is only 109 // available after switching root into 110 // /first_stage_ramdisk. To expose the module before switching root, install 111 // the recovery variant instead 112 Vendor_ramdisk_available *bool 113 114 // Normally Soong uses the directory structure to decide which modules 115 // should be included (framework) or excluded (non-framework) from the 116 // different snapshots (vendor, recovery, etc.), but this property 117 // allows a partner to exclude a module normally thought of as a 118 // framework module from the vendor snapshot. 119 Exclude_from_vendor_snapshot *bool 120 121 // Normally Soong uses the directory structure to decide which modules 122 // should be included (framework) or excluded (non-framework) from the 123 // different snapshots (vendor, recovery, etc.), but this property 124 // allows a partner to exclude a module normally thought of as a 125 // framework module from the recovery snapshot. 126 Exclude_from_recovery_snapshot *bool 127 128 // Make this module available when building for recovery 129 Recovery_available *bool 130 131 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 132 Min_sdk_version *string 133 134 HideFromMake bool `blueprint:"mutated"` 135 PreventInstall bool `blueprint:"mutated"` 136 137 Installable *bool 138} 139 140type Module struct { 141 fuzz.FuzzModule 142 143 VendorProperties cc.VendorProperties 144 145 Properties BaseProperties 146 147 hod android.HostOrDeviceSupported 148 multilib android.Multilib 149 150 makeLinkType string 151 152 afdo *afdo 153 compiler compiler 154 coverage *coverage 155 clippy *clippy 156 sanitize *sanitize 157 cachedToolchain config.Toolchain 158 sourceProvider SourceProvider 159 subAndroidMkOnce map[SubAndroidMkProvider]bool 160 161 // Output file to be installed, may be stripped or unstripped. 162 outputFile android.OptionalPath 163 164 docTimestampFile android.OptionalPath 165 166 hideApexVariantFromMake bool 167 168 // For apex variants, this is set as apex.min_sdk_version 169 apexSdkVersion android.ApiLevel 170} 171 172func (mod *Module) Header() bool { 173 //TODO: If Rust libraries provide header variants, this needs to be updated. 174 return false 175} 176 177func (mod *Module) SetPreventInstall() { 178 mod.Properties.PreventInstall = true 179} 180 181func (mod *Module) SetHideFromMake() { 182 mod.Properties.HideFromMake = true 183} 184 185func (mod *Module) HiddenFromMake() bool { 186 return mod.Properties.HideFromMake 187} 188 189func (mod *Module) SanitizePropDefined() bool { 190 // Because compiler is not set for some Rust modules where sanitize might be set, check that compiler is also not 191 // nil since we need compiler to actually sanitize. 192 return mod.sanitize != nil && mod.compiler != nil 193} 194 195func (mod *Module) IsPrebuilt() bool { 196 if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok { 197 return true 198 } 199 return false 200} 201 202func (mod *Module) OutputFiles(tag string) (android.Paths, error) { 203 switch tag { 204 case "": 205 if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) { 206 return mod.sourceProvider.Srcs(), nil 207 } else { 208 if mod.OutputFile().Valid() { 209 return android.Paths{mod.OutputFile().Path()}, nil 210 } 211 return android.Paths{}, nil 212 } 213 default: 214 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 215 } 216} 217 218func (mod *Module) SelectedStl() string { 219 return "" 220} 221 222func (mod *Module) NonCcVariants() bool { 223 if mod.compiler != nil { 224 if _, ok := mod.compiler.(libraryInterface); ok { 225 return false 226 } 227 } 228 panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName())) 229} 230 231func (mod *Module) Static() bool { 232 if mod.compiler != nil { 233 if library, ok := mod.compiler.(libraryInterface); ok { 234 return library.static() 235 } 236 } 237 return false 238} 239 240func (mod *Module) Shared() bool { 241 if mod.compiler != nil { 242 if library, ok := mod.compiler.(libraryInterface); ok { 243 return library.shared() 244 } 245 } 246 return false 247} 248 249func (mod *Module) Dylib() bool { 250 if mod.compiler != nil { 251 if library, ok := mod.compiler.(libraryInterface); ok { 252 return library.dylib() 253 } 254 } 255 return false 256} 257 258func (mod *Module) Rlib() bool { 259 if mod.compiler != nil { 260 if library, ok := mod.compiler.(libraryInterface); ok { 261 return library.rlib() 262 } 263 } 264 return false 265} 266 267func (mod *Module) Binary() bool { 268 if binary, ok := mod.compiler.(binaryInterface); ok { 269 return binary.binary() 270 } 271 return false 272} 273 274func (mod *Module) StaticExecutable() bool { 275 if !mod.Binary() { 276 return false 277 } 278 return mod.StaticallyLinked() 279} 280 281func (mod *Module) Object() bool { 282 // Rust has no modules which produce only object files. 283 return false 284} 285 286func (mod *Module) Toc() android.OptionalPath { 287 if mod.compiler != nil { 288 if lib, ok := mod.compiler.(libraryInterface); ok { 289 return lib.toc() 290 } 291 } 292 panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName())) 293} 294 295func (mod *Module) UseSdk() bool { 296 return false 297} 298 299func (mod *Module) RelativeInstallPath() string { 300 if mod.compiler != nil { 301 return mod.compiler.relativeInstallPath() 302 } 303 return "" 304} 305 306func (mod *Module) UseVndk() bool { 307 return mod.Properties.VndkVersion != "" 308} 309 310func (mod *Module) Bootstrap() bool { 311 return Bool(mod.Properties.Bootstrap) 312} 313 314func (mod *Module) MustUseVendorVariant() bool { 315 return true 316} 317 318func (mod *Module) SubName() string { 319 return mod.Properties.SubName 320} 321 322func (mod *Module) IsVndk() bool { 323 // TODO(b/165791368) 324 return false 325} 326 327func (mod *Module) IsVndkExt() bool { 328 return false 329} 330 331func (mod *Module) IsVndkSp() bool { 332 return false 333} 334 335func (mod *Module) IsVndkPrebuiltLibrary() bool { 336 // Rust modules do not provide VNDK prebuilts 337 return false 338} 339 340func (mod *Module) IsVendorPublicLibrary() bool { 341 return mod.VendorProperties.IsVendorPublicLibrary 342} 343 344func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool { 345 // Rust modules to not provide Sdk variants 346 return false 347} 348 349func (c *Module) IsVndkPrivate() bool { 350 return false 351} 352 353func (c *Module) IsLlndk() bool { 354 return false 355} 356 357func (c *Module) IsLlndkPublic() bool { 358 return false 359} 360 361func (mod *Module) KernelHeadersDecorator() bool { 362 return false 363} 364 365func (m *Module) NeedsLlndkVariants() bool { 366 return false 367} 368 369func (m *Module) NeedsVendorPublicLibraryVariants() bool { 370 return false 371} 372 373func (mod *Module) HasLlndkStubs() bool { 374 return false 375} 376 377func (mod *Module) StubsVersion() string { 378 panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName())) 379} 380 381func (mod *Module) SdkVersion() string { 382 return "" 383} 384 385func (mod *Module) AlwaysSdk() bool { 386 return false 387} 388 389func (mod *Module) IsSdkVariant() bool { 390 return false 391} 392 393func (mod *Module) SplitPerApiLevel() bool { 394 return false 395} 396 397type Deps struct { 398 Dylibs []string 399 Rlibs []string 400 Rustlibs []string 401 Stdlibs []string 402 ProcMacros []string 403 SharedLibs []string 404 StaticLibs []string 405 WholeStaticLibs []string 406 HeaderLibs []string 407 408 // Used for data dependencies adjacent to tests 409 DataLibs []string 410 DataBins []string 411 412 CrtBegin, CrtEnd []string 413} 414 415type PathDeps struct { 416 DyLibs RustLibraries 417 RLibs RustLibraries 418 SharedLibs android.Paths 419 SharedLibDeps android.Paths 420 StaticLibs android.Paths 421 ProcMacros RustLibraries 422 AfdoProfiles android.Paths 423 424 // depFlags and depLinkFlags are rustc and linker (clang) flags. 425 depFlags []string 426 depLinkFlags []string 427 428 // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker. 429 // Both of these are exported and propagate to dependencies. 430 linkDirs []string 431 linkObjects []string 432 433 // Used by bindgen modules which call clang 434 depClangFlags []string 435 depIncludePaths android.Paths 436 depGeneratedHeaders android.Paths 437 depSystemIncludePaths android.Paths 438 439 CrtBegin android.Paths 440 CrtEnd android.Paths 441 442 // Paths to generated source files 443 SrcDeps android.Paths 444 srcProviderFiles android.Paths 445} 446 447type RustLibraries []RustLibrary 448 449type RustLibrary struct { 450 Path android.Path 451 CrateName string 452} 453 454type compiler interface { 455 initialize(ctx ModuleContext) 456 compilerFlags(ctx ModuleContext, flags Flags) Flags 457 cfgFlags(ctx ModuleContext, flags Flags) Flags 458 featureFlags(ctx ModuleContext, flags Flags) Flags 459 compilerProps() []interface{} 460 compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path 461 compilerDeps(ctx DepsContext, deps Deps) Deps 462 crateName() string 463 rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath 464 465 // Output directory in which source-generated code from dependencies is 466 // copied. This is equivalent to Cargo's OUT_DIR variable. 467 CargoOutDir() android.OptionalPath 468 469 // CargoPkgVersion returns the value of the Cargo_pkg_version property. 470 CargoPkgVersion() string 471 472 // CargoEnvCompat returns whether Cargo environment variables should be used. 473 CargoEnvCompat() bool 474 475 inData() bool 476 install(ctx ModuleContext) 477 relativeInstallPath() string 478 everInstallable() bool 479 480 nativeCoverage() bool 481 482 Disabled() bool 483 SetDisabled() 484 485 stdLinkage(ctx *depsContext) RustLinkage 486 487 unstrippedOutputFilePath() android.Path 488 strippedOutputFilePath() android.OptionalPath 489} 490 491type exportedFlagsProducer interface { 492 exportLinkDirs(...string) 493 exportLinkObjects(...string) 494} 495 496type flagExporter struct { 497 linkDirs []string 498 linkObjects []string 499} 500 501func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { 502 flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) 503} 504 505func (flagExporter *flagExporter) exportLinkObjects(flags ...string) { 506 flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...)) 507} 508 509func (flagExporter *flagExporter) setProvider(ctx ModuleContext) { 510 ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{ 511 LinkDirs: flagExporter.linkDirs, 512 LinkObjects: flagExporter.linkObjects, 513 }) 514} 515 516var _ exportedFlagsProducer = (*flagExporter)(nil) 517 518func NewFlagExporter() *flagExporter { 519 return &flagExporter{} 520} 521 522type FlagExporterInfo struct { 523 Flags []string 524 LinkDirs []string // TODO: this should be android.Paths 525 LinkObjects []string // TODO: this should be android.Paths 526} 527 528var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{}) 529 530func (mod *Module) isCoverageVariant() bool { 531 return mod.coverage.Properties.IsCoverageVariant 532} 533 534var _ cc.Coverage = (*Module)(nil) 535 536func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { 537 return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant 538} 539 540func (mod *Module) VndkVersion() string { 541 return mod.Properties.VndkVersion 542} 543 544func (mod *Module) PreventInstall() bool { 545 return mod.Properties.PreventInstall 546} 547 548func (mod *Module) MarkAsCoverageVariant(coverage bool) { 549 mod.coverage.Properties.IsCoverageVariant = coverage 550} 551 552func (mod *Module) EnableCoverageIfNeeded() { 553 mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild 554} 555 556func defaultsFactory() android.Module { 557 return DefaultsFactory() 558} 559 560type Defaults struct { 561 android.ModuleBase 562 android.DefaultsModuleBase 563} 564 565func DefaultsFactory(props ...interface{}) android.Module { 566 module := &Defaults{} 567 568 module.AddProperties(props...) 569 module.AddProperties( 570 &BaseProperties{}, 571 &cc.AfdoProperties{}, 572 &cc.VendorProperties{}, 573 &BenchmarkProperties{}, 574 &BindgenProperties{}, 575 &BaseCompilerProperties{}, 576 &BinaryCompilerProperties{}, 577 &LibraryCompilerProperties{}, 578 &ProcMacroCompilerProperties{}, 579 &PrebuiltProperties{}, 580 &SourceProviderProperties{}, 581 &TestProperties{}, 582 &cc.CoverageProperties{}, 583 &cc.RustBindgenClangProperties{}, 584 &ClippyProperties{}, 585 &SanitizeProperties{}, 586 ) 587 588 android.InitDefaultsModule(module) 589 return module 590} 591 592func (mod *Module) CrateName() string { 593 return mod.compiler.crateName() 594} 595 596func (mod *Module) CcLibrary() bool { 597 if mod.compiler != nil { 598 if _, ok := mod.compiler.(libraryInterface); ok { 599 return true 600 } 601 } 602 return false 603} 604 605func (mod *Module) CcLibraryInterface() bool { 606 if mod.compiler != nil { 607 // use build{Static,Shared}() instead of {static,shared}() here because this might be called before 608 // VariantIs{Static,Shared} is set. 609 if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic()) { 610 return true 611 } 612 } 613 return false 614} 615 616func (mod *Module) UnstrippedOutputFile() android.Path { 617 if mod.compiler != nil { 618 return mod.compiler.unstrippedOutputFilePath() 619 } 620 return nil 621} 622 623func (mod *Module) IncludeDirs() android.Paths { 624 if mod.compiler != nil { 625 if library, ok := mod.compiler.(*libraryDecorator); ok { 626 return library.includeDirs 627 } 628 } 629 panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName())) 630} 631 632func (mod *Module) SetStatic() { 633 if mod.compiler != nil { 634 if library, ok := mod.compiler.(libraryInterface); ok { 635 library.setStatic() 636 return 637 } 638 } 639 panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName())) 640} 641 642func (mod *Module) SetShared() { 643 if mod.compiler != nil { 644 if library, ok := mod.compiler.(libraryInterface); ok { 645 library.setShared() 646 return 647 } 648 } 649 panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName())) 650} 651 652func (mod *Module) BuildStaticVariant() bool { 653 if mod.compiler != nil { 654 if library, ok := mod.compiler.(libraryInterface); ok { 655 return library.buildStatic() 656 } 657 } 658 panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) 659} 660 661func (mod *Module) BuildSharedVariant() bool { 662 if mod.compiler != nil { 663 if library, ok := mod.compiler.(libraryInterface); ok { 664 return library.buildShared() 665 } 666 } 667 panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName())) 668} 669 670func (mod *Module) Module() android.Module { 671 return mod 672} 673 674func (mod *Module) OutputFile() android.OptionalPath { 675 return mod.outputFile 676} 677 678func (mod *Module) CoverageFiles() android.Paths { 679 if mod.compiler != nil { 680 return android.Paths{} 681 } 682 panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName())) 683} 684 685func (mod *Module) installable(apexInfo android.ApexInfo) bool { 686 if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) { 687 return false 688 } 689 690 // The apex variant is not installable because it is included in the APEX and won't appear 691 // in the system partition as a standalone file. 692 if !apexInfo.IsForPlatform() { 693 return false 694 } 695 696 return mod.OutputFile().Valid() && !mod.Properties.PreventInstall 697} 698 699func (ctx moduleContext) apexVariationName() string { 700 return ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).ApexVariationName 701} 702 703var _ cc.LinkableInterface = (*Module)(nil) 704 705func (mod *Module) Init() android.Module { 706 mod.AddProperties(&mod.Properties) 707 mod.AddProperties(&mod.VendorProperties) 708 709 if mod.afdo != nil { 710 mod.AddProperties(mod.afdo.props()...) 711 } 712 if mod.compiler != nil { 713 mod.AddProperties(mod.compiler.compilerProps()...) 714 } 715 if mod.coverage != nil { 716 mod.AddProperties(mod.coverage.props()...) 717 } 718 if mod.clippy != nil { 719 mod.AddProperties(mod.clippy.props()...) 720 } 721 if mod.sourceProvider != nil { 722 mod.AddProperties(mod.sourceProvider.SourceProviderProps()...) 723 } 724 if mod.sanitize != nil { 725 mod.AddProperties(mod.sanitize.props()...) 726 } 727 728 android.InitAndroidArchModule(mod, mod.hod, mod.multilib) 729 android.InitApexModule(mod) 730 731 android.InitDefaultableModule(mod) 732 return mod 733} 734 735func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 736 return &Module{ 737 hod: hod, 738 multilib: multilib, 739 } 740} 741func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 742 module := newBaseModule(hod, multilib) 743 module.afdo = &afdo{} 744 module.coverage = &coverage{} 745 module.clippy = &clippy{} 746 module.sanitize = &sanitize{} 747 return module 748} 749 750type ModuleContext interface { 751 android.ModuleContext 752 ModuleContextIntf 753} 754 755type BaseModuleContext interface { 756 android.BaseModuleContext 757 ModuleContextIntf 758} 759 760type DepsContext interface { 761 android.BottomUpMutatorContext 762 ModuleContextIntf 763} 764 765type ModuleContextIntf interface { 766 RustModule() *Module 767 toolchain() config.Toolchain 768} 769 770type depsContext struct { 771 android.BottomUpMutatorContext 772} 773 774type moduleContext struct { 775 android.ModuleContext 776} 777 778type baseModuleContext struct { 779 android.BaseModuleContext 780} 781 782func (ctx *moduleContext) RustModule() *Module { 783 return ctx.Module().(*Module) 784} 785 786func (ctx *moduleContext) toolchain() config.Toolchain { 787 return ctx.RustModule().toolchain(ctx) 788} 789 790func (ctx *depsContext) RustModule() *Module { 791 return ctx.Module().(*Module) 792} 793 794func (ctx *depsContext) toolchain() config.Toolchain { 795 return ctx.RustModule().toolchain(ctx) 796} 797 798func (ctx *baseModuleContext) RustModule() *Module { 799 return ctx.Module().(*Module) 800} 801 802func (ctx *baseModuleContext) toolchain() config.Toolchain { 803 return ctx.RustModule().toolchain(ctx) 804} 805 806func (mod *Module) nativeCoverage() bool { 807 // Bug: http://b/137883967 - native-bridge modules do not currently work with coverage 808 if mod.Target().NativeBridge == android.NativeBridgeEnabled { 809 return false 810 } 811 return mod.compiler != nil && mod.compiler.nativeCoverage() 812} 813 814func (mod *Module) EverInstallable() bool { 815 return mod.compiler != nil && 816 // Check to see whether the module is actually ever installable. 817 mod.compiler.everInstallable() 818} 819 820func (mod *Module) Installable() *bool { 821 return mod.Properties.Installable 822} 823 824func (mod *Module) ProcMacro() bool { 825 if pm, ok := mod.compiler.(procMacroInterface); ok { 826 return pm.ProcMacro() 827 } 828 return false 829} 830 831func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { 832 if mod.cachedToolchain == nil { 833 mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) 834 } 835 return mod.cachedToolchain 836} 837 838func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchain { 839 return cc_config.FindToolchain(ctx.Os(), ctx.Arch()) 840} 841 842func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { 843} 844 845func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { 846 ctx := &moduleContext{ 847 ModuleContext: actx, 848 } 849 850 apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo) 851 if !apexInfo.IsForPlatform() { 852 mod.hideApexVariantFromMake = true 853 } 854 855 toolchain := mod.toolchain(ctx) 856 mod.makeLinkType = cc.GetMakeLinkType(actx, mod) 857 858 mod.Properties.SubName = cc.GetSubnameProperty(actx, mod) 859 860 if !toolchain.Supported() { 861 // This toolchain's unsupported, there's nothing to do for this mod. 862 return 863 } 864 865 deps := mod.depsToPaths(ctx) 866 flags := Flags{ 867 Toolchain: toolchain, 868 } 869 870 // Calculate rustc flags 871 if mod.afdo != nil { 872 flags, deps = mod.afdo.flags(ctx, flags, deps) 873 } 874 if mod.compiler != nil { 875 flags = mod.compiler.compilerFlags(ctx, flags) 876 flags = mod.compiler.cfgFlags(ctx, flags) 877 flags = mod.compiler.featureFlags(ctx, flags) 878 } 879 if mod.coverage != nil { 880 flags, deps = mod.coverage.flags(ctx, flags, deps) 881 } 882 if mod.clippy != nil { 883 flags, deps = mod.clippy.flags(ctx, flags, deps) 884 } 885 if mod.sanitize != nil { 886 flags, deps = mod.sanitize.flags(ctx, flags, deps) 887 } 888 889 // SourceProvider needs to call GenerateSource() before compiler calls 890 // compile() so it can provide the source. A SourceProvider has 891 // multiple variants (e.g. source, rlib, dylib). Only the "source" 892 // variant is responsible for effectively generating the source. The 893 // remaining variants relies on the "source" variant output. 894 if mod.sourceProvider != nil { 895 if mod.compiler.(libraryInterface).source() { 896 mod.sourceProvider.GenerateSource(ctx, deps) 897 mod.sourceProvider.setSubName(ctx.ModuleSubDir()) 898 } else { 899 sourceMod := actx.GetDirectDepWithTag(mod.Name(), sourceDepTag) 900 sourceLib := sourceMod.(*Module).compiler.(*libraryDecorator) 901 mod.sourceProvider.setOutputFiles(sourceLib.sourceProvider.Srcs()) 902 } 903 } 904 905 if mod.compiler != nil && !mod.compiler.Disabled() { 906 mod.compiler.initialize(ctx) 907 outputFile := mod.compiler.compile(ctx, flags, deps) 908 if ctx.Failed() { 909 return 910 } 911 mod.outputFile = android.OptionalPathForPath(outputFile) 912 bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath())) 913 914 mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps) 915 if mod.docTimestampFile.Valid() { 916 ctx.CheckbuildFile(mod.docTimestampFile.Path()) 917 } 918 919 // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current or 920 // RECOVERY_SNAPSHOT_VERSION is current. 921 if lib, ok := mod.compiler.(snapshotLibraryInterface); ok { 922 if cc.ShouldCollectHeadersForSnapshot(ctx, mod, apexInfo) { 923 lib.collectHeadersForSnapshot(ctx, deps) 924 } 925 } 926 927 apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo) 928 if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) && !mod.ProcMacro() { 929 // If the module has been specifically configure to not be installed then 930 // hide from make as otherwise it will break when running inside make as the 931 // output path to install will not be specified. Not all uninstallable 932 // modules can be hidden from make as some are needed for resolving make 933 // side dependencies. In particular, proc-macros need to be captured in the 934 // host snapshot. 935 mod.HideFromMake() 936 } else if !mod.installable(apexInfo) { 937 mod.SkipInstall() 938 } 939 940 // Still call install though, the installs will be stored as PackageSpecs to allow 941 // using the outputs in a genrule. 942 if mod.OutputFile().Valid() { 943 mod.compiler.install(ctx) 944 if ctx.Failed() { 945 return 946 } 947 } 948 949 ctx.Phony("rust", ctx.RustModule().OutputFile().Path()) 950 } 951} 952 953func (mod *Module) deps(ctx DepsContext) Deps { 954 deps := Deps{} 955 956 if mod.compiler != nil { 957 deps = mod.compiler.compilerDeps(ctx, deps) 958 } 959 if mod.sourceProvider != nil { 960 deps = mod.sourceProvider.SourceProviderDeps(ctx, deps) 961 } 962 963 if mod.coverage != nil { 964 deps = mod.coverage.deps(ctx, deps) 965 } 966 967 if mod.sanitize != nil { 968 deps = mod.sanitize.deps(ctx, deps) 969 } 970 971 deps.Rlibs = android.LastUniqueStrings(deps.Rlibs) 972 deps.Dylibs = android.LastUniqueStrings(deps.Dylibs) 973 deps.Rustlibs = android.LastUniqueStrings(deps.Rustlibs) 974 deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros) 975 deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs) 976 deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs) 977 deps.Stdlibs = android.LastUniqueStrings(deps.Stdlibs) 978 deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs) 979 return deps 980 981} 982 983type dependencyTag struct { 984 blueprint.BaseDependencyTag 985 name string 986 library bool 987 procMacro bool 988 dynamic bool 989} 990 991// InstallDepNeeded returns true for rlibs, dylibs, and proc macros so that they or their transitive 992// dependencies (especially C/C++ shared libs) are installed as dependencies of a rust binary. 993func (d dependencyTag) InstallDepNeeded() bool { 994 return d.library || d.procMacro 995} 996 997var _ android.InstallNeededDependencyTag = dependencyTag{} 998 999func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { 1000 if d.library && d.dynamic { 1001 return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} 1002 } 1003 return nil 1004} 1005 1006var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} 1007 1008var ( 1009 customBindgenDepTag = dependencyTag{name: "customBindgenTag"} 1010 rlibDepTag = dependencyTag{name: "rlibTag", library: true} 1011 dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true} 1012 procMacroDepTag = dependencyTag{name: "procMacro", procMacro: true} 1013 testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"} 1014 sourceDepTag = dependencyTag{name: "source"} 1015 dataLibDepTag = dependencyTag{name: "data lib"} 1016 dataBinDepTag = dependencyTag{name: "data bin"} 1017) 1018 1019func IsDylibDepTag(depTag blueprint.DependencyTag) bool { 1020 tag, ok := depTag.(dependencyTag) 1021 return ok && tag == dylibDepTag 1022} 1023 1024func IsRlibDepTag(depTag blueprint.DependencyTag) bool { 1025 tag, ok := depTag.(dependencyTag) 1026 return ok && tag == rlibDepTag 1027} 1028 1029type autoDep struct { 1030 variation string 1031 depTag dependencyTag 1032} 1033 1034var ( 1035 rlibVariation = "rlib" 1036 dylibVariation = "dylib" 1037 rlibAutoDep = autoDep{variation: rlibVariation, depTag: rlibDepTag} 1038 dylibAutoDep = autoDep{variation: dylibVariation, depTag: dylibDepTag} 1039) 1040 1041type autoDeppable interface { 1042 autoDep(ctx android.BottomUpMutatorContext) autoDep 1043} 1044 1045func (mod *Module) begin(ctx BaseModuleContext) { 1046 if mod.coverage != nil { 1047 mod.coverage.begin(ctx) 1048 } 1049 if mod.sanitize != nil { 1050 mod.sanitize.begin(ctx) 1051 } 1052} 1053 1054func (mod *Module) Prebuilt() *android.Prebuilt { 1055 if p, ok := mod.compiler.(rustPrebuilt); ok { 1056 return p.prebuilt() 1057 } 1058 return nil 1059} 1060 1061func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 1062 var depPaths PathDeps 1063 1064 directRlibDeps := []*Module{} 1065 directDylibDeps := []*Module{} 1066 directProcMacroDeps := []*Module{} 1067 directSharedLibDeps := []cc.SharedLibraryInfo{} 1068 directStaticLibDeps := [](cc.LinkableInterface){} 1069 directSrcProvidersDeps := []*Module{} 1070 directSrcDeps := [](android.SourceFileProducer){} 1071 1072 // For the dependency from platform to apex, use the latest stubs 1073 mod.apexSdkVersion = android.FutureApiLevel 1074 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 1075 if !apexInfo.IsForPlatform() { 1076 mod.apexSdkVersion = apexInfo.MinSdkVersion 1077 } 1078 1079 if android.InList("hwaddress", ctx.Config().SanitizeDevice()) { 1080 // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000) 1081 // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)). 1082 // (b/144430859) 1083 mod.apexSdkVersion = android.FutureApiLevel 1084 } 1085 1086 ctx.VisitDirectDeps(func(dep android.Module) { 1087 depName := ctx.OtherModuleName(dep) 1088 depTag := ctx.OtherModuleDependencyTag(dep) 1089 1090 if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() { 1091 //Handle Rust Modules 1092 makeLibName := cc.MakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName) 1093 1094 switch depTag { 1095 case dylibDepTag: 1096 dylib, ok := rustDep.compiler.(libraryInterface) 1097 if !ok || !dylib.dylib() { 1098 ctx.ModuleErrorf("mod %q not an dylib library", depName) 1099 return 1100 } 1101 directDylibDeps = append(directDylibDeps, rustDep) 1102 mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName) 1103 case rlibDepTag: 1104 1105 rlib, ok := rustDep.compiler.(libraryInterface) 1106 if !ok || !rlib.rlib() { 1107 ctx.ModuleErrorf("mod %q not an rlib library", makeLibName) 1108 return 1109 } 1110 directRlibDeps = append(directRlibDeps, rustDep) 1111 mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName) 1112 case procMacroDepTag: 1113 directProcMacroDeps = append(directProcMacroDeps, rustDep) 1114 mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) 1115 } 1116 1117 if android.IsSourceDepTagWithOutputTag(depTag, "") { 1118 // Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct 1119 // OS/Arch variant is used. 1120 var helper string 1121 if ctx.Host() { 1122 helper = "missing 'host_supported'?" 1123 } else { 1124 helper = "device module defined?" 1125 } 1126 1127 if dep.Target().Os != ctx.Os() { 1128 ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper) 1129 return 1130 } else if dep.Target().Arch.ArchType != ctx.Arch().ArchType { 1131 ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper) 1132 return 1133 } 1134 directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep) 1135 } 1136 1137 //Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS 1138 if depTag != procMacroDepTag { 1139 exportedInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo) 1140 depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...) 1141 depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...) 1142 depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...) 1143 } 1144 1145 if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { 1146 linkFile := rustDep.UnstrippedOutputFile() 1147 linkDir := linkPathFromFilePath(linkFile) 1148 if lib, ok := mod.compiler.(exportedFlagsProducer); ok { 1149 lib.exportLinkDirs(linkDir) 1150 } 1151 } 1152 1153 } else if ccDep, ok := dep.(cc.LinkableInterface); ok { 1154 //Handle C dependencies 1155 makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName) 1156 if _, ok := ccDep.(*Module); !ok { 1157 if ccDep.Module().Target().Os != ctx.Os() { 1158 ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) 1159 return 1160 } 1161 if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType { 1162 ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) 1163 return 1164 } 1165 } 1166 linkObject := ccDep.OutputFile() 1167 linkPath := linkPathFromFilePath(linkObject.Path()) 1168 1169 if !linkObject.Valid() { 1170 ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) 1171 } 1172 1173 exportDep := false 1174 switch { 1175 case cc.IsStaticDepTag(depTag): 1176 if cc.IsWholeStaticLib(depTag) { 1177 // rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail 1178 // if the library is not prefixed by "lib". 1179 if mod.Binary() { 1180 // Binaries may sometimes need to link whole static libraries that don't start with 'lib'. 1181 // Since binaries don't need to 'rebundle' these like libraries and only use these for the 1182 // final linkage, pass the args directly to the linker to handle these cases. 1183 depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...) 1184 } else if libName, ok := libNameFromFilePath(linkObject.Path()); ok { 1185 depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName) 1186 } else { 1187 ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName()) 1188 } 1189 } 1190 1191 // Add this to linkObjects to pass the library directly to the linker as well. This propagates 1192 // to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant. 1193 depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String()) 1194 depPaths.linkDirs = append(depPaths.linkDirs, linkPath) 1195 1196 exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) 1197 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1198 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) 1199 depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) 1200 depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) 1201 directStaticLibDeps = append(directStaticLibDeps, ccDep) 1202 1203 // Record baseLibName for snapshots. 1204 mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName)) 1205 1206 mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, makeLibName) 1207 case cc.IsSharedDepTag(depTag): 1208 // For the shared lib dependencies, we may link to the stub variant 1209 // of the dependency depending on the context (e.g. if this 1210 // dependency crosses the APEX boundaries). 1211 sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep) 1212 1213 // Re-get linkObject as ChooseStubOrImpl actually tells us which 1214 // object (either from stub or non-stub) to use. 1215 linkObject = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary) 1216 linkPath = linkPathFromFilePath(linkObject.Path()) 1217 1218 depPaths.linkDirs = append(depPaths.linkDirs, linkPath) 1219 depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String()) 1220 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1221 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) 1222 depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) 1223 depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) 1224 directSharedLibDeps = append(directSharedLibDeps, sharedLibraryInfo) 1225 1226 // Record baseLibName for snapshots. 1227 mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName)) 1228 1229 mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName) 1230 exportDep = true 1231 case cc.IsHeaderDepTag(depTag): 1232 exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo) 1233 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1234 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) 1235 depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) 1236 case depTag == cc.CrtBeginDepTag: 1237 depPaths.CrtBegin = append(depPaths.CrtBegin, linkObject.Path()) 1238 case depTag == cc.CrtEndDepTag: 1239 depPaths.CrtEnd = append(depPaths.CrtEnd, linkObject.Path()) 1240 } 1241 1242 // Make sure these dependencies are propagated 1243 if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { 1244 lib.exportLinkDirs(linkPath) 1245 lib.exportLinkObjects(linkObject.String()) 1246 } 1247 } else { 1248 switch { 1249 case depTag == cc.CrtBeginDepTag: 1250 depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, "")) 1251 case depTag == cc.CrtEndDepTag: 1252 depPaths.CrtEnd = append(depPaths.CrtEnd, android.OutputFileForModule(ctx, dep, "")) 1253 } 1254 } 1255 1256 if srcDep, ok := dep.(android.SourceFileProducer); ok { 1257 if android.IsSourceDepTagWithOutputTag(depTag, "") { 1258 // These are usually genrules which don't have per-target variants. 1259 directSrcDeps = append(directSrcDeps, srcDep) 1260 } 1261 } 1262 }) 1263 1264 var rlibDepFiles RustLibraries 1265 for _, dep := range directRlibDeps { 1266 rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) 1267 } 1268 var dylibDepFiles RustLibraries 1269 for _, dep := range directDylibDeps { 1270 dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) 1271 } 1272 var procMacroDepFiles RustLibraries 1273 for _, dep := range directProcMacroDeps { 1274 procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()}) 1275 } 1276 1277 var staticLibDepFiles android.Paths 1278 for _, dep := range directStaticLibDeps { 1279 staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path()) 1280 } 1281 1282 var sharedLibFiles android.Paths 1283 var sharedLibDepFiles android.Paths 1284 for _, dep := range directSharedLibDeps { 1285 sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary) 1286 if dep.TableOfContents.Valid() { 1287 sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path()) 1288 } else { 1289 sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary) 1290 } 1291 } 1292 1293 var srcProviderDepFiles android.Paths 1294 for _, dep := range directSrcProvidersDeps { 1295 srcs, _ := dep.OutputFiles("") 1296 srcProviderDepFiles = append(srcProviderDepFiles, srcs...) 1297 } 1298 for _, dep := range directSrcDeps { 1299 srcs := dep.Srcs() 1300 srcProviderDepFiles = append(srcProviderDepFiles, srcs...) 1301 } 1302 1303 depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) 1304 depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) 1305 depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibDepFiles...) 1306 depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...) 1307 depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) 1308 depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...) 1309 depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...) 1310 1311 // Dedup exported flags from dependencies 1312 depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs) 1313 depPaths.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects) 1314 depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) 1315 depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags) 1316 depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) 1317 depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths) 1318 1319 return depPaths 1320} 1321 1322func (mod *Module) InstallInData() bool { 1323 if mod.compiler == nil { 1324 return false 1325 } 1326 return mod.compiler.inData() 1327} 1328 1329func (mod *Module) InstallInRamdisk() bool { 1330 return mod.InRamdisk() 1331} 1332 1333func (mod *Module) InstallInVendorRamdisk() bool { 1334 return mod.InVendorRamdisk() 1335} 1336 1337func (mod *Module) InstallInRecovery() bool { 1338 return mod.InRecovery() 1339} 1340 1341func linkPathFromFilePath(filepath android.Path) string { 1342 return strings.Split(filepath.String(), filepath.Base())[0] 1343} 1344 1345func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 1346 ctx := &depsContext{ 1347 BottomUpMutatorContext: actx, 1348 } 1349 1350 deps := mod.deps(ctx) 1351 var commonDepVariations []blueprint.Variation 1352 var snapshotInfo *cc.SnapshotInfo 1353 1354 if ctx.Os() == android.Android { 1355 deps.SharedLibs, _ = cc.RewriteLibs(mod, &snapshotInfo, actx, ctx.Config(), deps.SharedLibs) 1356 } 1357 1358 stdLinkage := "dylib-std" 1359 if mod.compiler.stdLinkage(ctx) == RlibLinkage { 1360 stdLinkage = "rlib-std" 1361 } 1362 1363 rlibDepVariations := commonDepVariations 1364 1365 if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() { 1366 rlibDepVariations = append(rlibDepVariations, 1367 blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage}) 1368 } 1369 1370 // rlibs 1371 rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation}) 1372 for _, lib := range deps.Rlibs { 1373 depTag := rlibDepTag 1374 lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) 1375 1376 actx.AddVariationDependencies(rlibDepVariations, depTag, lib) 1377 } 1378 1379 // dylibs 1380 actx.AddVariationDependencies( 1381 append(commonDepVariations, []blueprint.Variation{ 1382 {Mutator: "rust_libraries", Variation: dylibVariation}}...), 1383 dylibDepTag, deps.Dylibs...) 1384 1385 // rustlibs 1386 if deps.Rustlibs != nil && !mod.compiler.Disabled() { 1387 autoDep := mod.compiler.(autoDeppable).autoDep(ctx) 1388 for _, lib := range deps.Rustlibs { 1389 if autoDep.depTag == rlibDepTag { 1390 // Handle the rlib deptag case 1391 addRlibDependency(actx, lib, mod, snapshotInfo, rlibDepVariations) 1392 } else { 1393 // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however. 1394 // Check for the existence of the dylib deptag variant. Select it if available, 1395 // otherwise select the rlib variant. 1396 autoDepVariations := append(commonDepVariations, 1397 blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}) 1398 if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) { 1399 actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib) 1400 } else { 1401 // If there's no dylib dependency available, try to add the rlib dependency instead. 1402 addRlibDependency(actx, lib, mod, snapshotInfo, rlibDepVariations) 1403 } 1404 } 1405 } 1406 } 1407 // stdlibs 1408 if deps.Stdlibs != nil { 1409 if mod.compiler.stdLinkage(ctx) == RlibLinkage { 1410 for _, lib := range deps.Stdlibs { 1411 depTag := rlibDepTag 1412 lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) 1413 1414 actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...), 1415 depTag, lib) 1416 } 1417 } else { 1418 actx.AddVariationDependencies( 1419 append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"}), 1420 dylibDepTag, deps.Stdlibs...) 1421 } 1422 } 1423 1424 for _, lib := range deps.SharedLibs { 1425 depTag := cc.SharedDepTag() 1426 name, version := cc.StubsLibNameAndVersion(lib) 1427 1428 variations := []blueprint.Variation{ 1429 {Mutator: "link", Variation: "shared"}, 1430 } 1431 cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false) 1432 } 1433 1434 for _, lib := range deps.WholeStaticLibs { 1435 depTag := cc.StaticDepTag(true) 1436 lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs) 1437 1438 actx.AddVariationDependencies([]blueprint.Variation{ 1439 {Mutator: "link", Variation: "static"}, 1440 }, depTag, lib) 1441 } 1442 1443 for _, lib := range deps.StaticLibs { 1444 depTag := cc.StaticDepTag(false) 1445 lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).StaticLibs) 1446 1447 actx.AddVariationDependencies([]blueprint.Variation{ 1448 {Mutator: "link", Variation: "static"}, 1449 }, depTag, lib) 1450 } 1451 1452 actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...) 1453 1454 crtVariations := cc.GetCrtVariations(ctx, mod) 1455 for _, crt := range deps.CrtBegin { 1456 actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, 1457 cc.RewriteSnapshotLib(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) 1458 } 1459 for _, crt := range deps.CrtEnd { 1460 actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, 1461 cc.RewriteSnapshotLib(crt, cc.GetSnapshot(mod, &snapshotInfo, actx).Objects)) 1462 } 1463 1464 if mod.sourceProvider != nil { 1465 if bindgen, ok := mod.sourceProvider.(*bindgenDecorator); ok && 1466 bindgen.Properties.Custom_bindgen != "" { 1467 actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), customBindgenDepTag, 1468 bindgen.Properties.Custom_bindgen) 1469 } 1470 } 1471 1472 actx.AddVariationDependencies([]blueprint.Variation{ 1473 {Mutator: "link", Variation: "shared"}, 1474 }, dataLibDepTag, deps.DataLibs...) 1475 1476 actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...) 1477 1478 // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy. 1479 actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...) 1480} 1481 1482// addRlibDependency will add an rlib dependency, rewriting to the snapshot library if available. 1483func addRlibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo *cc.SnapshotInfo, variations []blueprint.Variation) { 1484 lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs) 1485 actx.AddVariationDependencies(variations, rlibDepTag, lib) 1486} 1487 1488func BeginMutator(ctx android.BottomUpMutatorContext) { 1489 if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() { 1490 mod.beginMutator(ctx) 1491 } 1492} 1493 1494func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) { 1495 ctx := &baseModuleContext{ 1496 BaseModuleContext: actx, 1497 } 1498 1499 mod.begin(ctx) 1500} 1501 1502func (mod *Module) Name() string { 1503 name := mod.ModuleBase.Name() 1504 if p, ok := mod.compiler.(interface { 1505 Name(string) string 1506 }); ok { 1507 name = p.Name(name) 1508 } 1509 return name 1510} 1511 1512func (mod *Module) disableClippy() { 1513 if mod.clippy != nil { 1514 mod.clippy.Properties.Clippy_lints = proptools.StringPtr("none") 1515 } 1516} 1517 1518var _ android.HostToolProvider = (*Module)(nil) 1519var _ snapshot.RelativeInstallPath = (*Module)(nil) 1520 1521func (mod *Module) HostToolPath() android.OptionalPath { 1522 if !mod.Host() { 1523 return android.OptionalPath{} 1524 } 1525 if binary, ok := mod.compiler.(*binaryDecorator); ok { 1526 return android.OptionalPathForPath(binary.baseCompiler.path) 1527 } else if pm, ok := mod.compiler.(*procMacroDecorator); ok { 1528 // Even though proc-macros aren't strictly "tools", since they target the compiler 1529 // and act as compiler plugins, we treat them similarly. 1530 return android.OptionalPathForPath(pm.baseCompiler.path) 1531 } 1532 return android.OptionalPath{} 1533} 1534 1535var _ android.ApexModule = (*Module)(nil) 1536 1537func (mod *Module) MinSdkVersion() string { 1538 return String(mod.Properties.Min_sdk_version) 1539} 1540 1541// Implements android.ApexModule 1542func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { 1543 minSdkVersion := mod.MinSdkVersion() 1544 if minSdkVersion == "apex_inherit" { 1545 return nil 1546 } 1547 if minSdkVersion == "" { 1548 return fmt.Errorf("min_sdk_version is not specificed") 1549 } 1550 1551 // Not using nativeApiLevelFromUser because the context here is not 1552 // necessarily a native context. 1553 ver, err := android.ApiLevelFromUser(ctx, minSdkVersion) 1554 if err != nil { 1555 return err 1556 } 1557 1558 if ver.GreaterThan(sdkVersion) { 1559 return fmt.Errorf("newer SDK(%v)", ver) 1560 } 1561 return nil 1562} 1563 1564// Implements android.ApexModule 1565func (mod *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 1566 depTag := ctx.OtherModuleDependencyTag(dep) 1567 1568 if ccm, ok := dep.(*cc.Module); ok { 1569 if ccm.HasStubsVariants() { 1570 if cc.IsSharedDepTag(depTag) { 1571 // dynamic dep to a stubs lib crosses APEX boundary 1572 return false 1573 } 1574 if cc.IsRuntimeDepTag(depTag) { 1575 // runtime dep to a stubs lib also crosses APEX boundary 1576 return false 1577 } 1578 1579 if cc.IsHeaderDepTag(depTag) { 1580 return false 1581 } 1582 } 1583 if mod.Static() && cc.IsSharedDepTag(depTag) { 1584 // shared_lib dependency from a static lib is considered as crossing 1585 // the APEX boundary because the dependency doesn't actually is 1586 // linked; the dependency is used only during the compilation phase. 1587 return false 1588 } 1589 } 1590 1591 if depTag == procMacroDepTag { 1592 return false 1593 } 1594 1595 return true 1596} 1597 1598// Overrides ApexModule.IsInstallabeToApex() 1599func (mod *Module) IsInstallableToApex() bool { 1600 if mod.compiler != nil { 1601 if lib, ok := mod.compiler.(libraryInterface); ok && (lib.shared() || lib.dylib()) { 1602 return true 1603 } 1604 if _, ok := mod.compiler.(*binaryDecorator); ok { 1605 return true 1606 } 1607 } 1608 return false 1609} 1610 1611// If a library file has a "lib" prefix, extract the library name without the prefix. 1612func libNameFromFilePath(filepath android.Path) (string, bool) { 1613 libName := strings.TrimSuffix(filepath.Base(), filepath.Ext()) 1614 if strings.HasPrefix(libName, "lib") { 1615 libName = libName[3:] 1616 return libName, true 1617 } 1618 return "", false 1619} 1620 1621var Bool = proptools.Bool 1622var BoolDefault = proptools.BoolDefault 1623var String = proptools.String 1624var StringPtr = proptools.StringPtr 1625 1626var _ android.OutputFileProducer = (*Module)(nil) 1627