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 "regexp" 20 "strings" 21 22 "android/soong/android" 23 "android/soong/cc" 24 "android/soong/snapshot" 25) 26 27var ( 28 DylibStdlibSuffix = ".dylib-std" 29 RlibStdlibSuffix = ".rlib-std" 30) 31 32func init() { 33 android.RegisterModuleType("rust_library", RustLibraryFactory) 34 android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory) 35 android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory) 36 android.RegisterModuleType("rust_library_host", RustLibraryHostFactory) 37 android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory) 38 android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory) 39 android.RegisterModuleType("rust_ffi", RustFFIFactory) 40 android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory) 41 android.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory) 42 android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory) 43 android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory) 44 android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory) 45} 46 47type VariantLibraryProperties struct { 48 Enabled *bool `android:"arch_variant"` 49 Srcs []string `android:"path,arch_variant"` 50} 51 52type LibraryCompilerProperties struct { 53 Rlib VariantLibraryProperties `android:"arch_variant"` 54 Dylib VariantLibraryProperties `android:"arch_variant"` 55 Shared VariantLibraryProperties `android:"arch_variant"` 56 Static VariantLibraryProperties `android:"arch_variant"` 57 58 // path to include directories to pass to cc_* modules, only relevant for static/shared variants. 59 Include_dirs []string `android:"path,arch_variant"` 60 61 // Whether this library is part of the Rust toolchain sysroot. 62 Sysroot *bool 63} 64 65type LibraryMutatedProperties struct { 66 // Build a dylib variant 67 BuildDylib bool `blueprint:"mutated"` 68 // Build an rlib variant 69 BuildRlib bool `blueprint:"mutated"` 70 // Build a shared library variant 71 BuildShared bool `blueprint:"mutated"` 72 // Build a static library variant 73 BuildStatic bool `blueprint:"mutated"` 74 75 // This variant is a dylib 76 VariantIsDylib bool `blueprint:"mutated"` 77 // This variant is an rlib 78 VariantIsRlib bool `blueprint:"mutated"` 79 // This variant is a shared library 80 VariantIsShared bool `blueprint:"mutated"` 81 // This variant is a static library 82 VariantIsStatic bool `blueprint:"mutated"` 83 // This variant is a source provider 84 VariantIsSource bool `blueprint:"mutated"` 85 86 // This variant is disabled and should not be compiled 87 // (used for SourceProvider variants that produce only source) 88 VariantIsDisabled bool `blueprint:"mutated"` 89 90 // Whether this library variant should be link libstd via rlibs 91 VariantIsStaticStd bool `blueprint:"mutated"` 92} 93 94type libraryDecorator struct { 95 *baseCompiler 96 *flagExporter 97 stripper Stripper 98 99 Properties LibraryCompilerProperties 100 MutatedProperties LibraryMutatedProperties 101 includeDirs android.Paths 102 sourceProvider SourceProvider 103 104 collectedSnapshotHeaders android.Paths 105 106 // table-of-contents file for cdylib crates to optimize out relinking when possible 107 tocFile android.OptionalPath 108} 109 110type libraryInterface interface { 111 rlib() bool 112 dylib() bool 113 static() bool 114 shared() bool 115 sysroot() bool 116 source() bool 117 118 // Returns true if the build options for the module have selected a particular build type 119 buildRlib() bool 120 buildDylib() bool 121 buildShared() bool 122 buildStatic() bool 123 124 // Sets a particular variant type 125 setRlib() 126 setDylib() 127 setShared() 128 setStatic() 129 setSource() 130 131 // libstd linkage functions 132 rlibStd() bool 133 setRlibStd() 134 setDylibStd() 135 136 // Build a specific library variant 137 BuildOnlyFFI() 138 BuildOnlyRust() 139 BuildOnlyRlib() 140 BuildOnlyDylib() 141 BuildOnlyStatic() 142 BuildOnlyShared() 143 144 toc() android.OptionalPath 145} 146 147func (library *libraryDecorator) nativeCoverage() bool { 148 return true 149} 150 151func (library *libraryDecorator) toc() android.OptionalPath { 152 return library.tocFile 153} 154 155func (library *libraryDecorator) rlib() bool { 156 return library.MutatedProperties.VariantIsRlib 157} 158 159func (library *libraryDecorator) sysroot() bool { 160 return Bool(library.Properties.Sysroot) 161} 162 163func (library *libraryDecorator) dylib() bool { 164 return library.MutatedProperties.VariantIsDylib 165} 166 167func (library *libraryDecorator) shared() bool { 168 return library.MutatedProperties.VariantIsShared 169} 170 171func (library *libraryDecorator) static() bool { 172 return library.MutatedProperties.VariantIsStatic 173} 174 175func (library *libraryDecorator) source() bool { 176 return library.MutatedProperties.VariantIsSource 177} 178 179func (library *libraryDecorator) buildRlib() bool { 180 return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true) 181} 182 183func (library *libraryDecorator) buildDylib() bool { 184 return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true) 185} 186 187func (library *libraryDecorator) buildShared() bool { 188 return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true) 189} 190 191func (library *libraryDecorator) buildStatic() bool { 192 return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true) 193} 194 195func (library *libraryDecorator) setRlib() { 196 library.MutatedProperties.VariantIsRlib = true 197 library.MutatedProperties.VariantIsDylib = false 198 library.MutatedProperties.VariantIsStatic = false 199 library.MutatedProperties.VariantIsShared = false 200} 201 202func (library *libraryDecorator) setDylib() { 203 library.MutatedProperties.VariantIsRlib = false 204 library.MutatedProperties.VariantIsDylib = true 205 library.MutatedProperties.VariantIsStatic = false 206 library.MutatedProperties.VariantIsShared = false 207} 208 209func (library *libraryDecorator) rlibStd() bool { 210 return library.MutatedProperties.VariantIsStaticStd 211} 212 213func (library *libraryDecorator) setRlibStd() { 214 library.MutatedProperties.VariantIsStaticStd = true 215} 216 217func (library *libraryDecorator) setDylibStd() { 218 library.MutatedProperties.VariantIsStaticStd = false 219} 220 221func (library *libraryDecorator) setShared() { 222 library.MutatedProperties.VariantIsStatic = false 223 library.MutatedProperties.VariantIsShared = true 224 library.MutatedProperties.VariantIsRlib = false 225 library.MutatedProperties.VariantIsDylib = false 226} 227 228func (library *libraryDecorator) setStatic() { 229 library.MutatedProperties.VariantIsStatic = true 230 library.MutatedProperties.VariantIsShared = false 231 library.MutatedProperties.VariantIsRlib = false 232 library.MutatedProperties.VariantIsDylib = false 233} 234 235func (library *libraryDecorator) setSource() { 236 library.MutatedProperties.VariantIsSource = true 237} 238 239func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep { 240 if ctx.Module().(*Module).InVendor() { 241 // Vendor modules should statically link libstd. 242 return rlibAutoDep 243 } else if library.preferRlib() { 244 return rlibAutoDep 245 } else if library.rlib() || library.static() { 246 return rlibAutoDep 247 } else if library.dylib() || library.shared() { 248 return dylibAutoDep 249 } else if ctx.BazelConversionMode() { 250 // In Bazel conversion mode, we are currently ignoring the deptag, so we just need to supply a 251 // compatible tag in order to add the dependency. 252 return rlibAutoDep 253 } else { 254 panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName())) 255 } 256} 257 258func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage { 259 if ctx.RustModule().InVendor() { 260 // Vendor modules should statically link libstd. 261 return RlibLinkage 262 } else if library.static() || library.MutatedProperties.VariantIsStaticStd { 263 return RlibLinkage 264 } else if library.baseCompiler.preferRlib() { 265 return RlibLinkage 266 } 267 return DefaultLinkage 268} 269 270var _ compiler = (*libraryDecorator)(nil) 271var _ libraryInterface = (*libraryDecorator)(nil) 272var _ exportedFlagsProducer = (*libraryDecorator)(nil) 273 274// rust_library produces all rust variants. 275func RustLibraryFactory() android.Module { 276 module, library := NewRustLibrary(android.HostAndDeviceSupported) 277 library.BuildOnlyRust() 278 return module.Init() 279} 280 281// rust_ffi produces all ffi variants. 282func RustFFIFactory() android.Module { 283 module, library := NewRustLibrary(android.HostAndDeviceSupported) 284 library.BuildOnlyFFI() 285 return module.Init() 286} 287 288// rust_library_dylib produces a dylib. 289func RustLibraryDylibFactory() android.Module { 290 module, library := NewRustLibrary(android.HostAndDeviceSupported) 291 library.BuildOnlyDylib() 292 return module.Init() 293} 294 295// rust_library_rlib produces an rlib. 296func RustLibraryRlibFactory() android.Module { 297 module, library := NewRustLibrary(android.HostAndDeviceSupported) 298 library.BuildOnlyRlib() 299 return module.Init() 300} 301 302// rust_ffi_shared produces a shared library. 303func RustFFISharedFactory() android.Module { 304 module, library := NewRustLibrary(android.HostAndDeviceSupported) 305 library.BuildOnlyShared() 306 return module.Init() 307} 308 309// rust_ffi_static produces a static library. 310func RustFFIStaticFactory() android.Module { 311 module, library := NewRustLibrary(android.HostAndDeviceSupported) 312 library.BuildOnlyStatic() 313 return module.Init() 314} 315 316// rust_library_host produces all rust variants. 317func RustLibraryHostFactory() android.Module { 318 module, library := NewRustLibrary(android.HostSupported) 319 library.BuildOnlyRust() 320 return module.Init() 321} 322 323// rust_ffi_host produces all FFI variants. 324func RustFFIHostFactory() android.Module { 325 module, library := NewRustLibrary(android.HostSupported) 326 library.BuildOnlyFFI() 327 return module.Init() 328} 329 330// rust_library_dylib_host produces a dylib. 331func RustLibraryDylibHostFactory() android.Module { 332 module, library := NewRustLibrary(android.HostSupported) 333 library.BuildOnlyDylib() 334 return module.Init() 335} 336 337// rust_library_rlib_host produces an rlib. 338func RustLibraryRlibHostFactory() android.Module { 339 module, library := NewRustLibrary(android.HostSupported) 340 library.BuildOnlyRlib() 341 return module.Init() 342} 343 344// rust_ffi_static_host produces a static library. 345func RustFFIStaticHostFactory() android.Module { 346 module, library := NewRustLibrary(android.HostSupported) 347 library.BuildOnlyStatic() 348 return module.Init() 349} 350 351// rust_ffi_shared_host produces an shared library. 352func RustFFISharedHostFactory() android.Module { 353 module, library := NewRustLibrary(android.HostSupported) 354 library.BuildOnlyShared() 355 return module.Init() 356} 357 358func (library *libraryDecorator) BuildOnlyFFI() { 359 library.MutatedProperties.BuildDylib = false 360 library.MutatedProperties.BuildRlib = false 361 library.MutatedProperties.BuildShared = true 362 library.MutatedProperties.BuildStatic = true 363} 364 365func (library *libraryDecorator) BuildOnlyRust() { 366 library.MutatedProperties.BuildDylib = true 367 library.MutatedProperties.BuildRlib = true 368 library.MutatedProperties.BuildShared = false 369 library.MutatedProperties.BuildStatic = false 370} 371 372func (library *libraryDecorator) BuildOnlyDylib() { 373 library.MutatedProperties.BuildDylib = true 374 library.MutatedProperties.BuildRlib = false 375 library.MutatedProperties.BuildShared = false 376 library.MutatedProperties.BuildStatic = false 377} 378 379func (library *libraryDecorator) BuildOnlyRlib() { 380 library.MutatedProperties.BuildDylib = false 381 library.MutatedProperties.BuildRlib = true 382 library.MutatedProperties.BuildShared = false 383 library.MutatedProperties.BuildStatic = false 384} 385 386func (library *libraryDecorator) BuildOnlyStatic() { 387 library.MutatedProperties.BuildRlib = false 388 library.MutatedProperties.BuildDylib = false 389 library.MutatedProperties.BuildShared = false 390 library.MutatedProperties.BuildStatic = true 391} 392 393func (library *libraryDecorator) BuildOnlyShared() { 394 library.MutatedProperties.BuildRlib = false 395 library.MutatedProperties.BuildDylib = false 396 library.MutatedProperties.BuildStatic = false 397 library.MutatedProperties.BuildShared = true 398} 399 400func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 401 module := newModule(hod, android.MultilibBoth) 402 403 library := &libraryDecorator{ 404 MutatedProperties: LibraryMutatedProperties{ 405 BuildDylib: false, 406 BuildRlib: false, 407 BuildShared: false, 408 BuildStatic: false, 409 }, 410 baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem), 411 flagExporter: NewFlagExporter(), 412 } 413 414 module.compiler = library 415 416 return module, library 417} 418 419func (library *libraryDecorator) compilerProps() []interface{} { 420 return append(library.baseCompiler.compilerProps(), 421 &library.Properties, 422 &library.MutatedProperties, 423 &library.stripper.StripProperties) 424} 425 426func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 427 deps = library.baseCompiler.compilerDeps(ctx, deps) 428 429 if library.dylib() || library.shared() { 430 if ctx.toolchain().Bionic() { 431 deps = bionicDeps(ctx, deps, false) 432 deps.CrtBegin = []string{"crtbegin_so"} 433 deps.CrtEnd = []string{"crtend_so"} 434 } else if ctx.Os() == android.LinuxMusl { 435 deps = muslDeps(ctx, deps, false) 436 deps.CrtBegin = []string{"libc_musl_crtbegin_so"} 437 deps.CrtEnd = []string{"libc_musl_crtend_so"} 438 } 439 } 440 441 return deps 442} 443 444func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string { 445 return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix() 446} 447 448func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags { 449 flags = library.baseCompiler.cfgFlags(ctx, flags) 450 if library.dylib() { 451 // We need to add a dependency on std in order to link crates as dylibs. 452 // The hack to add this dependency is guarded by the following cfg so 453 // that we don't force a dependency when it isn't needed. 454 library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib") 455 } 456 457 flags.RustFlags = append(flags.RustFlags, library.baseCompiler.cfgsToFlags()...) 458 flags.RustdocFlags = append(flags.RustdocFlags, library.baseCompiler.cfgsToFlags()...) 459 460 return flags 461} 462 463func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { 464 flags = library.baseCompiler.compilerFlags(ctx, flags) 465 466 flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName()) 467 if library.shared() || library.static() { 468 library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...) 469 } 470 if library.shared() { 471 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx)) 472 } 473 474 return flags 475} 476 477func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { 478 var outputFile, ret android.ModuleOutPath 479 var fileName string 480 srcPath := library.srcPath(ctx, deps) 481 482 if library.sourceProvider != nil { 483 deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...) 484 } 485 486 // Calculate output filename 487 if library.rlib() { 488 fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix() 489 outputFile = android.PathForModuleOut(ctx, fileName) 490 ret = outputFile 491 } else if library.dylib() { 492 fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix() 493 outputFile = android.PathForModuleOut(ctx, fileName) 494 ret = outputFile 495 } else if library.static() { 496 fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix() 497 outputFile = android.PathForModuleOut(ctx, fileName) 498 ret = outputFile 499 } else if library.shared() { 500 fileName = library.sharedLibFilename(ctx) 501 outputFile = android.PathForModuleOut(ctx, fileName) 502 ret = outputFile 503 } 504 505 if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) { 506 strippedOutputFile := outputFile 507 outputFile = android.PathForModuleOut(ctx, "unstripped", fileName) 508 library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile) 509 510 library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile) 511 } 512 library.baseCompiler.unstrippedOutputFile = outputFile 513 514 flags.RustFlags = append(flags.RustFlags, deps.depFlags...) 515 flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...) 516 flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...) 517 518 if library.dylib() { 519 // We need prefer-dynamic for now to avoid linking in the static stdlib. See: 520 // https://github.com/rust-lang/rust/issues/19680 521 // https://github.com/rust-lang/rust/issues/34909 522 flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic") 523 } 524 525 // Call the appropriate builder for this library type 526 if library.rlib() { 527 TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile) 528 } else if library.dylib() { 529 TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile) 530 } else if library.static() { 531 TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile) 532 } else if library.shared() { 533 TransformSrctoShared(ctx, srcPath, deps, flags, outputFile) 534 } 535 536 if library.rlib() || library.dylib() { 537 library.flagExporter.exportLinkDirs(deps.linkDirs...) 538 library.flagExporter.exportLinkObjects(deps.linkObjects...) 539 } 540 541 if library.static() || library.shared() { 542 ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{ 543 IncludeDirs: library.includeDirs, 544 }) 545 } 546 547 if library.shared() { 548 // Optimize out relinking against shared libraries whose interface hasn't changed by 549 // depending on a table of contents file instead of the library itself. 550 tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc") 551 library.tocFile = android.OptionalPathForPath(tocFile) 552 cc.TransformSharedObjectToToc(ctx, outputFile, tocFile) 553 554 ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{ 555 TableOfContents: android.OptionalPathForPath(tocFile), 556 SharedLibrary: outputFile, 557 Target: ctx.Target(), 558 }) 559 } 560 561 if library.static() { 562 depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputFile).Build() 563 ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{ 564 StaticLibrary: outputFile, 565 566 TransitiveStaticLibrariesForOrdering: depSet, 567 }) 568 } 569 570 library.flagExporter.setProvider(ctx) 571 572 return ret 573} 574 575func (library *libraryDecorator) srcPath(ctx ModuleContext, deps PathDeps) android.Path { 576 if library.sourceProvider != nil { 577 // Assume the first source from the source provider is the library entry point. 578 return library.sourceProvider.Srcs()[0] 579 } else { 580 path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs) 581 return path 582 } 583} 584 585func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags, 586 deps PathDeps) android.OptionalPath { 587 // rustdoc has builtin support for documenting config specific information 588 // regardless of the actual config it was given 589 // (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information), 590 // so we generate the rustdoc for only the primary module so that we have a 591 // single set of docs to refer to. 592 if ctx.Module() != ctx.PrimaryModule() { 593 return android.OptionalPath{} 594 } 595 596 return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps), 597 deps, flags)) 598} 599 600func (library *libraryDecorator) getStem(ctx ModuleContext) string { 601 stem := library.baseCompiler.getStemWithoutSuffix(ctx) 602 validateLibraryStem(ctx, stem, library.crateName()) 603 604 return stem + String(library.baseCompiler.Properties.Suffix) 605} 606 607func (library *libraryDecorator) install(ctx ModuleContext) { 608 // Only shared and dylib variants make sense to install. 609 if library.shared() || library.dylib() { 610 library.baseCompiler.install(ctx) 611 } 612} 613 614func (library *libraryDecorator) Disabled() bool { 615 return library.MutatedProperties.VariantIsDisabled 616} 617 618func (library *libraryDecorator) SetDisabled() { 619 library.MutatedProperties.VariantIsDisabled = true 620} 621 622var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+") 623 624func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) { 625 if crate_name == "" { 626 ctx.PropertyErrorf("crate_name", "crate_name must be defined.") 627 } 628 629 // crate_names are used for the library output file, and rustc expects these 630 // to be alphanumeric with underscores allowed. 631 if validCrateName.MatchString(crate_name) { 632 ctx.PropertyErrorf("crate_name", 633 "library crate_names must be alphanumeric with underscores allowed") 634 } 635 636 // Libraries are expected to begin with "lib" followed by the crate_name 637 if !strings.HasPrefix(filename, "lib"+crate_name) { 638 ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>") 639 } 640} 641 642// LibraryMutator mutates the libraries into variants according to the 643// build{Rlib,Dylib} attributes. 644func LibraryMutator(mctx android.BottomUpMutatorContext) { 645 // Only mutate on Rust libraries. 646 m, ok := mctx.Module().(*Module) 647 if !ok || m.compiler == nil { 648 return 649 } 650 library, ok := m.compiler.(libraryInterface) 651 if !ok { 652 return 653 } 654 655 var variants []string 656 // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib) 657 // depend on this variant. It must be the first variant to be declared. 658 sourceVariant := false 659 if m.sourceProvider != nil { 660 variants = append(variants, "source") 661 sourceVariant = true 662 } 663 if library.buildRlib() { 664 variants = append(variants, rlibVariation) 665 } 666 if library.buildDylib() { 667 variants = append(variants, dylibVariation) 668 } 669 670 if len(variants) == 0 { 671 return 672 } 673 modules := mctx.CreateLocalVariations(variants...) 674 675 // The order of the variations (modules) matches the variant names provided. Iterate 676 // through the new variation modules and set their mutated properties. 677 for i, v := range modules { 678 switch variants[i] { 679 case rlibVariation: 680 v.(*Module).compiler.(libraryInterface).setRlib() 681 case dylibVariation: 682 v.(*Module).compiler.(libraryInterface).setDylib() 683 if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation { 684 // TODO(b/165791368) 685 // Disable dylib Vendor Ramdisk variations until we support these. 686 v.(*Module).Disable() 687 } 688 689 variation := v.(*Module).ModuleBase.ImageVariation().Variation 690 if strings.HasPrefix(variation, cc.VendorVariationPrefix) { 691 // TODO(b/204303985) 692 // Disable vendor dylibs until they are supported 693 v.(*Module).Disable() 694 } 695 696 if strings.HasPrefix(variation, cc.VendorVariationPrefix) && 697 m.HasVendorVariant() && 698 !snapshot.IsVendorProprietaryModule(mctx) && 699 strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() { 700 701 // cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are 702 // produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for 703 // non-vendor proprietary modules. 704 v.(*Module).Disable() 705 } 706 707 case "source": 708 v.(*Module).compiler.(libraryInterface).setSource() 709 // The source variant does not produce any library. 710 // Disable the compilation steps. 711 v.(*Module).compiler.SetDisabled() 712 } 713 } 714 715 // If a source variant is created, add an inter-variant dependency 716 // between the other variants and the source variant. 717 if sourceVariant { 718 sv := modules[0] 719 for _, v := range modules[1:] { 720 if !v.Enabled() { 721 continue 722 } 723 mctx.AddInterVariantDependency(sourceDepTag, v, sv) 724 } 725 // Alias the source variation so it can be named directly in "srcs" properties. 726 mctx.AliasVariation("source") 727 } 728} 729 730func LibstdMutator(mctx android.BottomUpMutatorContext) { 731 if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() { 732 switch library := m.compiler.(type) { 733 case libraryInterface: 734 // Only create a variant if a library is actually being built. 735 if library.rlib() && !library.sysroot() { 736 variants := []string{"rlib-std", "dylib-std"} 737 modules := mctx.CreateLocalVariations(variants...) 738 739 rlib := modules[0].(*Module) 740 dylib := modules[1].(*Module) 741 rlib.compiler.(libraryInterface).setRlibStd() 742 dylib.compiler.(libraryInterface).setDylibStd() 743 if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation || 744 strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) { 745 // TODO(b/165791368) 746 // Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib 747 // variants are properly supported. 748 dylib.Disable() 749 } 750 rlib.Properties.RustSubName += RlibStdlibSuffix 751 dylib.Properties.RustSubName += DylibStdlibSuffix 752 } 753 } 754 } 755} 756 757func (l *libraryDecorator) snapshotHeaders() android.Paths { 758 if l.collectedSnapshotHeaders == nil { 759 panic("snapshotHeaders() must be called after collectHeadersForSnapshot()") 760 } 761 return l.collectedSnapshotHeaders 762} 763 764// collectHeadersForSnapshot collects all exported headers from library. 765// It globs header files in the source tree for exported include directories, 766// and tracks generated header files separately. 767// 768// This is to be called from GenerateAndroidBuildActions, and then collected 769// header files can be retrieved by snapshotHeaders(). 770func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) { 771 ret := android.Paths{} 772 773 // Glob together the headers from the modules include_dirs property 774 for _, path := range android.CopyOfPaths(l.includeDirs) { 775 dir := path.String() 776 globDir := dir + "/**/*" 777 glob, err := ctx.GlobWithDeps(globDir, nil) 778 if err != nil { 779 ctx.ModuleErrorf("glob of %q failed: %s", globDir, err) 780 return 781 } 782 783 for _, header := range glob { 784 // Filter out only the files with extensions that are headers. 785 found := false 786 for _, ext := range cc.HeaderExts { 787 if strings.HasSuffix(header, ext) { 788 found = true 789 break 790 } 791 } 792 if !found { 793 continue 794 } 795 ret = append(ret, android.PathForSource(ctx, header)) 796 } 797 } 798 799 // Glob together the headers from C dependencies as well, starting with non-generated headers. 800 ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...) 801 802 // Collect generated headers from C dependencies. 803 ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...) 804 805 // TODO(185577950): If support for generated headers is added, they need to be collected here as well. 806 l.collectedSnapshotHeaders = ret 807} 808