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