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