1// Copyright 2019 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package rust 16 17import ( 18 "fmt" 19 "strings" 20 21 "github.com/google/blueprint" 22 "github.com/google/blueprint/proptools" 23 24 "android/soong/android" 25 "android/soong/cc" 26 "android/soong/rust/config" 27) 28 29var pctx = android.NewPackageContext("android/soong/rust") 30 31func init() { 32 // Only allow rust modules to be defined for certain projects 33 34 android.AddNeverAllowRules( 35 android.NeverAllow(). 36 NotIn(config.RustAllowedPaths...). 37 ModuleType(config.RustModuleTypes...)) 38 39 android.RegisterModuleType("rust_defaults", defaultsFactory) 40 android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { 41 ctx.BottomUp("rust_libraries", LibraryMutator).Parallel() 42 ctx.BottomUp("rust_begin", BeginMutator).Parallel() 43 }) 44 pctx.Import("android/soong/rust/config") 45 pctx.ImportAs("ccConfig", "android/soong/cc/config") 46} 47 48type Flags struct { 49 GlobalRustFlags []string // Flags that apply globally to rust 50 GlobalLinkFlags []string // Flags that apply globally to linker 51 RustFlags []string // Flags that apply to rust 52 LinkFlags []string // Flags that apply to linker 53 ClippyFlags []string // Flags that apply to clippy-driver, during the linting 54 Toolchain config.Toolchain 55 Coverage bool 56 Clippy bool 57} 58 59type BaseProperties struct { 60 AndroidMkRlibs []string 61 AndroidMkDylibs []string 62 AndroidMkProcMacroLibs []string 63 AndroidMkSharedLibs []string 64 AndroidMkStaticLibs []string 65 66 SubName string `blueprint:"mutated"` 67 PreventInstall bool 68 HideFromMake bool 69} 70 71type Module struct { 72 android.ModuleBase 73 android.DefaultableModuleBase 74 75 Properties BaseProperties 76 77 hod android.HostOrDeviceSupported 78 multilib android.Multilib 79 80 compiler compiler 81 coverage *coverage 82 clippy *clippy 83 cachedToolchain config.Toolchain 84 sourceProvider SourceProvider 85 subAndroidMkOnce map[subAndroidMkProvider]bool 86 outputFile android.OptionalPath 87 88 subName string 89} 90 91func (mod *Module) OutputFiles(tag string) (android.Paths, error) { 92 switch tag { 93 case "": 94 if mod.sourceProvider != nil { 95 return mod.sourceProvider.Srcs(), nil 96 } else { 97 if mod.outputFile.Valid() { 98 return android.Paths{mod.outputFile.Path()}, nil 99 } 100 return android.Paths{}, nil 101 } 102 default: 103 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 104 } 105} 106 107var _ android.ImageInterface = (*Module)(nil) 108 109func (mod *Module) ImageMutatorBegin(ctx android.BaseModuleContext) {} 110 111func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { 112 return true 113} 114 115func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool { 116 return mod.InRamdisk() 117} 118 119func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool { 120 return mod.InRecovery() 121} 122 123func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string { 124 return nil 125} 126 127func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { 128} 129 130func (mod *Module) BuildStubs() bool { 131 return false 132} 133 134func (mod *Module) HasStubsVariants() bool { 135 return false 136} 137 138func (mod *Module) SelectedStl() string { 139 return "" 140} 141 142func (mod *Module) NonCcVariants() bool { 143 if mod.compiler != nil { 144 if _, ok := mod.compiler.(libraryInterface); ok { 145 return false 146 } 147 } 148 panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName())) 149} 150 151func (mod *Module) ApiLevel() string { 152 panic(fmt.Errorf("Called ApiLevel on Rust module %q; stubs libraries are not yet supported.", mod.BaseModuleName())) 153} 154 155func (mod *Module) Static() bool { 156 if mod.compiler != nil { 157 if library, ok := mod.compiler.(libraryInterface); ok { 158 return library.static() 159 } 160 } 161 return false 162} 163 164func (mod *Module) Shared() bool { 165 if mod.compiler != nil { 166 if library, ok := mod.compiler.(libraryInterface); ok { 167 return library.shared() 168 } 169 } 170 return false 171} 172 173func (mod *Module) Toc() android.OptionalPath { 174 if mod.compiler != nil { 175 if _, ok := mod.compiler.(libraryInterface); ok { 176 return android.OptionalPath{} 177 } 178 } 179 panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName())) 180} 181 182func (mod *Module) OnlyInRamdisk() bool { 183 return false 184} 185 186func (mod *Module) OnlyInRecovery() bool { 187 return false 188} 189 190func (mod *Module) UseSdk() bool { 191 return false 192} 193 194func (mod *Module) UseVndk() bool { 195 return false 196} 197 198func (mod *Module) MustUseVendorVariant() bool { 199 return false 200} 201 202func (mod *Module) IsVndk() bool { 203 return false 204} 205 206func (mod *Module) HasVendorVariant() bool { 207 return false 208} 209 210func (mod *Module) SdkVersion() string { 211 return "" 212} 213 214func (mod *Module) AlwaysSdk() bool { 215 return false 216} 217 218func (mod *Module) IsSdkVariant() bool { 219 return false 220} 221 222func (mod *Module) ToolchainLibrary() bool { 223 return false 224} 225 226func (mod *Module) NdkPrebuiltStl() bool { 227 return false 228} 229 230func (mod *Module) StubDecorator() bool { 231 return false 232} 233 234type Deps struct { 235 Dylibs []string 236 Rlibs []string 237 Rustlibs []string 238 ProcMacros []string 239 SharedLibs []string 240 StaticLibs []string 241 242 CrtBegin, CrtEnd string 243} 244 245type PathDeps struct { 246 DyLibs RustLibraries 247 RLibs RustLibraries 248 SharedLibs android.Paths 249 StaticLibs android.Paths 250 ProcMacros RustLibraries 251 linkDirs []string 252 depFlags []string 253 //ReexportedDeps android.Paths 254 255 // Used by bindgen modules which call clang 256 depClangFlags []string 257 depIncludePaths android.Paths 258 depSystemIncludePaths android.Paths 259 260 coverageFiles android.Paths 261 262 CrtBegin android.OptionalPath 263 CrtEnd android.OptionalPath 264 265 // Paths to generated source files 266 SrcDeps android.Paths 267} 268 269type RustLibraries []RustLibrary 270 271type RustLibrary struct { 272 Path android.Path 273 CrateName string 274} 275 276type compiler interface { 277 compilerFlags(ctx ModuleContext, flags Flags) Flags 278 compilerProps() []interface{} 279 compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path 280 compilerDeps(ctx DepsContext, deps Deps) Deps 281 crateName() string 282 283 inData() bool 284 install(ctx ModuleContext, path android.Path) 285 relativeInstallPath() string 286 287 nativeCoverage() bool 288} 289 290type exportedFlagsProducer interface { 291 exportedLinkDirs() []string 292 exportedDepFlags() []string 293 exportLinkDirs(...string) 294 exportDepFlags(...string) 295} 296 297type flagExporter struct { 298 depFlags []string 299 linkDirs []string 300} 301 302func (flagExporter *flagExporter) exportedLinkDirs() []string { 303 return flagExporter.linkDirs 304} 305 306func (flagExporter *flagExporter) exportedDepFlags() []string { 307 return flagExporter.depFlags 308} 309 310func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { 311 flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) 312} 313 314func (flagExporter *flagExporter) exportDepFlags(flags ...string) { 315 flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...)) 316} 317 318var _ exportedFlagsProducer = (*flagExporter)(nil) 319 320func NewFlagExporter() *flagExporter { 321 return &flagExporter{ 322 depFlags: []string{}, 323 linkDirs: []string{}, 324 } 325} 326 327func (mod *Module) isCoverageVariant() bool { 328 return mod.coverage.Properties.IsCoverageVariant 329} 330 331var _ cc.Coverage = (*Module)(nil) 332 333func (mod *Module) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool { 334 return mod.coverage != nil && mod.coverage.Properties.NeedCoverageVariant 335} 336 337func (mod *Module) PreventInstall() { 338 mod.Properties.PreventInstall = true 339} 340 341func (mod *Module) HideFromMake() { 342 mod.Properties.HideFromMake = true 343} 344 345func (mod *Module) MarkAsCoverageVariant(coverage bool) { 346 mod.coverage.Properties.IsCoverageVariant = coverage 347} 348 349func (mod *Module) EnableCoverageIfNeeded() { 350 mod.coverage.Properties.CoverageEnabled = mod.coverage.Properties.NeedCoverageBuild 351} 352 353func defaultsFactory() android.Module { 354 return DefaultsFactory() 355} 356 357type Defaults struct { 358 android.ModuleBase 359 android.DefaultsModuleBase 360} 361 362func DefaultsFactory(props ...interface{}) android.Module { 363 module := &Defaults{} 364 365 module.AddProperties(props...) 366 module.AddProperties( 367 &BaseProperties{}, 368 &BaseCompilerProperties{}, 369 &BinaryCompilerProperties{}, 370 &LibraryCompilerProperties{}, 371 &ProcMacroCompilerProperties{}, 372 &PrebuiltProperties{}, 373 &SourceProviderProperties{}, 374 &TestProperties{}, 375 &cc.CoverageProperties{}, 376 &ClippyProperties{}, 377 ) 378 379 android.InitDefaultsModule(module) 380 return module 381} 382 383func (mod *Module) CrateName() string { 384 return mod.compiler.crateName() 385} 386 387func (mod *Module) CcLibrary() bool { 388 if mod.compiler != nil { 389 if _, ok := mod.compiler.(*libraryDecorator); ok { 390 return true 391 } 392 } 393 return false 394} 395 396func (mod *Module) CcLibraryInterface() bool { 397 if mod.compiler != nil { 398 // use build{Static,Shared}() instead of {static,shared}() here because this might be called before 399 // VariantIs{Static,Shared} is set. 400 if lib, ok := mod.compiler.(libraryInterface); ok && (lib.buildShared() || lib.buildStatic()) { 401 return true 402 } 403 } 404 return false 405} 406 407func (mod *Module) IncludeDirs() android.Paths { 408 if mod.compiler != nil { 409 if library, ok := mod.compiler.(*libraryDecorator); ok { 410 return library.includeDirs 411 } 412 } 413 panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName())) 414} 415 416func (mod *Module) SetStatic() { 417 if mod.compiler != nil { 418 if library, ok := mod.compiler.(libraryInterface); ok { 419 library.setStatic() 420 return 421 } 422 } 423 panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName())) 424} 425 426func (mod *Module) SetShared() { 427 if mod.compiler != nil { 428 if library, ok := mod.compiler.(libraryInterface); ok { 429 library.setShared() 430 return 431 } 432 } 433 panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName())) 434} 435 436func (mod *Module) SetBuildStubs() { 437 panic("SetBuildStubs not yet implemented for rust modules") 438} 439 440func (mod *Module) SetStubsVersions(string) { 441 panic("SetStubsVersions not yet implemented for rust modules") 442} 443 444func (mod *Module) StubsVersion() string { 445 panic("SetStubsVersions not yet implemented for rust modules") 446} 447 448func (mod *Module) BuildStaticVariant() bool { 449 if mod.compiler != nil { 450 if library, ok := mod.compiler.(libraryInterface); ok { 451 return library.buildStatic() 452 } 453 } 454 panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) 455} 456 457func (mod *Module) BuildSharedVariant() bool { 458 if mod.compiler != nil { 459 if library, ok := mod.compiler.(libraryInterface); ok { 460 return library.buildShared() 461 } 462 } 463 panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName())) 464} 465 466// Rust module deps don't have a link order (?) 467func (mod *Module) SetDepsInLinkOrder([]android.Path) {} 468 469func (mod *Module) GetDepsInLinkOrder() []android.Path { 470 return []android.Path{} 471} 472 473func (mod *Module) GetStaticVariant() cc.LinkableInterface { 474 return nil 475} 476 477func (mod *Module) Module() android.Module { 478 return mod 479} 480 481func (mod *Module) StubsVersions() []string { 482 // For now, Rust has no stubs versions. 483 if mod.compiler != nil { 484 if _, ok := mod.compiler.(libraryInterface); ok { 485 return []string{} 486 } 487 } 488 panic(fmt.Errorf("StubsVersions called on non-library module: %q", mod.BaseModuleName())) 489} 490 491func (mod *Module) OutputFile() android.OptionalPath { 492 return mod.outputFile 493} 494 495func (mod *Module) InRecovery() bool { 496 // For now, Rust has no notion of the recovery image 497 return false 498} 499func (mod *Module) HasStaticVariant() bool { 500 if mod.GetStaticVariant() != nil { 501 return true 502 } 503 return false 504} 505 506func (mod *Module) CoverageFiles() android.Paths { 507 if mod.compiler != nil { 508 if !mod.compiler.nativeCoverage() { 509 return android.Paths{} 510 } 511 if library, ok := mod.compiler.(*libraryDecorator); ok { 512 if library.coverageFile != nil { 513 return android.Paths{library.coverageFile} 514 } 515 return android.Paths{} 516 } 517 } 518 panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName())) 519} 520 521var _ cc.LinkableInterface = (*Module)(nil) 522 523func (mod *Module) Init() android.Module { 524 mod.AddProperties(&mod.Properties) 525 526 if mod.compiler != nil { 527 mod.AddProperties(mod.compiler.compilerProps()...) 528 } 529 if mod.coverage != nil { 530 mod.AddProperties(mod.coverage.props()...) 531 } 532 if mod.clippy != nil { 533 mod.AddProperties(mod.clippy.props()...) 534 } 535 if mod.sourceProvider != nil { 536 mod.AddProperties(mod.sourceProvider.sourceProviderProps()...) 537 } 538 539 android.InitAndroidArchModule(mod, mod.hod, mod.multilib) 540 541 android.InitDefaultableModule(mod) 542 543 // Explicitly disable unsupported targets. 544 android.AddLoadHook(mod, func(ctx android.LoadHookContext) { 545 disableTargets := struct { 546 Target struct { 547 Linux_bionic struct { 548 Enabled *bool 549 } 550 } 551 }{} 552 disableTargets.Target.Linux_bionic.Enabled = proptools.BoolPtr(false) 553 554 ctx.AppendProperties(&disableTargets) 555 }) 556 557 return mod 558} 559 560func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 561 return &Module{ 562 hod: hod, 563 multilib: multilib, 564 } 565} 566func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { 567 module := newBaseModule(hod, multilib) 568 module.coverage = &coverage{} 569 module.clippy = &clippy{} 570 return module 571} 572 573type ModuleContext interface { 574 android.ModuleContext 575 ModuleContextIntf 576} 577 578type BaseModuleContext interface { 579 android.BaseModuleContext 580 ModuleContextIntf 581} 582 583type DepsContext interface { 584 android.BottomUpMutatorContext 585 ModuleContextIntf 586} 587 588type ModuleContextIntf interface { 589 RustModule() *Module 590 toolchain() config.Toolchain 591} 592 593type depsContext struct { 594 android.BottomUpMutatorContext 595} 596 597type moduleContext struct { 598 android.ModuleContext 599} 600 601type baseModuleContext struct { 602 android.BaseModuleContext 603} 604 605func (ctx *moduleContext) RustModule() *Module { 606 return ctx.Module().(*Module) 607} 608 609func (ctx *moduleContext) toolchain() config.Toolchain { 610 return ctx.RustModule().toolchain(ctx) 611} 612 613func (ctx *depsContext) RustModule() *Module { 614 return ctx.Module().(*Module) 615} 616 617func (ctx *depsContext) toolchain() config.Toolchain { 618 return ctx.RustModule().toolchain(ctx) 619} 620 621func (ctx *baseModuleContext) RustModule() *Module { 622 return ctx.Module().(*Module) 623} 624 625func (ctx *baseModuleContext) toolchain() config.Toolchain { 626 return ctx.RustModule().toolchain(ctx) 627} 628 629func (mod *Module) nativeCoverage() bool { 630 return mod.compiler != nil && mod.compiler.nativeCoverage() 631} 632 633func (mod *Module) toolchain(ctx android.BaseModuleContext) config.Toolchain { 634 if mod.cachedToolchain == nil { 635 mod.cachedToolchain = config.FindToolchain(ctx.Os(), ctx.Arch()) 636 } 637 return mod.cachedToolchain 638} 639 640func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) { 641} 642 643func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { 644 ctx := &moduleContext{ 645 ModuleContext: actx, 646 } 647 648 toolchain := mod.toolchain(ctx) 649 650 if !toolchain.Supported() { 651 // This toolchain's unsupported, there's nothing to do for this mod. 652 return 653 } 654 655 deps := mod.depsToPaths(ctx) 656 flags := Flags{ 657 Toolchain: toolchain, 658 } 659 660 if mod.compiler != nil { 661 flags = mod.compiler.compilerFlags(ctx, flags) 662 } 663 if mod.coverage != nil { 664 flags, deps = mod.coverage.flags(ctx, flags, deps) 665 } 666 if mod.clippy != nil { 667 flags, deps = mod.clippy.flags(ctx, flags, deps) 668 } 669 670 if mod.compiler != nil { 671 outputFile := mod.compiler.compile(ctx, flags, deps) 672 mod.outputFile = android.OptionalPathForPath(outputFile) 673 if !mod.Properties.PreventInstall { 674 mod.compiler.install(ctx, mod.outputFile.Path()) 675 } 676 } else if mod.sourceProvider != nil { 677 outputFile := mod.sourceProvider.generateSource(ctx, deps) 678 mod.outputFile = android.OptionalPathForPath(outputFile) 679 mod.subName = ctx.ModuleSubDir() 680 } 681} 682 683func (mod *Module) deps(ctx DepsContext) Deps { 684 deps := Deps{} 685 686 if mod.compiler != nil { 687 deps = mod.compiler.compilerDeps(ctx, deps) 688 } else if mod.sourceProvider != nil { 689 deps = mod.sourceProvider.sourceProviderDeps(ctx, deps) 690 } 691 692 if mod.coverage != nil { 693 deps = mod.coverage.deps(ctx, deps) 694 } 695 696 deps.Rlibs = android.LastUniqueStrings(deps.Rlibs) 697 deps.Dylibs = android.LastUniqueStrings(deps.Dylibs) 698 deps.Rustlibs = android.LastUniqueStrings(deps.Rustlibs) 699 deps.ProcMacros = android.LastUniqueStrings(deps.ProcMacros) 700 deps.SharedLibs = android.LastUniqueStrings(deps.SharedLibs) 701 deps.StaticLibs = android.LastUniqueStrings(deps.StaticLibs) 702 703 return deps 704 705} 706 707type dependencyTag struct { 708 blueprint.BaseDependencyTag 709 name string 710 library bool 711 proc_macro bool 712} 713 714var ( 715 rlibDepTag = dependencyTag{name: "rlibTag", library: true} 716 dylibDepTag = dependencyTag{name: "dylib", library: true} 717 procMacroDepTag = dependencyTag{name: "procMacro", proc_macro: true} 718 testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"} 719) 720 721type autoDep struct { 722 variation string 723 depTag dependencyTag 724} 725 726var ( 727 rlibAutoDep = autoDep{variation: "rlib", depTag: rlibDepTag} 728 dylibAutoDep = autoDep{variation: "dylib", depTag: dylibDepTag} 729) 730 731type autoDeppable interface { 732 autoDep() autoDep 733} 734 735func (mod *Module) begin(ctx BaseModuleContext) { 736 if mod.coverage != nil { 737 mod.coverage.begin(ctx) 738 } 739} 740 741func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { 742 var depPaths PathDeps 743 744 directRlibDeps := []*Module{} 745 directDylibDeps := []*Module{} 746 directProcMacroDeps := []*Module{} 747 directSharedLibDeps := [](cc.LinkableInterface){} 748 directStaticLibDeps := [](cc.LinkableInterface){} 749 directSrcProvidersDeps := []*Module{} 750 directSrcDeps := [](android.SourceFileProducer){} 751 752 ctx.VisitDirectDeps(func(dep android.Module) { 753 depName := ctx.OtherModuleName(dep) 754 depTag := ctx.OtherModuleDependencyTag(dep) 755 if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() { 756 //Handle Rust Modules 757 758 linkFile := rustDep.outputFile 759 if !linkFile.Valid() { 760 ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) 761 } 762 763 switch depTag { 764 case dylibDepTag: 765 dylib, ok := rustDep.compiler.(libraryInterface) 766 if !ok || !dylib.dylib() { 767 ctx.ModuleErrorf("mod %q not an dylib library", depName) 768 return 769 } 770 directDylibDeps = append(directDylibDeps, rustDep) 771 mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, depName) 772 case rlibDepTag: 773 rlib, ok := rustDep.compiler.(libraryInterface) 774 if !ok || !rlib.rlib() { 775 ctx.ModuleErrorf("mod %q not an rlib library", depName) 776 return 777 } 778 depPaths.coverageFiles = append(depPaths.coverageFiles, rustDep.CoverageFiles()...) 779 directRlibDeps = append(directRlibDeps, rustDep) 780 mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, depName) 781 case procMacroDepTag: 782 directProcMacroDeps = append(directProcMacroDeps, rustDep) 783 mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, depName) 784 case android.SourceDepTag: 785 // Since these deps are added in path_properties.go via AddDependencies, we need to ensure the correct 786 // OS/Arch variant is used. 787 var helper string 788 if ctx.Host() { 789 helper = "missing 'host_supported'?" 790 } else { 791 helper = "device module defined?" 792 } 793 794 if dep.Target().Os != ctx.Os() { 795 ctx.ModuleErrorf("OS mismatch on dependency %q (%s)", dep.Name(), helper) 796 return 797 } else if dep.Target().Arch.ArchType != ctx.Arch().ArchType { 798 ctx.ModuleErrorf("Arch mismatch on dependency %q (%s)", dep.Name(), helper) 799 return 800 } 801 directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep) 802 } 803 804 //Append the dependencies exportedDirs 805 if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok { 806 depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...) 807 depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...) 808 } 809 810 if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { 811 linkDir := linkPathFromFilePath(linkFile.Path()) 812 if lib, ok := mod.compiler.(exportedFlagsProducer); ok { 813 lib.exportLinkDirs(linkDir) 814 } 815 } 816 817 } else if ccDep, ok := dep.(cc.LinkableInterface); ok { 818 //Handle C dependencies 819 if _, ok := ccDep.(*Module); !ok { 820 if ccDep.Module().Target().Os != ctx.Os() { 821 ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) 822 return 823 } 824 if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType { 825 ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) 826 return 827 } 828 } 829 830 linkFile := ccDep.OutputFile() 831 linkPath := linkPathFromFilePath(linkFile.Path()) 832 libName := libNameFromFilePath(linkFile.Path()) 833 depFlag := "-l" + libName 834 835 if !linkFile.Valid() { 836 ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) 837 } 838 839 exportDep := false 840 switch depTag { 841 case cc.StaticDepTag: 842 depFlag = "-lstatic=" + libName 843 depPaths.linkDirs = append(depPaths.linkDirs, linkPath) 844 depPaths.depFlags = append(depPaths.depFlags, depFlag) 845 depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...) 846 if mod, ok := ccDep.(*cc.Module); ok { 847 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...) 848 depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...) 849 } 850 depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...) 851 directStaticLibDeps = append(directStaticLibDeps, ccDep) 852 mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName) 853 case cc.SharedDepTag: 854 depFlag = "-ldylib=" + libName 855 depPaths.linkDirs = append(depPaths.linkDirs, linkPath) 856 depPaths.depFlags = append(depPaths.depFlags, depFlag) 857 depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...) 858 if mod, ok := ccDep.(*cc.Module); ok { 859 depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...) 860 depPaths.depClangFlags = append(depPaths.depClangFlags, mod.ExportedFlags()...) 861 } 862 directSharedLibDeps = append(directSharedLibDeps, ccDep) 863 mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName) 864 exportDep = true 865 case cc.CrtBeginDepTag: 866 depPaths.CrtBegin = linkFile 867 case cc.CrtEndDepTag: 868 depPaths.CrtEnd = linkFile 869 } 870 871 // Make sure these dependencies are propagated 872 if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { 873 lib.exportLinkDirs(linkPath) 874 lib.exportDepFlags(depFlag) 875 } 876 } 877 878 if srcDep, ok := dep.(android.SourceFileProducer); ok { 879 switch depTag { 880 case android.SourceDepTag: 881 // These are usually genrules which don't have per-target variants. 882 directSrcDeps = append(directSrcDeps, srcDep) 883 } 884 } 885 }) 886 887 var rlibDepFiles RustLibraries 888 for _, dep := range directRlibDeps { 889 rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()}) 890 } 891 var dylibDepFiles RustLibraries 892 for _, dep := range directDylibDeps { 893 dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()}) 894 } 895 var procMacroDepFiles RustLibraries 896 for _, dep := range directProcMacroDeps { 897 procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.outputFile.Path(), CrateName: dep.CrateName()}) 898 } 899 900 var staticLibDepFiles android.Paths 901 for _, dep := range directStaticLibDeps { 902 staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path()) 903 } 904 905 var sharedLibDepFiles android.Paths 906 for _, dep := range directSharedLibDeps { 907 sharedLibDepFiles = append(sharedLibDepFiles, dep.OutputFile().Path()) 908 } 909 910 var srcProviderDepFiles android.Paths 911 for _, dep := range directSrcProvidersDeps { 912 srcs, _ := dep.OutputFiles("") 913 srcProviderDepFiles = append(srcProviderDepFiles, srcs...) 914 } 915 for _, dep := range directSrcDeps { 916 srcs := dep.Srcs() 917 srcProviderDepFiles = append(srcProviderDepFiles, srcs...) 918 } 919 920 depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...) 921 depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...) 922 depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibDepFiles...) 923 depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...) 924 depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...) 925 depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...) 926 927 // Dedup exported flags from dependencies 928 depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs) 929 depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags) 930 depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags) 931 depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths) 932 depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths) 933 934 return depPaths 935} 936 937func (mod *Module) InstallInData() bool { 938 if mod.compiler == nil { 939 return false 940 } 941 return mod.compiler.inData() 942} 943 944func linkPathFromFilePath(filepath android.Path) string { 945 return strings.Split(filepath.String(), filepath.Base())[0] 946} 947 948func libNameFromFilePath(filepath android.Path) string { 949 libName := strings.TrimSuffix(filepath.Base(), filepath.Ext()) 950 if strings.HasPrefix(libName, "lib") { 951 libName = libName[3:] 952 } 953 return libName 954} 955 956func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { 957 ctx := &depsContext{ 958 BottomUpMutatorContext: actx, 959 } 960 961 deps := mod.deps(ctx) 962 commonDepVariations := []blueprint.Variation{} 963 if cc.VersionVariantAvailable(mod) { 964 commonDepVariations = append(commonDepVariations, 965 blueprint.Variation{Mutator: "version", Variation: ""}) 966 } 967 if !mod.Host() { 968 commonDepVariations = append(commonDepVariations, 969 blueprint.Variation{Mutator: "image", Variation: android.CoreVariation}) 970 } 971 actx.AddVariationDependencies( 972 append(commonDepVariations, []blueprint.Variation{ 973 {Mutator: "rust_libraries", Variation: "rlib"}}...), 974 rlibDepTag, deps.Rlibs...) 975 actx.AddVariationDependencies( 976 append(commonDepVariations, []blueprint.Variation{ 977 {Mutator: "rust_libraries", Variation: "dylib"}}...), 978 dylibDepTag, deps.Dylibs...) 979 980 if deps.Rustlibs != nil { 981 autoDep := mod.compiler.(autoDeppable).autoDep() 982 actx.AddVariationDependencies( 983 append(commonDepVariations, []blueprint.Variation{ 984 {Mutator: "rust_libraries", Variation: autoDep.variation}}...), 985 autoDep.depTag, deps.Rustlibs...) 986 } 987 988 actx.AddVariationDependencies(append(commonDepVariations, 989 blueprint.Variation{Mutator: "link", Variation: "shared"}), 990 cc.SharedDepTag, deps.SharedLibs...) 991 actx.AddVariationDependencies(append(commonDepVariations, 992 blueprint.Variation{Mutator: "link", Variation: "static"}), 993 cc.StaticDepTag, deps.StaticLibs...) 994 995 if deps.CrtBegin != "" { 996 actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin) 997 } 998 if deps.CrtEnd != "" { 999 actx.AddVariationDependencies(commonDepVariations, cc.CrtEndDepTag, deps.CrtEnd) 1000 } 1001 1002 // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy. 1003 actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...) 1004} 1005 1006func BeginMutator(ctx android.BottomUpMutatorContext) { 1007 if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() { 1008 mod.beginMutator(ctx) 1009 } 1010} 1011 1012func (mod *Module) beginMutator(actx android.BottomUpMutatorContext) { 1013 ctx := &baseModuleContext{ 1014 BaseModuleContext: actx, 1015 } 1016 1017 mod.begin(ctx) 1018} 1019 1020func (mod *Module) Name() string { 1021 name := mod.ModuleBase.Name() 1022 if p, ok := mod.compiler.(interface { 1023 Name(string) string 1024 }); ok { 1025 name = p.Name(name) 1026 } 1027 return name 1028} 1029 1030var _ android.HostToolProvider = (*Module)(nil) 1031 1032func (mod *Module) HostToolPath() android.OptionalPath { 1033 if !mod.Host() { 1034 return android.OptionalPath{} 1035 } 1036 if _, ok := mod.compiler.(*binaryDecorator); ok { 1037 return mod.outputFile 1038 } 1039 return android.OptionalPath{} 1040} 1041 1042var Bool = proptools.Bool 1043var BoolDefault = proptools.BoolDefault 1044var String = proptools.String 1045var StringPtr = proptools.StringPtr 1046 1047var _ android.OutputFileProducer = (*Module)(nil) 1048