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 "strconv" 20 "strings" 21 22 "android/soong/bloaty" 23 24 "github.com/google/blueprint" 25 "github.com/google/blueprint/depset" 26 "github.com/google/blueprint/proptools" 27 28 "android/soong/android" 29 "android/soong/cc" 30 cc_config "android/soong/cc/config" 31 "android/soong/fuzz" 32 "android/soong/rust/config" 33) 34 35var pctx = android.NewPackageContext("android/soong/rust") 36 37type LibraryInfo struct { 38 Rlib bool 39 Dylib bool 40} 41 42type CompilerInfo struct { 43 StdLinkageForDevice RustLinkage 44 StdLinkageForNonDevice RustLinkage 45 NoStdlibs bool 46 LibraryInfo *LibraryInfo 47} 48 49type ProtobufDecoratorInfo struct{} 50 51type SourceProviderInfo struct { 52 Srcs android.Paths 53 ProtobufDecoratorInfo *ProtobufDecoratorInfo 54} 55 56type RustInfo struct { 57 AndroidMkSuffix string 58 RustSubName string 59 TransitiveAndroidMkSharedLibs depset.DepSet[string] 60 CompilerInfo *CompilerInfo 61 SnapshotInfo *cc.SnapshotInfo 62 SourceProviderInfo *SourceProviderInfo 63 XrefRustFiles android.Paths 64 DocTimestampFile android.OptionalPath 65} 66 67var RustInfoProvider = blueprint.NewProvider[*RustInfo]() 68 69func init() { 70 android.RegisterModuleType("rust_defaults", defaultsFactory) 71 android.PreDepsMutators(registerPreDepsMutators) 72 android.PostDepsMutators(registerPostDepsMutators) 73 pctx.Import("android/soong/android") 74 pctx.Import("android/soong/rust/config") 75 pctx.ImportAs("cc_config", "android/soong/cc/config") 76 android.InitRegistrationContext.RegisterParallelSingletonType("kythe_rust_extract", kytheExtractRustFactory) 77} 78 79func registerPreDepsMutators(ctx android.RegisterMutatorsContext) { 80 ctx.Transition("rust_libraries", &libraryTransitionMutator{}) 81 ctx.Transition("rust_stdlinkage", &libstdTransitionMutator{}) 82 ctx.BottomUp("rust_begin", BeginMutator) 83} 84 85func registerPostDepsMutators(ctx android.RegisterMutatorsContext) { 86 ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator) 87} 88 89type Flags struct { 90 GlobalRustFlags []string // Flags that apply globally to rust 91 GlobalLinkFlags []string // Flags that apply globally to linker 92 RustFlags []string // Flags that apply to rust 93 LinkFlags []string // Flags that apply to linker 94 ClippyFlags []string // Flags that apply to clippy-driver, during the linting 95 RustdocFlags []string // Flags that apply to rustdoc 96 Toolchain config.Toolchain 97 Coverage bool 98 Clippy bool 99 EmitXrefs bool // If true, emit rules to aid cross-referencing 100} 101 102type BaseProperties struct { 103 AndroidMkRlibs []string `blueprint:"mutated"` 104 AndroidMkDylibs []string `blueprint:"mutated"` 105 AndroidMkProcMacroLibs []string `blueprint:"mutated"` 106 AndroidMkStaticLibs []string `blueprint:"mutated"` 107 AndroidMkHeaderLibs []string `blueprint:"mutated"` 108 109 ImageVariation string `blueprint:"mutated"` 110 VndkVersion string `blueprint:"mutated"` 111 SubName string `blueprint:"mutated"` 112 113 // SubName is used by CC for tracking image variants / SDK versions. RustSubName is used for Rust-specific 114 // subnaming which shouldn't be visible to CC modules (such as the rlib stdlinkage subname). This should be 115 // appended before SubName. 116 RustSubName string `blueprint:"mutated"` 117 118 // Set by imageMutator 119 ProductVariantNeeded bool `blueprint:"mutated"` 120 VendorVariantNeeded bool `blueprint:"mutated"` 121 CoreVariantNeeded bool `blueprint:"mutated"` 122 VendorRamdiskVariantNeeded bool `blueprint:"mutated"` 123 RamdiskVariantNeeded bool `blueprint:"mutated"` 124 RecoveryVariantNeeded bool `blueprint:"mutated"` 125 ExtraVariants []string `blueprint:"mutated"` 126 127 // Allows this module to use non-APEX version of libraries. Useful 128 // for building binaries that are started before APEXes are activated. 129 Bootstrap *bool 130 131 // Used by vendor snapshot to record dependencies from snapshot modules. 132 SnapshotSharedLibs []string `blueprint:"mutated"` 133 SnapshotStaticLibs []string `blueprint:"mutated"` 134 SnapshotRlibs []string `blueprint:"mutated"` 135 SnapshotDylibs []string `blueprint:"mutated"` 136 137 // Make this module available when building for ramdisk. 138 // On device without a dedicated recovery partition, the module is only 139 // available after switching root into 140 // /first_stage_ramdisk. To expose the module before switching root, install 141 // the recovery variant instead. 142 Ramdisk_available *bool 143 144 // Make this module available when building for vendor ramdisk. 145 // On device without a dedicated recovery partition, the module is only 146 // available after switching root into 147 // /first_stage_ramdisk. To expose the module before switching root, install 148 // the recovery variant instead 149 Vendor_ramdisk_available *bool 150 151 // Normally Soong uses the directory structure to decide which modules 152 // should be included (framework) or excluded (non-framework) from the 153 // different snapshots (vendor, recovery, etc.), but this property 154 // allows a partner to exclude a module normally thought of as a 155 // framework module from the vendor snapshot. 156 Exclude_from_vendor_snapshot *bool 157 158 // Normally Soong uses the directory structure to decide which modules 159 // should be included (framework) or excluded (non-framework) from the 160 // different snapshots (vendor, recovery, etc.), but this property 161 // allows a partner to exclude a module normally thought of as a 162 // framework module from the recovery snapshot. 163 Exclude_from_recovery_snapshot *bool 164 165 // Make this module available when building for recovery 166 Recovery_available *bool 167 168 // The API level that this module is built against. The APIs of this API level will be 169 // visible at build time, but use of any APIs newer than min_sdk_version will render the 170 // module unloadable on older devices. In the future it will be possible to weakly-link new 171 // APIs, making the behavior match Java: such modules will load on older devices, but 172 // calling new APIs on devices that do not support them will result in a crash. 173 // 174 // This property has the same behavior as sdk_version does for Java modules. For those 175 // familiar with Android Gradle, the property behaves similarly to how compileSdkVersion 176 // does for Java code. 177 // 178 // In addition, setting this property causes two variants to be built, one for the platform 179 // and one for apps. 180 Sdk_version *string 181 182 // Minimum OS API level supported by this C or C++ module. This property becomes the value 183 // of the __ANDROID_API__ macro. When the C or C++ module is included in an APEX or an APK, 184 // this property is also used to ensure that the min_sdk_version of the containing module is 185 // not older (i.e. less) than this module's min_sdk_version. When not set, this property 186 // defaults to the value of sdk_version. When this is set to "apex_inherit", this tracks 187 // min_sdk_version of the containing APEX. When the module 188 // is not built for an APEX, "apex_inherit" defaults to sdk_version. 189 Min_sdk_version *string 190 191 // Variant is an SDK variant created by sdkMutator 192 IsSdkVariant bool `blueprint:"mutated"` 193 194 // Set by factories of module types that can only be referenced from variants compiled against 195 // the SDK. 196 AlwaysSdk bool `blueprint:"mutated"` 197 198 HideFromMake bool `blueprint:"mutated"` 199 PreventInstall bool `blueprint:"mutated"` 200 201 Installable *bool 202} 203 204type Module struct { 205 fuzz.FuzzModule 206 207 VendorProperties cc.VendorProperties 208 209 Properties BaseProperties 210 211 hod android.HostOrDeviceSupported 212 multilib android.Multilib 213 testModule bool 214 215 makeLinkType string 216 217 afdo *afdo 218 compiler compiler 219 coverage *coverage 220 clippy *clippy 221 sanitize *sanitize 222 cachedToolchain config.Toolchain 223 sourceProvider SourceProvider 224 subAndroidMkOnce map[SubAndroidMkProvider]bool 225 226 exportedLinkDirs []string 227 228 // Output file to be installed, may be stripped or unstripped. 229 outputFile android.OptionalPath 230 231 // Cross-reference input file 232 kytheFiles android.Paths 233 234 docTimestampFile android.OptionalPath 235 236 hideApexVariantFromMake bool 237 238 // For apex variants, this is set as apex.min_sdk_version 239 apexSdkVersion android.ApiLevel 240 241 transitiveAndroidMkSharedLibs depset.DepSet[string] 242 243 // Shared flags among stubs build rules of this module 244 sharedFlags cc.SharedFlags 245} 246 247func (mod *Module) Header() bool { 248 //TODO: If Rust libraries provide header variants, this needs to be updated. 249 return false 250} 251 252func (mod *Module) SetPreventInstall() { 253 mod.Properties.PreventInstall = true 254} 255 256func (mod *Module) SetHideFromMake() { 257 mod.Properties.HideFromMake = true 258} 259 260func (mod *Module) HiddenFromMake() bool { 261 return mod.Properties.HideFromMake 262} 263 264func (mod *Module) SanitizePropDefined() bool { 265 // Because compiler is not set for some Rust modules where sanitize might be set, check that compiler is also not 266 // nil since we need compiler to actually sanitize. 267 return mod.sanitize != nil && mod.compiler != nil 268} 269 270func (mod *Module) IsPrebuilt() bool { 271 if _, ok := mod.compiler.(*prebuiltLibraryDecorator); ok { 272 return true 273 } 274 return false 275} 276 277func (mod *Module) SelectedStl() string { 278 return "" 279} 280 281func (mod *Module) NonCcVariants() bool { 282 if mod.compiler != nil { 283 if library, ok := mod.compiler.(libraryInterface); ok { 284 return library.buildRlib() || library.buildDylib() 285 } 286 } 287 panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName())) 288} 289 290func (mod *Module) Static() bool { 291 if mod.compiler != nil { 292 if library, ok := mod.compiler.(libraryInterface); ok { 293 return library.static() 294 } 295 } 296 return false 297} 298 299func (mod *Module) Shared() bool { 300 if mod.compiler != nil { 301 if library, ok := mod.compiler.(libraryInterface); ok { 302 return library.shared() 303 } 304 } 305 return false 306} 307 308func (mod *Module) Dylib() bool { 309 if mod.compiler != nil { 310 if library, ok := mod.compiler.(libraryInterface); ok { 311 return library.dylib() 312 } 313 } 314 return false 315} 316 317func (mod *Module) Source() bool { 318 if mod.compiler != nil { 319 if library, ok := mod.compiler.(libraryInterface); ok && mod.sourceProvider != nil { 320 return library.source() 321 } 322 } 323 return false 324} 325 326func (mod *Module) RlibStd() bool { 327 if mod.compiler != nil { 328 if library, ok := mod.compiler.(libraryInterface); ok && library.rlib() { 329 return library.rlibStd() 330 } 331 } 332 panic(fmt.Errorf("RlibStd() called on non-rlib module: %q", mod.BaseModuleName())) 333} 334 335func (mod *Module) Rlib() bool { 336 if mod.compiler != nil { 337 if library, ok := mod.compiler.(libraryInterface); ok { 338 return library.rlib() 339 } 340 } 341 return false 342} 343 344func (mod *Module) Binary() bool { 345 if binary, ok := mod.compiler.(binaryInterface); ok { 346 return binary.binary() 347 } 348 return false 349} 350 351func (mod *Module) StaticExecutable() bool { 352 if !mod.Binary() { 353 return false 354 } 355 return mod.StaticallyLinked() 356} 357 358func (mod *Module) ApexExclude() bool { 359 if mod.compiler != nil { 360 if library, ok := mod.compiler.(libraryInterface); ok { 361 return library.apexExclude() 362 } 363 } 364 return false 365} 366 367func (mod *Module) Object() bool { 368 // Rust has no modules which produce only object files. 369 return false 370} 371 372func (mod *Module) Toc() android.OptionalPath { 373 if mod.compiler != nil { 374 if lib, ok := mod.compiler.(libraryInterface); ok { 375 return lib.toc() 376 } 377 } 378 panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName())) 379} 380 381func (mod *Module) UseSdk() bool { 382 return false 383} 384 385func (mod *Module) RelativeInstallPath() string { 386 if mod.compiler != nil { 387 return mod.compiler.relativeInstallPath() 388 } 389 return "" 390} 391 392func (mod *Module) UseVndk() bool { 393 return mod.Properties.VndkVersion != "" 394} 395 396func (mod *Module) Bootstrap() bool { 397 return Bool(mod.Properties.Bootstrap) 398} 399 400func (mod *Module) SubName() string { 401 return mod.Properties.SubName 402} 403 404func (mod *Module) IsVndkPrebuiltLibrary() bool { 405 // Rust modules do not provide VNDK prebuilts 406 return false 407} 408 409func (mod *Module) IsVendorPublicLibrary() bool { 410 // Rust modules do not currently support vendor_public_library 411 return false 412} 413 414func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool { 415 // Rust modules to not provide Sdk variants 416 return false 417} 418 419func (c *Module) IsVndkPrivate() bool { 420 // Rust modules do not currently support VNDK variants 421 return false 422} 423 424func (c *Module) IsLlndk() bool { 425 // Rust modules do not currently support LLNDK variants 426 return false 427} 428 429func (mod *Module) KernelHeadersDecorator() bool { 430 return false 431} 432 433func (m *Module) NeedsLlndkVariants() bool { 434 // Rust modules do not currently support LLNDK variants 435 return false 436} 437 438func (m *Module) NeedsVendorPublicLibraryVariants() bool { 439 // Rust modules do not currently support vendor_public_library 440 return false 441} 442 443func (mod *Module) HasLlndkStubs() bool { 444 // Rust modules do not currently support LLNDK stubs 445 return false 446} 447 448func (mod *Module) SdkVersion() string { 449 return String(mod.Properties.Sdk_version) 450} 451 452func (mod *Module) AlwaysSdk() bool { 453 return mod.Properties.AlwaysSdk 454} 455 456func (mod *Module) IsSdkVariant() bool { 457 return mod.Properties.IsSdkVariant 458} 459 460func (mod *Module) SplitPerApiLevel() bool { 461 return cc.CanUseSdk(mod) && mod.IsCrt() 462} 463 464func (mod *Module) XrefRustFiles() android.Paths { 465 return mod.kytheFiles 466} 467 468type Deps struct { 469 Dylibs []string 470 Rlibs []string 471 Rustlibs []string 472 Stdlibs []string 473 ProcMacros []string 474 SharedLibs []string 475 StaticLibs []string 476 WholeStaticLibs []string 477 HeaderLibs []string 478 479 // Used for data dependencies adjacent to tests 480 DataLibs []string 481 DataBins []string 482 483 CrtBegin, CrtEnd []string 484} 485 486type PathDeps struct { 487 DyLibs RustLibraries 488 RLibs RustLibraries 489 SharedLibs android.Paths 490 SharedLibDeps android.Paths 491 StaticLibs android.Paths 492 ProcMacros RustLibraries 493 AfdoProfiles android.Paths 494 LinkerDeps android.Paths 495 496 // depFlags and depLinkFlags are rustc and linker (clang) flags. 497 depFlags []string 498 depLinkFlags []string 499 500 // track cc static-libs that have Rlib dependencies 501 reexportedCcRlibDeps []cc.RustRlibDep 502 reexportedWholeCcRlibDeps []cc.RustRlibDep 503 ccRlibDeps []cc.RustRlibDep 504 505 // linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker 506 // Both of these are exported and propagate to dependencies. 507 linkDirs []string 508 rustLibObjects []string 509 staticLibObjects []string 510 wholeStaticLibObjects []string 511 sharedLibObjects []string 512 513 // exportedLinkDirs are exported linkDirs for direct rlib dependencies to 514 // cc_library_static dependants of rlibs. 515 // Track them separately from linkDirs so superfluous -L flags don't get emitted. 516 exportedLinkDirs []string 517 518 // Used by bindgen modules which call clang 519 depClangFlags []string 520 depIncludePaths android.Paths 521 depGeneratedHeaders android.Paths 522 depSystemIncludePaths android.Paths 523 524 CrtBegin android.Paths 525 CrtEnd android.Paths 526 527 // Paths to generated source files 528 SrcDeps android.Paths 529 srcProviderFiles android.Paths 530 531 directImplementationDeps android.Paths 532 transitiveImplementationDeps []depset.DepSet[android.Path] 533} 534 535type RustLibraries []RustLibrary 536 537type RustLibrary struct { 538 Path android.Path 539 CrateName string 540} 541 542type exportedFlagsProducer interface { 543 exportLinkDirs(...string) 544 exportRustLibs(...string) 545 exportStaticLibs(...string) 546 exportWholeStaticLibs(...string) 547 exportSharedLibs(...string) 548} 549 550type xref interface { 551 XrefRustFiles() android.Paths 552} 553 554type flagExporter struct { 555 linkDirs []string 556 ccLinkDirs []string 557 rustLibPaths []string 558 staticLibObjects []string 559 sharedLibObjects []string 560 wholeStaticLibObjects []string 561 wholeRustRlibDeps []cc.RustRlibDep 562} 563 564func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { 565 flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) 566} 567 568func (flagExporter *flagExporter) exportRustLibs(flags ...string) { 569 flagExporter.rustLibPaths = android.FirstUniqueStrings(append(flagExporter.rustLibPaths, flags...)) 570} 571 572func (flagExporter *flagExporter) exportStaticLibs(flags ...string) { 573 flagExporter.staticLibObjects = android.FirstUniqueStrings(append(flagExporter.staticLibObjects, flags...)) 574} 575 576func (flagExporter *flagExporter) exportSharedLibs(flags ...string) { 577 flagExporter.sharedLibObjects = android.FirstUniqueStrings(append(flagExporter.sharedLibObjects, flags...)) 578} 579 580func (flagExporter *flagExporter) exportWholeStaticLibs(flags ...string) { 581 flagExporter.wholeStaticLibObjects = android.FirstUniqueStrings(append(flagExporter.wholeStaticLibObjects, flags...)) 582} 583 584func (flagExporter *flagExporter) setRustProvider(ctx ModuleContext) { 585 android.SetProvider(ctx, RustFlagExporterInfoProvider, RustFlagExporterInfo{ 586 LinkDirs: flagExporter.linkDirs, 587 RustLibObjects: flagExporter.rustLibPaths, 588 StaticLibObjects: flagExporter.staticLibObjects, 589 WholeStaticLibObjects: flagExporter.wholeStaticLibObjects, 590 SharedLibPaths: flagExporter.sharedLibObjects, 591 WholeRustRlibDeps: flagExporter.wholeRustRlibDeps, 592 }) 593} 594 595var _ exportedFlagsProducer = (*flagExporter)(nil) 596 597func NewFlagExporter() *flagExporter { 598 return &flagExporter{} 599} 600 601type RustFlagExporterInfo struct { 602 Flags []string 603 LinkDirs []string 604 RustLibObjects []string 605 StaticLibObjects []string 606 WholeStaticLibObjects []string 607 SharedLibPaths []string 608 WholeRustRlibDeps []cc.RustRlibDep 609} 610 611var RustFlagExporterInfoProvider = blueprint.NewProvider[RustFlagExporterInfo]() 612 613func (mod *Module) isCoverageVariant() bool { 614 return mod.coverage.Properties.IsCoverageVariant 615} 616 617var _ cc.Coverage = (*Module)(nil) 618 619func (mod *Module) IsNativeCoverageNeeded(ctx cc.IsNativeCoverageNeededContext) bool { 620 return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant 621} 622 623func (mod *Module) VndkVersion() string { 624 return mod.Properties.VndkVersion 625} 626 627func (mod *Module) ExportedCrateLinkDirs() []string { 628 return mod.exportedLinkDirs 629} 630 631func (mod *Module) PreventInstall() bool { 632 return mod.Properties.PreventInstall 633} 634func (c *Module) ForceDisableSanitizers() { 635 c.sanitize.Properties.ForceDisable = true 636} 637 638func (mod *Module) MarkAsCoverageVariant(coverage bool) { 639 mod.coverage.Properties.IsCoverageVariant = coverage 640} 641 642func (mod *Module) EnableCoverageIfNeeded() { 643 mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild 644} 645 646func defaultsFactory() android.Module { 647 return DefaultsFactory() 648} 649 650type Defaults struct { 651 android.ModuleBase 652 android.DefaultsModuleBase 653} 654 655func DefaultsFactory(props ...interface{}) android.Module { 656 module := &Defaults{} 657 658 module.AddProperties(props...) 659 module.AddProperties( 660 &BaseProperties{}, 661 &cc.AfdoProperties{}, 662 &cc.VendorProperties{}, 663 &BenchmarkProperties{}, 664 &BindgenProperties{}, 665 &BaseCompilerProperties{}, 666 &BinaryCompilerProperties{}, 667 &LibraryCompilerProperties{}, 668 &ProcMacroCompilerProperties{}, 669 &PrebuiltProperties{}, 670 &SourceProviderProperties{}, 671 &TestProperties{}, 672 &cc.CoverageProperties{}, 673 &cc.RustBindgenClangProperties{}, 674 &ClippyProperties{}, 675 &SanitizeProperties{}, 676 &fuzz.FuzzProperties{}, 677 ) 678 679 android.InitDefaultsModule(module) 680 return module 681} 682 683func (mod *Module) CrateName() string { 684 return mod.compiler.crateName() 685} 686 687func (mod *Module) CcLibrary() bool { 688 if mod.compiler != nil { 689 if _, ok := mod.compiler.(libraryInterface); ok { 690 return true 691 } 692 } 693 return false 694} 695 696func (mod *Module) CcLibraryInterface() bool { 697 if mod.compiler != nil { 698 // use build{Static,Shared}() instead of {static,shared}() here because this might be called before 699 // VariantIs{Static,Shared} is set. 700 if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic() || lib.buildRlib()) { 701 return true 702 } 703 } 704 return false 705} 706 707func (mod *Module) RustLibraryInterface() bool { 708 if mod.compiler != nil { 709 if _, ok := mod.compiler.(libraryInterface); ok { 710 return true 711 } 712 } 713 return false 714} 715 716func (mod *Module) IsFuzzModule() bool { 717 if _, ok := mod.compiler.(*fuzzDecorator); ok { 718 return true 719 } 720 return false 721} 722 723func (mod *Module) FuzzModuleStruct() fuzz.FuzzModule { 724 return mod.FuzzModule 725} 726 727func (mod *Module) FuzzPackagedModule() fuzz.FuzzPackagedModule { 728 if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok { 729 return fuzzer.fuzzPackagedModule 730 } 731 panic(fmt.Errorf("FuzzPackagedModule called on non-fuzz module: %q", mod.BaseModuleName())) 732} 733 734func (mod *Module) FuzzSharedLibraries() android.RuleBuilderInstalls { 735 if fuzzer, ok := mod.compiler.(*fuzzDecorator); ok { 736 return fuzzer.sharedLibraries 737 } 738 panic(fmt.Errorf("FuzzSharedLibraries called on non-fuzz module: %q", mod.BaseModuleName())) 739} 740 741func (mod *Module) UnstrippedOutputFile() android.Path { 742 if mod.compiler != nil { 743 return mod.compiler.unstrippedOutputFilePath() 744 } 745 return nil 746} 747 748func (mod *Module) SetStatic() { 749 if mod.compiler != nil { 750 if library, ok := mod.compiler.(libraryInterface); ok { 751 library.setStatic() 752 return 753 } 754 } 755 panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName())) 756} 757 758func (mod *Module) SetShared() { 759 if mod.compiler != nil { 760 if library, ok := mod.compiler.(libraryInterface); ok { 761 library.setShared() 762 return 763 } 764 } 765 panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName())) 766} 767 768func (mod *Module) BuildStaticVariant() bool { 769 if mod.compiler != nil { 770 if library, ok := mod.compiler.(libraryInterface); ok { 771 return library.buildStatic() 772 } 773 } 774 panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) 775} 776 777func (mod *Module) BuildRlibVariant() bool { 778 if mod.compiler != nil { 779 if library, ok := mod.compiler.(libraryInterface); ok { 780 return library.buildRlib() 781 } 782 } 783 panic(fmt.Errorf("BuildRlibVariant called on non-library module: %q", mod.BaseModuleName())) 784} 785 786func (mod *Module) BuildSharedVariant() bool { 787 if mod.compiler != nil { 788 if library, ok := mod.compiler.(libraryInterface); ok { 789 return library.buildShared() 790 } 791 } 792 panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName())) 793} 794 795func (mod *Module) Module() android.Module { 796 return mod 797} 798 799func (mod *Module) OutputFile() android.OptionalPath { 800 return mod.outputFile 801} 802 803func (mod *Module) CoverageFiles() android.Paths { 804 if mod.compiler != nil { 805 return android.Paths{} 806 } 807 panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName())) 808} 809 810// Rust does not produce gcno files, and therefore does not produce a coverage archive. 811func (mod *Module) CoverageOutputFile() android.OptionalPath { 812 return android.OptionalPath{} 813} 814 815func (mod *Module) IsNdk(config android.Config) bool { 816 return false 817} 818 819func (mod *Module) IsStubs() bool { 820 if lib, ok := mod.compiler.(libraryInterface); ok { 821 return lib.BuildStubs() 822 } 823 return false 824} 825 826func (mod *Module) HasStubsVariants() bool { 827 if lib, ok := mod.compiler.(libraryInterface); ok { 828 return lib.HasStubsVariants() 829 } 830 return false 831} 832 833func (mod *Module) ApexSdkVersion() android.ApiLevel { 834 return mod.apexSdkVersion 835} 836 837func (mod *Module) RustApexExclude() bool { 838 return mod.ApexExclude() 839} 840 841func (mod *Module) getSharedFlags() *cc.SharedFlags { 842 shared := &mod.sharedFlags 843 if shared.FlagsMap == nil { 844 shared.NumSharedFlags = 0 845 shared.FlagsMap = make(map[string]string) 846 } 847 return shared 848} 849 850func (mod *Module) ImplementationModuleNameForMake() string { 851 name := mod.BaseModuleName() 852 if versioned, ok := mod.compiler.(cc.VersionedInterface); ok { 853 name = versioned.ImplementationModuleName(name) 854 } 855 return name 856} 857 858func (mod *Module) Multilib() string { 859 return mod.Arch().ArchType.Multilib 860} 861 862func (mod *Module) IsCrt() bool { 863 // Rust does not currently provide any crt modules. 864 return false 865} 866 867func (mod *Module) installable(apexInfo android.ApexInfo) bool { 868 if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) { 869 return false 870 } 871 872 // The apex variant is not installable because it is included in the APEX and won't appear 873 // in the system partition as a standalone file. 874 if !apexInfo.IsForPlatform() { 875 return false 876 } 877 878 return mod.OutputFile().Valid() && !mod.Properties.PreventInstall 879} 880 881func (ctx moduleContext) apexVariationName() string { 882 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 883 return apexInfo.ApexVariationName 884} 885 886var _ cc.LinkableInterface = (*Module)(nil) 887var _ cc.VersionedLinkableInterface = (*Module)(nil) 888 889func (mod *Module) Init() android.Module { 890 mod.AddProperties(&mod.Properties) 891 mod.AddProperties(&mod.VendorProperties) 892 893 if mod.afdo != nil { 894 mod.AddProperties(mod.afdo.props()...) 895 } 896 if mod.compiler != nil { 897 mod.AddProperties(mod.compiler.compilerProps()...) 898 } 899 if mod.coverage != nil { 900 mod.AddProperties(mod.coverage.props()...) 901 } 902 if mod.clippy != nil { 903 mod.AddProperties(mod.clippy.props()...) 904 } 905 if mod.sourceProvider != nil { 906 mod.AddProperties(mod.sourceProvider.SourceProviderProps()...) 907 } 908 if mod.sanitize != nil { 909 mod.AddProperties(mod.sanitize.props()...) 910 } 911 912 android.InitAndroidArchModule(mod, mod.hod, mod.multilib) 913 android.InitApexModule(mod) 914 915 android.InitDefaultableModule(mod) 916 return mod 917} 918 919func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 920 return &Module{ 921 hod: hod, 922 multilib: multilib, 923 } 924} 925func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 926 module := newBaseModule(hod, multilib) 927 module.afdo = &afdo{} 928 module.coverage = &coverage{} 929 module.clippy = &clippy{} 930 module.sanitize = &sanitize{} 931 return module 932} 933 934type ModuleContext interface { 935 android.ModuleContext 936 ModuleContextIntf 937} 938 939type BaseModuleContext interface { 940 android.BaseModuleContext 941 ModuleContextIntf 942} 943 944type DepsContext interface { 945 android.BottomUpMutatorContext 946 ModuleContextIntf 947} 948 949type ModuleContextIntf interface { 950 RustModule() *Module 951 toolchain() config.Toolchain 952} 953 954type depsContext struct { 955 android.BottomUpMutatorContext 956} 957 958type moduleContext struct { 959 android.ModuleContext 960} 961 962type baseModuleContext struct { 963 android.BaseModuleContext 964} 965 966func (ctx *moduleContext) RustModule() *Module { 967 return ctx.Module().(*Module) 968} 969 970func (ctx *moduleContext) toolchain() config.Toolchain { 971 return ctx.RustModule().toolchain(ctx) 972} 973 974func (ctx *depsContext) RustModule() *Module { 975 return ctx.Module().(*Module) 976} 977 978func (ctx *depsContext) toolchain() config.Toolchain { 979 return ctx.RustModule().toolchain(ctx) 980} 981 982func (ctx *baseModuleContext) RustModule() *Module { 983 return ctx.Module().(*Module) 984} 985 986func (ctx *baseModuleContext) toolchain() config.Toolchain { 987 return ctx.RustModule().toolchain(ctx) 988} 989 990func (mod *Module) nativeCoverage() bool { 991 // Bug: http://b/137883967 - native-bridge modules do not currently work with coverage 992 if mod.Target().NativeBridge == android.NativeBridgeEnabled { 993 return false 994 } 995 return mod.compiler != nil && mod.compiler.nativeCoverage() 996} 997 998func (mod *Module) SetStl(s string) { 999 // STL is a CC concept; do nothing for Rust 1000} 1001 1002func (mod *Module) SetSdkVersion(s string) { 1003 mod.Properties.Sdk_version = StringPtr(s) 1004} 1005 1006func (mod *Module) SetMinSdkVersion(s string) { 1007 mod.Properties.Min_sdk_version = StringPtr(s) 1008} 1009 1010func (mod *Module) VersionedInterface() cc.VersionedInterface { 1011 if _, ok := mod.compiler.(cc.VersionedInterface); ok { 1012 return mod.compiler.(cc.VersionedInterface) 1013 } 1014 return nil 1015} 1016 1017func (mod *Module) EverInstallable() bool { 1018 return mod.compiler != nil && 1019 // Check to see whether the module is actually ever installable. 1020 mod.compiler.everInstallable() 1021} 1022 1023func (mod *Module) Installable() *bool { 1024 return mod.Properties.Installable 1025} 1026 1027func (mod *Module) ProcMacro() bool { 1028 if pm, ok := mod.compiler.(procMacroInterface); ok { 1029 return pm.ProcMacro() 1030 } 1031 return false 1032} 1033 1034func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { 1035 if mod.cachedToolchain == nil { 1036 mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) 1037 } 1038 return mod.cachedToolchain 1039} 1040 1041func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchain { 1042 return cc_config.FindToolchain(ctx.Os(), ctx.Arch()) 1043} 1044 1045func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1046} 1047 1048func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { 1049 ctx := &moduleContext{ 1050 ModuleContext: actx, 1051 } 1052 1053 apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider) 1054 if !apexInfo.IsForPlatform() { 1055 mod.hideApexVariantFromMake = true 1056 } 1057 1058 toolchain := mod.toolchain(ctx) 1059 mod.makeLinkType = cc.GetMakeLinkType(actx, mod) 1060 1061 mod.Properties.SubName = cc.GetSubnameProperty(actx, mod) 1062 1063 if !toolchain.Supported() { 1064 // This toolchain's unsupported, there's nothing to do for this mod. 1065 return 1066 } 1067 1068 deps := mod.depsToPaths(ctx) 1069 // Export linkDirs for CC rust generatedlibs 1070 mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.exportedLinkDirs...) 1071 mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.linkDirs...) 1072 1073 flags := Flags{ 1074 Toolchain: toolchain, 1075 } 1076 1077 // Calculate rustc flags 1078 if mod.afdo != nil { 1079 flags, deps = mod.afdo.flags(actx, flags, deps) 1080 } 1081 if mod.compiler != nil { 1082 flags = mod.compiler.compilerFlags(ctx, flags) 1083 flags = mod.compiler.cfgFlags(ctx, flags) 1084 flags = mod.compiler.featureFlags(ctx, mod, flags) 1085 } 1086 if mod.coverage != nil { 1087 flags, deps = mod.coverage.flags(ctx, flags, deps) 1088 } 1089 if mod.clippy != nil { 1090 flags, deps = mod.clippy.flags(ctx, flags, deps) 1091 } 1092 if mod.sanitize != nil { 1093 flags, deps = mod.sanitize.flags(ctx, flags, deps) 1094 } 1095 1096 // SourceProvider needs to call GenerateSource() before compiler calls 1097 // compile() so it can provide the source. A SourceProvider has 1098 // multiple variants (e.g. source, rlib, dylib). Only the "source" 1099 // variant is responsible for effectively generating the source. The 1100 // remaining variants relies on the "source" variant output. 1101 if mod.sourceProvider != nil { 1102 if mod.compiler.(libraryInterface).source() { 1103 mod.sourceProvider.GenerateSource(ctx, deps) 1104 mod.sourceProvider.setSubName(ctx.ModuleSubDir()) 1105 } else { 1106 sourceMod := actx.GetDirectDepProxyWithTag(mod.Name(), sourceDepTag) 1107 sourceLib := android.OtherModuleProviderOrDefault(ctx, sourceMod, RustInfoProvider).SourceProviderInfo 1108 mod.sourceProvider.setOutputFiles(sourceLib.Srcs) 1109 } 1110 ctx.CheckbuildFile(mod.sourceProvider.Srcs()...) 1111 } 1112 1113 if mod.compiler != nil && !mod.compiler.Disabled() { 1114 mod.compiler.initialize(ctx) 1115 buildOutput := mod.compiler.compile(ctx, flags, deps) 1116 if ctx.Failed() { 1117 return 1118 } 1119 mod.outputFile = android.OptionalPathForPath(buildOutput.outputFile) 1120 ctx.CheckbuildFile(buildOutput.outputFile) 1121 if buildOutput.kytheFile != nil { 1122 mod.kytheFiles = append(mod.kytheFiles, buildOutput.kytheFile) 1123 } 1124 bloaty.MeasureSizeForPaths(ctx, mod.compiler.strippedOutputFilePath(), android.OptionalPathForPath(mod.compiler.unstrippedOutputFilePath())) 1125 1126 mod.docTimestampFile = mod.compiler.rustdoc(ctx, flags, deps) 1127 1128 apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider) 1129 if !proptools.BoolDefault(mod.Installable(), mod.EverInstallable()) && !mod.ProcMacro() { 1130 // If the module has been specifically configure to not be installed then 1131 // hide from make as otherwise it will break when running inside make as the 1132 // output path to install will not be specified. Not all uninstallable 1133 // modules can be hidden from make as some are needed for resolving make 1134 // side dependencies. In particular, proc-macros need to be captured in the 1135 // host snapshot. 1136 mod.HideFromMake() 1137 mod.SkipInstall() 1138 } else if !mod.installable(apexInfo) { 1139 mod.SkipInstall() 1140 } 1141 1142 // Still call install though, the installs will be stored as PackageSpecs to allow 1143 // using the outputs in a genrule. 1144 if mod.OutputFile().Valid() { 1145 mod.compiler.install(ctx) 1146 if ctx.Failed() { 1147 return 1148 } 1149 // Export your own directory as a linkDir 1150 mod.exportedLinkDirs = append(mod.exportedLinkDirs, linkPathFromFilePath(mod.OutputFile().Path())) 1151 1152 } 1153 1154 android.SetProvider(ctx, cc.ImplementationDepInfoProvider, &cc.ImplementationDepInfo{ 1155 ImplementationDeps: depset.New(depset.PREORDER, deps.directImplementationDeps, deps.transitiveImplementationDeps), 1156 }) 1157 1158 ctx.Phony("rust", ctx.RustModule().OutputFile().Path()) 1159 } 1160 1161 linkableInfo := cc.CreateCommonLinkableInfo(ctx, mod) 1162 linkableInfo.Static = mod.Static() 1163 linkableInfo.Shared = mod.Shared() 1164 linkableInfo.CrateName = mod.CrateName() 1165 linkableInfo.ExportedCrateLinkDirs = mod.ExportedCrateLinkDirs() 1166 if lib, ok := mod.compiler.(cc.VersionedInterface); ok { 1167 linkableInfo.StubsVersion = lib.StubsVersion() 1168 } 1169 1170 android.SetProvider(ctx, cc.LinkableInfoProvider, linkableInfo) 1171 1172 rustInfo := &RustInfo{ 1173 AndroidMkSuffix: mod.AndroidMkSuffix(), 1174 RustSubName: mod.Properties.RustSubName, 1175 TransitiveAndroidMkSharedLibs: mod.transitiveAndroidMkSharedLibs, 1176 XrefRustFiles: mod.XrefRustFiles(), 1177 DocTimestampFile: mod.docTimestampFile, 1178 } 1179 if mod.compiler != nil { 1180 rustInfo.CompilerInfo = &CompilerInfo{ 1181 NoStdlibs: mod.compiler.noStdlibs(), 1182 StdLinkageForDevice: mod.compiler.stdLinkage(true), 1183 StdLinkageForNonDevice: mod.compiler.stdLinkage(false), 1184 } 1185 if lib, ok := mod.compiler.(libraryInterface); ok { 1186 rustInfo.CompilerInfo.LibraryInfo = &LibraryInfo{ 1187 Dylib: lib.dylib(), 1188 Rlib: lib.rlib(), 1189 } 1190 } 1191 if lib, ok := mod.compiler.(cc.SnapshotInterface); ok { 1192 rustInfo.SnapshotInfo = &cc.SnapshotInfo{ 1193 SnapshotAndroidMkSuffix: lib.SnapshotAndroidMkSuffix(), 1194 } 1195 } 1196 } 1197 if mod.sourceProvider != nil { 1198 rustInfo.SourceProviderInfo = &SourceProviderInfo{ 1199 Srcs: mod.sourceProvider.Srcs(), 1200 } 1201 if _, ok := mod.sourceProvider.(*protobufDecorator); ok { 1202 rustInfo.SourceProviderInfo.ProtobufDecoratorInfo = &ProtobufDecoratorInfo{} 1203 } 1204 } 1205 android.SetProvider(ctx, RustInfoProvider, rustInfo) 1206 1207 ccInfo := &cc.CcInfo{ 1208 IsPrebuilt: mod.IsPrebuilt(), 1209 } 1210 1211 // Define the linker info if compiler != nil because Rust currently 1212 // does compilation and linking in one step. If this changes in the future, 1213 // move this as appropriate. 1214 baseCompilerProps := mod.compiler.baseCompilerProps() 1215 ccInfo.LinkerInfo = &cc.LinkerInfo{ 1216 WholeStaticLibs: baseCompilerProps.Whole_static_libs.GetOrDefault(ctx, nil), 1217 StaticLibs: baseCompilerProps.Static_libs.GetOrDefault(ctx, nil), 1218 SharedLibs: baseCompilerProps.Shared_libs.GetOrDefault(ctx, nil), 1219 } 1220 1221 android.SetProvider(ctx, cc.CcInfoProvider, ccInfo) 1222 1223 mod.setOutputFiles(ctx) 1224 1225 buildComplianceMetadataInfo(ctx, mod, deps) 1226 1227 moduleInfoJSON := ctx.ModuleInfoJSON() 1228 if mod.compiler != nil { 1229 mod.compiler.moduleInfoJSON(ctx, moduleInfoJSON) 1230 } 1231} 1232 1233func (mod *Module) setOutputFiles(ctx ModuleContext) { 1234 if mod.sourceProvider != nil && (mod.compiler == nil || mod.compiler.Disabled()) { 1235 ctx.SetOutputFiles(mod.sourceProvider.Srcs(), "") 1236 } else if mod.OutputFile().Valid() { 1237 ctx.SetOutputFiles(android.Paths{mod.OutputFile().Path()}, "") 1238 } else { 1239 ctx.SetOutputFiles(android.Paths{}, "") 1240 } 1241 if mod.compiler != nil { 1242 ctx.SetOutputFiles(android.PathsIfNonNil(mod.compiler.unstrippedOutputFilePath()), "unstripped") 1243 } 1244} 1245 1246func buildComplianceMetadataInfo(ctx *moduleContext, mod *Module, deps PathDeps) { 1247 // Dump metadata that can not be done in android/compliance-metadata.go 1248 metadataInfo := ctx.ComplianceMetadataInfo() 1249 metadataInfo.SetStringValue(android.ComplianceMetadataProp.IS_STATIC_LIB, strconv.FormatBool(mod.Static())) 1250 metadataInfo.SetStringValue(android.ComplianceMetadataProp.BUILT_FILES, mod.outputFile.String()) 1251 1252 // Static libs 1253 staticDeps := ctx.GetDirectDepsProxyWithTag(rlibDepTag) 1254 staticDepNames := make([]string, 0, len(staticDeps)) 1255 for _, dep := range staticDeps { 1256 staticDepNames = append(staticDepNames, dep.Name()) 1257 } 1258 ccStaticDeps := ctx.GetDirectDepsProxyWithTag(cc.StaticDepTag(false)) 1259 for _, dep := range ccStaticDeps { 1260 staticDepNames = append(staticDepNames, dep.Name()) 1261 } 1262 1263 staticDepPaths := make([]string, 0, len(deps.StaticLibs)+len(deps.RLibs)) 1264 // C static libraries 1265 for _, dep := range deps.StaticLibs { 1266 staticDepPaths = append(staticDepPaths, dep.String()) 1267 } 1268 // Rust static libraries 1269 for _, dep := range deps.RLibs { 1270 staticDepPaths = append(staticDepPaths, dep.Path.String()) 1271 } 1272 metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) 1273 metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEP_FILES, android.FirstUniqueStrings(staticDepPaths)) 1274 1275 // C Whole static libs 1276 ccWholeStaticDeps := ctx.GetDirectDepsProxyWithTag(cc.StaticDepTag(true)) 1277 wholeStaticDepNames := make([]string, 0, len(ccWholeStaticDeps)) 1278 for _, dep := range ccStaticDeps { 1279 wholeStaticDepNames = append(wholeStaticDepNames, dep.Name()) 1280 } 1281 metadataInfo.SetListValue(android.ComplianceMetadataProp.STATIC_DEPS, android.FirstUniqueStrings(staticDepNames)) 1282} 1283 1284func (mod *Module) deps(ctx DepsContext) Deps { 1285 deps := Deps{} 1286 1287 if mod.compiler != nil { 1288 deps = mod.compiler.compilerDeps(ctx, deps) 1289 } 1290 if mod.sourceProvider != nil { 1291 deps = mod.sourceProvider.SourceProviderDeps(ctx, deps) 1292 } 1293 1294 if mod.coverage != nil { 1295 deps = mod.coverage.deps(ctx, deps) 1296 } 1297 1298 if mod.sanitize != nil { 1299 deps = mod.sanitize.deps(ctx, deps) 1300 } 1301 1302 deps.Rlibs = android.LastUniqueStrings(deps.Rlibs) 1303 deps.Dylibs = android.LastUniqueStrings(deps.Dylibs) 1304 deps.Rustlibs = android.LastUniqueStrings(deps.Rustlibs) 1305 deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros) 1306 deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs) 1307 deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs) 1308 deps.Stdlibs = android.LastUniqueStrings(deps.Stdlibs) 1309 deps.WholeStaticLibs = android.LastUniqueStrings(deps.WholeStaticLibs) 1310 return deps 1311 1312} 1313 1314type dependencyTag struct { 1315 blueprint.BaseDependencyTag 1316 name string 1317 library bool 1318 procMacro bool 1319 dynamic bool 1320} 1321 1322// InstallDepNeeded returns true for rlibs, dylibs, and proc macros so that they or their transitive 1323// dependencies (especially C/C++ shared libs) are installed as dependencies of a rust binary. 1324func (d dependencyTag) InstallDepNeeded() bool { 1325 return d.library || d.procMacro 1326} 1327 1328var _ android.InstallNeededDependencyTag = dependencyTag{} 1329 1330func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { 1331 if d.library && d.dynamic { 1332 return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} 1333 } 1334 return nil 1335} 1336 1337func (d dependencyTag) PropagateAconfigValidation() bool { 1338 return d == rlibDepTag || d == sourceDepTag 1339} 1340 1341var _ android.PropagateAconfigValidationDependencyTag = dependencyTag{} 1342 1343var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} 1344 1345var ( 1346 customBindgenDepTag = dependencyTag{name: "customBindgenTag"} 1347 rlibDepTag = dependencyTag{name: "rlibTag", library: true} 1348 dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true} 1349 procMacroDepTag = dependencyTag{name: "procMacro", procMacro: true} 1350 sourceDepTag = dependencyTag{name: "source"} 1351 dataLibDepTag = dependencyTag{name: "data lib"} 1352 dataBinDepTag = dependencyTag{name: "data bin"} 1353) 1354 1355func IsDylibDepTag(depTag blueprint.DependencyTag) bool { 1356 tag, ok := depTag.(dependencyTag) 1357 return ok && tag == dylibDepTag 1358} 1359 1360func IsRlibDepTag(depTag blueprint.DependencyTag) bool { 1361 tag, ok := depTag.(dependencyTag) 1362 return ok && tag == rlibDepTag 1363} 1364 1365type autoDep struct { 1366 variation string 1367 depTag dependencyTag 1368} 1369 1370var ( 1371 sourceVariation = "source" 1372 rlibVariation = "rlib" 1373 dylibVariation = "dylib" 1374 rlibAutoDep = autoDep{variation: rlibVariation, depTag: rlibDepTag} 1375 dylibAutoDep = autoDep{variation: dylibVariation, depTag: dylibDepTag} 1376) 1377 1378type autoDeppable interface { 1379 autoDep(ctx android.BottomUpMutatorContext) autoDep 1380} 1381 1382func (mod *Module) begin(ctx BaseModuleContext) { 1383 if mod.coverage != nil { 1384 mod.coverage.begin(ctx) 1385 } 1386 if mod.sanitize != nil { 1387 mod.sanitize.begin(ctx) 1388 } 1389 1390 if mod.UseSdk() && mod.IsSdkVariant() { 1391 sdkVersion := "" 1392 if ctx.Device() { 1393 sdkVersion = mod.SdkVersion() 1394 } 1395 version, err := cc.NativeApiLevelFromUser(ctx, sdkVersion) 1396 if err != nil { 1397 ctx.PropertyErrorf("sdk_version", err.Error()) 1398 mod.Properties.Sdk_version = nil 1399 } else { 1400 mod.Properties.Sdk_version = StringPtr(version.String()) 1401 } 1402 } 1403 1404} 1405 1406func (mod *Module) Prebuilt() *android.Prebuilt { 1407 if p, ok := mod.compiler.(rustPrebuilt); ok { 1408 return p.prebuilt() 1409 } 1410 return nil 1411} 1412 1413func (mod *Module) Symlinks() []string { 1414 // TODO update this to return the list of symlinks when Rust supports defining symlinks 1415 return nil 1416} 1417 1418func rustMakeLibName(rustInfo *RustInfo, linkableInfo *cc.LinkableInfo, commonInfo *android.CommonModuleInfo, depName string) string { 1419 if rustInfo != nil { 1420 // Use base module name for snapshots when exporting to Makefile. 1421 if rustInfo.SnapshotInfo != nil { 1422 baseName := commonInfo.BaseModuleName 1423 return baseName + rustInfo.SnapshotInfo.SnapshotAndroidMkSuffix + rustInfo.AndroidMkSuffix 1424 } 1425 } 1426 return cc.MakeLibName(nil, linkableInfo, commonInfo, depName) 1427} 1428 1429func collectIncludedProtos(mod *Module, rustInfo *RustInfo, linkableInfo *cc.LinkableInfo) { 1430 if protoMod, ok := mod.sourceProvider.(*protobufDecorator); ok { 1431 if rustInfo.SourceProviderInfo.ProtobufDecoratorInfo != nil { 1432 protoMod.additionalCrates = append(protoMod.additionalCrates, linkableInfo.CrateName) 1433 } 1434 } 1435} 1436 1437func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 1438 var depPaths PathDeps 1439 1440 directRlibDeps := []*cc.LinkableInfo{} 1441 directDylibDeps := []*cc.LinkableInfo{} 1442 directProcMacroDeps := []*cc.LinkableInfo{} 1443 directSharedLibDeps := []cc.SharedLibraryInfo{} 1444 directStaticLibDeps := [](*cc.LinkableInfo){} 1445 directSrcProvidersDeps := []*android.ModuleProxy{} 1446 directSrcDeps := []android.SourceFilesInfo{} 1447 1448 // For the dependency from platform to apex, use the latest stubs 1449 mod.apexSdkVersion = android.FutureApiLevel 1450 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 1451 if !apexInfo.IsForPlatform() { 1452 mod.apexSdkVersion = apexInfo.MinSdkVersion 1453 } 1454 1455 if android.InList("hwaddress", ctx.Config().SanitizeDevice()) { 1456 // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000) 1457 // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)). 1458 // (b/144430859) 1459 mod.apexSdkVersion = android.FutureApiLevel 1460 } 1461 1462 skipModuleList := map[string]bool{} 1463 1464 var transitiveAndroidMkSharedLibs []depset.DepSet[string] 1465 var directAndroidMkSharedLibs []string 1466 1467 ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) { 1468 depName := ctx.OtherModuleName(dep) 1469 depTag := ctx.OtherModuleDependencyTag(dep) 1470 modStdLinkage := mod.compiler.stdLinkage(ctx.Device()) 1471 1472 if _, exists := skipModuleList[depName]; exists { 1473 return 1474 } 1475 1476 if depTag == android.DarwinUniversalVariantTag { 1477 return 1478 } 1479 1480 rustInfo, hasRustInfo := android.OtherModuleProvider(ctx, dep, RustInfoProvider) 1481 ccInfo, _ := android.OtherModuleProvider(ctx, dep, cc.CcInfoProvider) 1482 linkableInfo, hasLinkableInfo := android.OtherModuleProvider(ctx, dep, cc.LinkableInfoProvider) 1483 commonInfo := android.OtherModulePointerProviderOrDefault(ctx, dep, android.CommonModuleInfoProvider) 1484 if hasRustInfo && !linkableInfo.Static && !linkableInfo.Shared { 1485 //Handle Rust Modules 1486 makeLibName := rustMakeLibName(rustInfo, linkableInfo, commonInfo, depName+rustInfo.RustSubName) 1487 1488 switch { 1489 case depTag == dylibDepTag: 1490 dylib := rustInfo.CompilerInfo.LibraryInfo 1491 if dylib == nil || !dylib.Dylib { 1492 ctx.ModuleErrorf("mod %q not an dylib library", depName) 1493 return 1494 } 1495 directDylibDeps = append(directDylibDeps, linkableInfo) 1496 mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName) 1497 mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName)) 1498 1499 depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, "")) 1500 if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok { 1501 depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps) 1502 } 1503 1504 if !rustInfo.CompilerInfo.NoStdlibs { 1505 rustDepStdLinkage := rustInfo.CompilerInfo.StdLinkageForNonDevice 1506 if ctx.Device() { 1507 rustDepStdLinkage = rustInfo.CompilerInfo.StdLinkageForDevice 1508 } 1509 if rustDepStdLinkage != modStdLinkage { 1510 ctx.ModuleErrorf("Rust dependency %q has the wrong StdLinkage; expected %#v, got %#v", depName, modStdLinkage, rustDepStdLinkage) 1511 return 1512 } 1513 } 1514 1515 case depTag == rlibDepTag: 1516 rlib := rustInfo.CompilerInfo.LibraryInfo 1517 if rlib == nil || !rlib.Rlib { 1518 ctx.ModuleErrorf("mod %q not an rlib library", makeLibName) 1519 return 1520 } 1521 directRlibDeps = append(directRlibDeps, linkableInfo) 1522 mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName) 1523 mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName)) 1524 1525 // rust_ffi rlibs may export include dirs, so collect those here. 1526 exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) 1527 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1528 depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(linkableInfo.OutputFile.Path())) 1529 1530 // rlibs are not installed, so don't add the output file to directImplementationDeps 1531 if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok { 1532 depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps) 1533 } 1534 1535 if !rustInfo.CompilerInfo.NoStdlibs { 1536 rustDepStdLinkage := rustInfo.CompilerInfo.StdLinkageForNonDevice 1537 if ctx.Device() { 1538 rustDepStdLinkage = rustInfo.CompilerInfo.StdLinkageForDevice 1539 } 1540 if rustDepStdLinkage != modStdLinkage { 1541 ctx.ModuleErrorf("Rust dependency %q has the wrong StdLinkage; expected %#v, got %#v", depName, modStdLinkage, rustDepStdLinkage) 1542 return 1543 } 1544 } 1545 1546 if !mod.Rlib() { 1547 depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...) 1548 } else { 1549 // rlibs need to reexport these 1550 depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...) 1551 } 1552 1553 case depTag == procMacroDepTag: 1554 directProcMacroDeps = append(directProcMacroDeps, linkableInfo) 1555 mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName) 1556 // proc_macro link dirs need to be exported, so collect those here. 1557 depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(linkableInfo.OutputFile.Path())) 1558 1559 case depTag == sourceDepTag: 1560 if _, ok := mod.sourceProvider.(*protobufDecorator); ok { 1561 collectIncludedProtos(mod, rustInfo, linkableInfo) 1562 } 1563 case cc.IsStaticDepTag(depTag): 1564 // Rust FFI rlibs should not be declared in a Rust modules 1565 // "static_libs" list as we can't handle them properly at the 1566 // moment (for example, they only produce an rlib-std variant). 1567 // Instead, a normal rust_library variant should be used. 1568 ctx.PropertyErrorf("static_libs", 1569 "found '%s' in static_libs; use a rust_library module in rustlibs instead of a rust_ffi module in static_libs", 1570 depName) 1571 1572 } 1573 1574 transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustInfo.TransitiveAndroidMkSharedLibs) 1575 1576 if android.IsSourceDepTagWithOutputTag(depTag, "") { 1577 // Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct 1578 // OS/Arch variant is used. 1579 var helper string 1580 if ctx.Host() { 1581 helper = "missing 'host_supported'?" 1582 } else { 1583 helper = "device module defined?" 1584 } 1585 1586 if commonInfo.Target.Os != ctx.Os() { 1587 ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper) 1588 return 1589 } else if commonInfo.Target.Arch.ArchType != ctx.Arch().ArchType { 1590 ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper) 1591 return 1592 } 1593 directSrcProvidersDeps = append(directSrcProvidersDeps, &dep) 1594 } 1595 1596 exportedRustInfo, _ := android.OtherModuleProvider(ctx, dep, RustFlagExporterInfoProvider) 1597 exportedInfo, _ := android.OtherModuleProvider(ctx, dep, RustFlagExporterInfoProvider) 1598 //Append the dependencies exported objects, except for proc-macros which target a different arch/OS 1599 if depTag != procMacroDepTag { 1600 depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...) 1601 depPaths.rustLibObjects = append(depPaths.rustLibObjects, exportedInfo.RustLibObjects...) 1602 depPaths.sharedLibObjects = append(depPaths.sharedLibObjects, exportedInfo.SharedLibPaths...) 1603 depPaths.staticLibObjects = append(depPaths.staticLibObjects, exportedInfo.StaticLibObjects...) 1604 depPaths.wholeStaticLibObjects = append(depPaths.wholeStaticLibObjects, exportedInfo.WholeStaticLibObjects...) 1605 depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...) 1606 1607 depPaths.reexportedWholeCcRlibDeps = append(depPaths.reexportedWholeCcRlibDeps, exportedRustInfo.WholeRustRlibDeps...) 1608 if !mod.Rlib() { 1609 depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedRustInfo.WholeRustRlibDeps...) 1610 } 1611 } 1612 1613 if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { 1614 linkFile := linkableInfo.UnstrippedOutputFile 1615 linkDir := linkPathFromFilePath(linkFile) 1616 if lib, ok := mod.compiler.(exportedFlagsProducer); ok { 1617 lib.exportLinkDirs(linkDir) 1618 } 1619 } 1620 1621 if depTag == sourceDepTag { 1622 if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() { 1623 if rustInfo.SourceProviderInfo.ProtobufDecoratorInfo != nil { 1624 exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) 1625 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1626 } 1627 } 1628 } 1629 } else if hasLinkableInfo { 1630 //Handle C dependencies 1631 makeLibName := cc.MakeLibName(ccInfo, linkableInfo, commonInfo, depName) 1632 if !hasRustInfo { 1633 if commonInfo.Target.Os != ctx.Os() { 1634 ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) 1635 return 1636 } 1637 if commonInfo.Target.Arch.ArchType != ctx.Arch().ArchType { 1638 ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) 1639 return 1640 } 1641 } 1642 ccLibPath := linkableInfo.OutputFile 1643 if !ccLibPath.Valid() { 1644 if !ctx.Config().AllowMissingDependencies() { 1645 ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) 1646 } else { 1647 ctx.AddMissingDependencies([]string{depName}) 1648 } 1649 return 1650 } 1651 1652 linkPath := linkPathFromFilePath(ccLibPath.Path()) 1653 1654 exportDep := false 1655 switch { 1656 case cc.IsStaticDepTag(depTag): 1657 if cc.IsWholeStaticLib(depTag) { 1658 // rustc will bundle static libraries when they're passed with "-lstatic=<lib>". This will fail 1659 // if the library is not prefixed by "lib". 1660 if mod.Binary() { 1661 // Since binaries don't need to 'rebundle' these like libraries and only use these for the 1662 // final linkage, pass the args directly to the linker to handle these cases. 1663 depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", ccLibPath.Path().String(), "-Wl,--no-whole-archive"}...) 1664 } else if libName, ok := libNameFromFilePath(ccLibPath.Path()); ok { 1665 depPaths.depFlags = append(depPaths.depFlags, "-lstatic:+whole-archive="+libName) 1666 depPaths.depLinkFlags = append(depPaths.depLinkFlags, ccLibPath.Path().String()) 1667 } else { 1668 ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName()) 1669 } 1670 } 1671 1672 exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) 1673 if cc.IsWholeStaticLib(depTag) { 1674 // Add whole staticlibs to wholeStaticLibObjects to propagate to Rust all dependents. 1675 depPaths.wholeStaticLibObjects = append(depPaths.wholeStaticLibObjects, ccLibPath.String()) 1676 1677 // We also propagate forward whole-static'd cc staticlibs with rust_ffi_rlib dependencies 1678 // We don't need to check a hypothetical exportedRustInfo.WholeRustRlibDeps because we 1679 // wouldn't expect a rust_ffi_rlib to be listed in `static_libs` (Soong explicitly disallows this) 1680 depPaths.reexportedWholeCcRlibDeps = append(depPaths.reexportedWholeCcRlibDeps, exportedInfo.RustRlibDeps...) 1681 } else { 1682 // If not whole_static, add to staticLibObjects, which only propagate through rlibs to their dependents. 1683 depPaths.staticLibObjects = append(depPaths.staticLibObjects, ccLibPath.String()) 1684 1685 if mod.Rlib() { 1686 // rlibs propagate their inherited rust_ffi_rlibs forward. 1687 depPaths.reexportedCcRlibDeps = append(depPaths.reexportedCcRlibDeps, exportedInfo.RustRlibDeps...) 1688 } 1689 } 1690 1691 depPaths.linkDirs = append(depPaths.linkDirs, linkPath) 1692 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1693 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) 1694 depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) 1695 depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) 1696 1697 if !mod.Rlib() { 1698 // rlibs don't need to build the generated static library, so they don't need to track these. 1699 depPaths.ccRlibDeps = append(depPaths.ccRlibDeps, exportedInfo.RustRlibDeps...) 1700 } 1701 1702 directStaticLibDeps = append(directStaticLibDeps, linkableInfo) 1703 1704 // Record baseLibName for snapshots. 1705 mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName)) 1706 1707 mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, makeLibName) 1708 case cc.IsSharedDepTag(depTag): 1709 // For the shared lib dependencies, we may link to the stub variant 1710 // of the dependency depending on the context (e.g. if this 1711 // dependency crosses the APEX boundaries). 1712 sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep) 1713 1714 if !sharedLibraryInfo.IsStubs { 1715 // TODO(b/362509506): remove this additional check once all apex_exclude uses are switched to stubs. 1716 if !linkableInfo.RustApexExclude { 1717 depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, "")) 1718 if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok { 1719 depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps) 1720 } 1721 } 1722 } 1723 1724 // Re-get linkObject as ChooseStubOrImpl actually tells us which 1725 // object (either from stub or non-stub) to use. 1726 ccLibPath = android.OptionalPathForPath(sharedLibraryInfo.SharedLibrary) 1727 if !ccLibPath.Valid() { 1728 if !ctx.Config().AllowMissingDependencies() { 1729 ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) 1730 } else { 1731 ctx.AddMissingDependencies([]string{depName}) 1732 } 1733 return 1734 } 1735 linkPath = linkPathFromFilePath(ccLibPath.Path()) 1736 1737 depPaths.linkDirs = append(depPaths.linkDirs, linkPath) 1738 depPaths.sharedLibObjects = append(depPaths.sharedLibObjects, ccLibPath.String()) 1739 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1740 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) 1741 depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...) 1742 depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) 1743 directSharedLibDeps = append(directSharedLibDeps, sharedLibraryInfo) 1744 1745 // Record baseLibName for snapshots. 1746 mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName)) 1747 1748 directAndroidMkSharedLibs = append(directAndroidMkSharedLibs, makeLibName) 1749 exportDep = true 1750 case cc.IsHeaderDepTag(depTag): 1751 exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider) 1752 depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...) 1753 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...) 1754 depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...) 1755 mod.Properties.AndroidMkHeaderLibs = append(mod.Properties.AndroidMkHeaderLibs, makeLibName) 1756 case depTag == cc.CrtBeginDepTag: 1757 depPaths.CrtBegin = append(depPaths.CrtBegin, ccLibPath.Path()) 1758 case depTag == cc.CrtEndDepTag: 1759 depPaths.CrtEnd = append(depPaths.CrtEnd, ccLibPath.Path()) 1760 } 1761 1762 // Make sure shared dependencies are propagated 1763 if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { 1764 lib.exportLinkDirs(linkPath) 1765 lib.exportSharedLibs(ccLibPath.String()) 1766 } 1767 } else { 1768 switch { 1769 case depTag == cc.CrtBeginDepTag: 1770 depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, "")) 1771 case depTag == cc.CrtEndDepTag: 1772 depPaths.CrtEnd = append(depPaths.CrtEnd, android.OutputFileForModule(ctx, dep, "")) 1773 } 1774 } 1775 1776 if srcDep, ok := android.OtherModuleProvider(ctx, dep, android.SourceFilesInfoProvider); ok { 1777 if android.IsSourceDepTagWithOutputTag(depTag, "") { 1778 // These are usually genrules which don't have per-target variants. 1779 directSrcDeps = append(directSrcDeps, srcDep) 1780 } 1781 } 1782 }) 1783 1784 mod.transitiveAndroidMkSharedLibs = depset.New[string](depset.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs) 1785 1786 var rlibDepFiles RustLibraries 1787 aliases := mod.compiler.Aliases() 1788 for _, dep := range directRlibDeps { 1789 crateName := dep.CrateName 1790 if alias, aliased := aliases[crateName]; aliased { 1791 crateName = alias 1792 } 1793 rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile, CrateName: crateName}) 1794 } 1795 var dylibDepFiles RustLibraries 1796 for _, dep := range directDylibDeps { 1797 crateName := dep.CrateName 1798 if alias, aliased := aliases[crateName]; aliased { 1799 crateName = alias 1800 } 1801 dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile, CrateName: crateName}) 1802 } 1803 var procMacroDepFiles RustLibraries 1804 for _, dep := range directProcMacroDeps { 1805 crateName := dep.CrateName 1806 if alias, aliased := aliases[crateName]; aliased { 1807 crateName = alias 1808 } 1809 procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile, CrateName: crateName}) 1810 } 1811 1812 var staticLibDepFiles android.Paths 1813 for _, dep := range directStaticLibDeps { 1814 staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile.Path()) 1815 } 1816 1817 var sharedLibFiles android.Paths 1818 var sharedLibDepFiles android.Paths 1819 for _, dep := range directSharedLibDeps { 1820 sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary) 1821 if dep.TableOfContents.Valid() { 1822 sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path()) 1823 } else { 1824 sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary) 1825 } 1826 } 1827 1828 var srcProviderDepFiles android.Paths 1829 for _, dep := range directSrcProvidersDeps { 1830 srcs := android.OutputFilesForModule(ctx, *dep, "") 1831 srcProviderDepFiles = append(srcProviderDepFiles, srcs...) 1832 } 1833 for _, dep := range directSrcDeps { 1834 srcs := dep.Srcs 1835 srcProviderDepFiles = append(srcProviderDepFiles, srcs...) 1836 } 1837 1838 depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) 1839 depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) 1840 depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...) 1841 depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...) 1842 depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) 1843 depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...) 1844 depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...) 1845 1846 // Dedup exported flags from dependencies 1847 depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs) 1848 depPaths.rustLibObjects = android.FirstUniqueStrings(depPaths.rustLibObjects) 1849 depPaths.staticLibObjects = android.FirstUniqueStrings(depPaths.staticLibObjects) 1850 depPaths.wholeStaticLibObjects = android.FirstUniqueStrings(depPaths.wholeStaticLibObjects) 1851 depPaths.sharedLibObjects = android.FirstUniqueStrings(depPaths.sharedLibObjects) 1852 depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) 1853 depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags) 1854 depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) 1855 depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths) 1856 depPaths.depLinkFlags = android.FirstUniqueStrings(depPaths.depLinkFlags) 1857 depPaths.reexportedCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedCcRlibDeps, cc.EqRustRlibDeps) 1858 depPaths.reexportedWholeCcRlibDeps = android.FirstUniqueFunc(depPaths.reexportedWholeCcRlibDeps, cc.EqRustRlibDeps) 1859 depPaths.ccRlibDeps = android.FirstUniqueFunc(depPaths.ccRlibDeps, cc.EqRustRlibDeps) 1860 1861 return depPaths 1862} 1863 1864func (mod *Module) InstallInData() bool { 1865 if mod.compiler == nil { 1866 return false 1867 } 1868 return mod.compiler.inData() 1869} 1870 1871func (mod *Module) InstallInRamdisk() bool { 1872 return mod.InRamdisk() 1873} 1874 1875func (mod *Module) InstallInVendorRamdisk() bool { 1876 return mod.InVendorRamdisk() 1877} 1878 1879func (mod *Module) InstallInRecovery() bool { 1880 return mod.InRecovery() 1881} 1882 1883func linkPathFromFilePath(filepath android.Path) string { 1884 return strings.Split(filepath.String(), filepath.Base())[0] 1885} 1886 1887// usePublicApi returns true if the rust variant should link against NDK (publicapi) 1888func (r *Module) usePublicApi() bool { 1889 return r.Device() && r.UseSdk() 1890} 1891 1892// useVendorApi returns true if the rust variant should link against LLNDK (vendorapi) 1893func (r *Module) useVendorApi() bool { 1894 return r.Device() && (r.InVendor() || r.InProduct()) 1895} 1896 1897func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 1898 ctx := &depsContext{ 1899 BottomUpMutatorContext: actx, 1900 } 1901 1902 deps := mod.deps(ctx) 1903 var commonDepVariations []blueprint.Variation 1904 1905 if ctx.Os() == android.Android { 1906 deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs) 1907 } 1908 1909 stdLinkage := "dylib-std" 1910 if mod.compiler.stdLinkage(ctx.Device()) == RlibLinkage { 1911 stdLinkage = "rlib-std" 1912 } 1913 1914 rlibDepVariations := commonDepVariations 1915 1916 if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() { 1917 rlibDepVariations = append(rlibDepVariations, 1918 blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage}) 1919 } 1920 1921 // rlibs 1922 rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation}) 1923 for _, lib := range deps.Rlibs { 1924 depTag := rlibDepTag 1925 actx.AddVariationDependencies(rlibDepVariations, depTag, lib) 1926 } 1927 1928 // dylibs 1929 dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation}) 1930 1931 for _, lib := range deps.Dylibs { 1932 actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib) 1933 } 1934 1935 // rustlibs 1936 if deps.Rustlibs != nil { 1937 if !mod.compiler.Disabled() { 1938 for _, lib := range deps.Rustlibs { 1939 autoDep := mod.compiler.(autoDeppable).autoDep(ctx) 1940 if autoDep.depTag == rlibDepTag { 1941 // Handle the rlib deptag case 1942 actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib) 1943 1944 } else { 1945 // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however. 1946 // Check for the existence of the dylib deptag variant. Select it if available, 1947 // otherwise select the rlib variant. 1948 autoDepVariations := append(commonDepVariations, 1949 blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}) 1950 if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) { 1951 actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib) 1952 1953 } else { 1954 // If there's no dylib dependency available, try to add the rlib dependency instead. 1955 actx.AddVariationDependencies(rlibDepVariations, rlibDepTag, lib) 1956 1957 } 1958 } 1959 } 1960 } else if _, ok := mod.sourceProvider.(*protobufDecorator); ok { 1961 for _, lib := range deps.Rustlibs { 1962 srcProviderVariations := append(commonDepVariations, 1963 blueprint.Variation{Mutator: "rust_libraries", Variation: sourceVariation}) 1964 1965 // Only add rustlib dependencies if they're source providers themselves. 1966 // This is used to track which crate names need to be added to the source generated 1967 // in the rust_protobuf mod.rs. 1968 if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) { 1969 actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib) 1970 } 1971 } 1972 } 1973 } 1974 1975 // stdlibs 1976 if deps.Stdlibs != nil { 1977 if mod.compiler.stdLinkage(ctx.Device()) == RlibLinkage { 1978 for _, lib := range deps.Stdlibs { 1979 actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...), 1980 rlibDepTag, lib) 1981 } 1982 } else { 1983 for _, lib := range deps.Stdlibs { 1984 actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib) 1985 1986 } 1987 } 1988 } 1989 1990 for _, lib := range deps.SharedLibs { 1991 depTag := cc.SharedDepTag() 1992 name, version := cc.StubsLibNameAndVersion(lib) 1993 1994 variations := []blueprint.Variation{ 1995 {Mutator: "link", Variation: "shared"}, 1996 } 1997 cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false) 1998 } 1999 2000 for _, lib := range deps.WholeStaticLibs { 2001 depTag := cc.StaticDepTag(true) 2002 2003 actx.AddVariationDependencies([]blueprint.Variation{ 2004 {Mutator: "link", Variation: "static"}, 2005 }, depTag, lib) 2006 } 2007 2008 for _, lib := range deps.StaticLibs { 2009 depTag := cc.StaticDepTag(false) 2010 2011 actx.AddVariationDependencies([]blueprint.Variation{ 2012 {Mutator: "link", Variation: "static"}, 2013 }, depTag, lib) 2014 } 2015 2016 actx.AddVariationDependencies(nil, cc.HeaderDepTag(), deps.HeaderLibs...) 2017 2018 crtVariations := cc.GetCrtVariations(ctx, mod) 2019 for _, crt := range deps.CrtBegin { 2020 actx.AddVariationDependencies(crtVariations, cc.CrtBeginDepTag, crt) 2021 } 2022 for _, crt := range deps.CrtEnd { 2023 actx.AddVariationDependencies(crtVariations, cc.CrtEndDepTag, crt) 2024 } 2025 2026 if mod.sourceProvider != nil { 2027 if bindgen, ok := mod.sourceProvider.(*bindgenDecorator); ok && 2028 bindgen.Properties.Custom_bindgen != "" { 2029 actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), customBindgenDepTag, 2030 bindgen.Properties.Custom_bindgen) 2031 } 2032 } 2033 2034 actx.AddVariationDependencies([]blueprint.Variation{ 2035 {Mutator: "link", Variation: "shared"}, 2036 }, dataLibDepTag, deps.DataLibs...) 2037 2038 actx.AddVariationDependencies(nil, dataBinDepTag, deps.DataBins...) 2039 2040 // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy. 2041 actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...) 2042 2043 mod.afdo.addDep(ctx, actx) 2044} 2045 2046func BeginMutator(ctx android.BottomUpMutatorContext) { 2047 if mod, ok := ctx.Module().(*Module); ok && mod.Enabled(ctx) { 2048 mod.beginMutator(ctx) 2049 } 2050} 2051 2052func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) { 2053 ctx := &baseModuleContext{ 2054 BaseModuleContext: actx, 2055 } 2056 2057 mod.begin(ctx) 2058} 2059 2060func (mod *Module) Name() string { 2061 name := mod.ModuleBase.Name() 2062 if p, ok := mod.compiler.(interface { 2063 Name(string) string 2064 }); ok { 2065 name = p.Name(name) 2066 } 2067 return name 2068} 2069 2070func (mod *Module) disableClippy() { 2071 if mod.clippy != nil { 2072 mod.clippy.Properties.Clippy_lints = proptools.StringPtr("none") 2073 } 2074} 2075 2076var _ android.HostToolProvider = (*Module)(nil) 2077 2078func (mod *Module) HostToolPath() android.OptionalPath { 2079 if !mod.Host() { 2080 return android.OptionalPath{} 2081 } 2082 if binary, ok := mod.compiler.(*binaryDecorator); ok { 2083 return android.OptionalPathForPath(binary.baseCompiler.path) 2084 } else if pm, ok := mod.compiler.(*procMacroDecorator); ok { 2085 // Even though proc-macros aren't strictly "tools", since they target the compiler 2086 // and act as compiler plugins, we treat them similarly. 2087 return android.OptionalPathForPath(pm.baseCompiler.path) 2088 } 2089 return android.OptionalPath{} 2090} 2091 2092var _ android.ApexModule = (*Module)(nil) 2093 2094// If a module is marked for exclusion from apexes, don't provide apex variants. 2095// TODO(b/362509506): remove this once all apex_exclude usages are removed. 2096func (m *Module) CanHaveApexVariants() bool { 2097 if m.ApexExclude() { 2098 return false 2099 } else { 2100 return m.ApexModuleBase.CanHaveApexVariants() 2101 } 2102} 2103 2104func (mod *Module) MinSdkVersion() string { 2105 return String(mod.Properties.Min_sdk_version) 2106} 2107 2108// Implements android.ApexModule 2109func (mod *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { 2110 minSdkVersion := mod.MinSdkVersion() 2111 if minSdkVersion == "apex_inherit" { 2112 return android.MinApiLevel 2113 } 2114 2115 if minSdkVersion == "" { 2116 return android.NoneApiLevel 2117 } 2118 // Not using nativeApiLevelFromUser because the context here is not 2119 // necessarily a native context. 2120 ver, err := android.ApiLevelFromUserWithConfig(ctx.Config(), minSdkVersion) 2121 if err != nil { 2122 return android.NoneApiLevel 2123 } 2124 2125 return ver 2126} 2127 2128// Implements android.ApexModule 2129func (mod *Module) AlwaysRequiresPlatformApexVariant() bool { 2130 // stub libraries and native bridge libraries are always available to platform 2131 // TODO(b/362509506): remove the ApexExclude() check once all apex_exclude uses are switched to stubs. 2132 return mod.IsStubs() || mod.Target().NativeBridge == android.NativeBridgeEnabled || mod.ApexExclude() 2133} 2134 2135// Implements android.ApexModule 2136type RustDepInSameApexChecker struct { 2137 Static bool 2138 HasStubsVariants bool 2139 ApexExclude bool 2140 Host bool 2141} 2142 2143func (mod *Module) GetDepInSameApexChecker() android.DepInSameApexChecker { 2144 return RustDepInSameApexChecker{ 2145 Static: mod.Static(), 2146 HasStubsVariants: mod.HasStubsVariants(), 2147 ApexExclude: mod.ApexExclude(), 2148 Host: mod.Host(), 2149 } 2150} 2151 2152func (r RustDepInSameApexChecker) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool { 2153 if depTag == procMacroDepTag || depTag == customBindgenDepTag { 2154 return false 2155 } 2156 2157 if r.Static && cc.IsSharedDepTag(depTag) { 2158 // shared_lib dependency from a static lib is considered as crossing 2159 // the APEX boundary because the dependency doesn't actually is 2160 // linked; the dependency is used only during the compilation phase. 2161 return false 2162 } 2163 2164 if depTag == cc.StubImplDepTag { 2165 // We don't track from an implementation library to its stubs. 2166 return false 2167 } 2168 2169 if cc.ExcludeInApexDepTag(depTag) { 2170 return false 2171 } 2172 2173 // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs. 2174 if r.ApexExclude { 2175 return false 2176 } 2177 2178 return true 2179} 2180 2181func (r RustDepInSameApexChecker) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool { 2182 if r.Host { 2183 return false 2184 } 2185 // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs. 2186 if r.ApexExclude { 2187 return false 2188 } 2189 2190 if r.HasStubsVariants { 2191 if cc.IsSharedDepTag(depTag) && !cc.IsExplicitImplSharedDepTag(depTag) { 2192 // dynamic dep to a stubs lib crosses APEX boundary 2193 return false 2194 } 2195 if cc.IsRuntimeDepTag(depTag) { 2196 // runtime dep to a stubs lib also crosses APEX boundary 2197 return false 2198 } 2199 if cc.IsHeaderDepTag(depTag) { 2200 return false 2201 } 2202 } 2203 return true 2204} 2205 2206// Overrides ApexModule.IsInstallabeToApex() 2207func (mod *Module) IsInstallableToApex() bool { 2208 // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs. 2209 if mod.ApexExclude() { 2210 return false 2211 } 2212 2213 if mod.compiler != nil { 2214 if lib, ok := mod.compiler.(libraryInterface); ok { 2215 return (lib.shared() || lib.dylib()) && !lib.BuildStubs() 2216 } 2217 if _, ok := mod.compiler.(*binaryDecorator); ok { 2218 return true 2219 } 2220 } 2221 return false 2222} 2223 2224// If a library file has a "lib" prefix, extract the library name without the prefix. 2225func libNameFromFilePath(filepath android.Path) (string, bool) { 2226 libName := strings.TrimSuffix(filepath.Base(), filepath.Ext()) 2227 if strings.HasPrefix(libName, "lib") { 2228 libName = libName[3:] 2229 return libName, true 2230 } 2231 return "", false 2232} 2233 2234func kytheExtractRustFactory() android.Singleton { 2235 return &kytheExtractRustSingleton{} 2236} 2237 2238type kytheExtractRustSingleton struct { 2239} 2240 2241func (k kytheExtractRustSingleton) GenerateBuildActions(ctx android.SingletonContext) { 2242 var xrefTargets android.Paths 2243 ctx.VisitAllModuleProxies(func(module android.ModuleProxy) { 2244 if rustModule, ok := android.OtherModuleProvider(ctx, module, RustInfoProvider); ok { 2245 xrefTargets = append(xrefTargets, rustModule.XrefRustFiles...) 2246 } 2247 }) 2248 if len(xrefTargets) > 0 { 2249 ctx.Phony("xref_rust", xrefTargets...) 2250 } 2251} 2252 2253func (c *Module) Partition() string { 2254 return "" 2255} 2256 2257var Bool = proptools.Bool 2258var BoolDefault = proptools.BoolDefault 2259var String = proptools.String 2260var StringPtr = proptools.StringPtr 2261