123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813 |
- // Copyright 2019 The Android Open Source Project
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package rust
- import (
- "fmt"
- "regexp"
- "strings"
- "android/soong/android"
- "android/soong/cc"
- "android/soong/snapshot"
- )
- var (
- RlibStdlibSuffix = ".rlib-std"
- )
- func init() {
- android.RegisterModuleType("rust_library", RustLibraryFactory)
- android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory)
- android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory)
- android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
- android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
- android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
- android.RegisterModuleType("rust_ffi", RustFFIFactory)
- android.RegisterModuleType("rust_ffi_shared", RustFFISharedFactory)
- android.RegisterModuleType("rust_ffi_static", RustFFIStaticFactory)
- android.RegisterModuleType("rust_ffi_host", RustFFIHostFactory)
- android.RegisterModuleType("rust_ffi_host_shared", RustFFISharedHostFactory)
- android.RegisterModuleType("rust_ffi_host_static", RustFFIStaticHostFactory)
- }
- type VariantLibraryProperties struct {
- Enabled *bool `android:"arch_variant"`
- Srcs []string `android:"path,arch_variant"`
- }
- type LibraryCompilerProperties struct {
- Rlib VariantLibraryProperties `android:"arch_variant"`
- Dylib VariantLibraryProperties `android:"arch_variant"`
- Shared VariantLibraryProperties `android:"arch_variant"`
- Static VariantLibraryProperties `android:"arch_variant"`
- // path to include directories to pass to cc_* modules, only relevant for static/shared variants.
- Include_dirs []string `android:"path,arch_variant"`
- // Whether this library is part of the Rust toolchain sysroot.
- Sysroot *bool
- }
- type LibraryMutatedProperties struct {
- // Build a dylib variant
- BuildDylib bool `blueprint:"mutated"`
- // Build an rlib variant
- BuildRlib bool `blueprint:"mutated"`
- // Build a shared library variant
- BuildShared bool `blueprint:"mutated"`
- // Build a static library variant
- BuildStatic bool `blueprint:"mutated"`
- // This variant is a dylib
- VariantIsDylib bool `blueprint:"mutated"`
- // This variant is an rlib
- VariantIsRlib bool `blueprint:"mutated"`
- // This variant is a shared library
- VariantIsShared bool `blueprint:"mutated"`
- // This variant is a static library
- VariantIsStatic bool `blueprint:"mutated"`
- // This variant is a source provider
- VariantIsSource bool `blueprint:"mutated"`
- // This variant is disabled and should not be compiled
- // (used for SourceProvider variants that produce only source)
- VariantIsDisabled bool `blueprint:"mutated"`
- // Whether this library variant should be link libstd via rlibs
- VariantIsStaticStd bool `blueprint:"mutated"`
- }
- type libraryDecorator struct {
- *baseCompiler
- *flagExporter
- stripper Stripper
- Properties LibraryCompilerProperties
- MutatedProperties LibraryMutatedProperties
- includeDirs android.Paths
- sourceProvider SourceProvider
- collectedSnapshotHeaders android.Paths
- // table-of-contents file for cdylib crates to optimize out relinking when possible
- tocFile android.OptionalPath
- }
- type libraryInterface interface {
- rlib() bool
- dylib() bool
- static() bool
- shared() bool
- sysroot() bool
- source() bool
- // Returns true if the build options for the module have selected a particular build type
- buildRlib() bool
- buildDylib() bool
- buildShared() bool
- buildStatic() bool
- // Sets a particular variant type
- setRlib()
- setDylib()
- setShared()
- setStatic()
- setSource()
- // libstd linkage functions
- rlibStd() bool
- setRlibStd()
- setDylibStd()
- // Build a specific library variant
- BuildOnlyFFI()
- BuildOnlyRust()
- BuildOnlyRlib()
- BuildOnlyDylib()
- BuildOnlyStatic()
- BuildOnlyShared()
- toc() android.OptionalPath
- }
- func (library *libraryDecorator) nativeCoverage() bool {
- return true
- }
- func (library *libraryDecorator) toc() android.OptionalPath {
- return library.tocFile
- }
- func (library *libraryDecorator) rlib() bool {
- return library.MutatedProperties.VariantIsRlib
- }
- func (library *libraryDecorator) sysroot() bool {
- return Bool(library.Properties.Sysroot)
- }
- func (library *libraryDecorator) dylib() bool {
- return library.MutatedProperties.VariantIsDylib
- }
- func (library *libraryDecorator) shared() bool {
- return library.MutatedProperties.VariantIsShared
- }
- func (library *libraryDecorator) static() bool {
- return library.MutatedProperties.VariantIsStatic
- }
- func (library *libraryDecorator) source() bool {
- return library.MutatedProperties.VariantIsSource
- }
- func (library *libraryDecorator) buildRlib() bool {
- return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
- }
- func (library *libraryDecorator) buildDylib() bool {
- return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
- }
- func (library *libraryDecorator) buildShared() bool {
- return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
- }
- func (library *libraryDecorator) buildStatic() bool {
- return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
- }
- func (library *libraryDecorator) setRlib() {
- library.MutatedProperties.VariantIsRlib = true
- library.MutatedProperties.VariantIsDylib = false
- library.MutatedProperties.VariantIsStatic = false
- library.MutatedProperties.VariantIsShared = false
- }
- func (library *libraryDecorator) setDylib() {
- library.MutatedProperties.VariantIsRlib = false
- library.MutatedProperties.VariantIsDylib = true
- library.MutatedProperties.VariantIsStatic = false
- library.MutatedProperties.VariantIsShared = false
- }
- func (library *libraryDecorator) rlibStd() bool {
- return library.MutatedProperties.VariantIsStaticStd
- }
- func (library *libraryDecorator) setRlibStd() {
- library.MutatedProperties.VariantIsStaticStd = true
- }
- func (library *libraryDecorator) setDylibStd() {
- library.MutatedProperties.VariantIsStaticStd = false
- }
- func (library *libraryDecorator) setShared() {
- library.MutatedProperties.VariantIsStatic = false
- library.MutatedProperties.VariantIsShared = true
- library.MutatedProperties.VariantIsRlib = false
- library.MutatedProperties.VariantIsDylib = false
- }
- func (library *libraryDecorator) setStatic() {
- library.MutatedProperties.VariantIsStatic = true
- library.MutatedProperties.VariantIsShared = false
- library.MutatedProperties.VariantIsRlib = false
- library.MutatedProperties.VariantIsDylib = false
- }
- func (library *libraryDecorator) setSource() {
- library.MutatedProperties.VariantIsSource = true
- }
- func (library *libraryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
- if ctx.Module().(*Module).InVendor() {
- // Vendor modules should statically link libstd.
- return rlibAutoDep
- } else if library.preferRlib() {
- return rlibAutoDep
- } else if library.rlib() || library.static() {
- return rlibAutoDep
- } else if library.dylib() || library.shared() {
- return dylibAutoDep
- } else {
- panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName()))
- }
- }
- func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
- if ctx.RustModule().InVendor() {
- // Vendor modules should statically link libstd.
- return RlibLinkage
- } else if library.static() || library.MutatedProperties.VariantIsStaticStd {
- return RlibLinkage
- } else if library.baseCompiler.preferRlib() {
- return RlibLinkage
- }
- return DefaultLinkage
- }
- var _ compiler = (*libraryDecorator)(nil)
- var _ libraryInterface = (*libraryDecorator)(nil)
- var _ exportedFlagsProducer = (*libraryDecorator)(nil)
- // rust_library produces all Rust variants (rust_library_dylib and
- // rust_library_rlib).
- func RustLibraryFactory() android.Module {
- module, library := NewRustLibrary(android.HostAndDeviceSupported)
- library.BuildOnlyRust()
- return module.Init()
- }
- // rust_ffi produces all FFI variants (rust_ffi_shared and
- // rust_ffi_static).
- func RustFFIFactory() android.Module {
- module, library := NewRustLibrary(android.HostAndDeviceSupported)
- library.BuildOnlyFFI()
- return module.Init()
- }
- // rust_library_dylib produces a Rust dylib (Rust crate type "dylib").
- func RustLibraryDylibFactory() android.Module {
- module, library := NewRustLibrary(android.HostAndDeviceSupported)
- library.BuildOnlyDylib()
- return module.Init()
- }
- // rust_library_rlib produces an rlib (Rust crate type "rlib").
- func RustLibraryRlibFactory() android.Module {
- module, library := NewRustLibrary(android.HostAndDeviceSupported)
- library.BuildOnlyRlib()
- return module.Init()
- }
- // rust_ffi_shared produces a shared library (Rust crate type
- // "cdylib").
- func RustFFISharedFactory() android.Module {
- module, library := NewRustLibrary(android.HostAndDeviceSupported)
- library.BuildOnlyShared()
- return module.Init()
- }
- // rust_ffi_static produces a static library (Rust crate type
- // "staticlib").
- func RustFFIStaticFactory() android.Module {
- module, library := NewRustLibrary(android.HostAndDeviceSupported)
- library.BuildOnlyStatic()
- return module.Init()
- }
- // rust_library_host produces all Rust variants for the host
- // (rust_library_dylib_host and rust_library_rlib_host).
- func RustLibraryHostFactory() android.Module {
- module, library := NewRustLibrary(android.HostSupported)
- library.BuildOnlyRust()
- return module.Init()
- }
- // rust_ffi_host produces all FFI variants for the host
- // (rust_ffi_static_host and rust_ffi_shared_host).
- func RustFFIHostFactory() android.Module {
- module, library := NewRustLibrary(android.HostSupported)
- library.BuildOnlyFFI()
- return module.Init()
- }
- // rust_library_dylib_host produces a dylib for the host (Rust crate
- // type "dylib").
- func RustLibraryDylibHostFactory() android.Module {
- module, library := NewRustLibrary(android.HostSupported)
- library.BuildOnlyDylib()
- return module.Init()
- }
- // rust_library_rlib_host produces an rlib for the host (Rust crate
- // type "rlib").
- func RustLibraryRlibHostFactory() android.Module {
- module, library := NewRustLibrary(android.HostSupported)
- library.BuildOnlyRlib()
- return module.Init()
- }
- // rust_ffi_static_host produces a static library for the host (Rust
- // crate type "staticlib").
- func RustFFIStaticHostFactory() android.Module {
- module, library := NewRustLibrary(android.HostSupported)
- library.BuildOnlyStatic()
- return module.Init()
- }
- // rust_ffi_shared_host produces an shared library for the host (Rust
- // crate type "cdylib").
- func RustFFISharedHostFactory() android.Module {
- module, library := NewRustLibrary(android.HostSupported)
- library.BuildOnlyShared()
- return module.Init()
- }
- func (library *libraryDecorator) BuildOnlyFFI() {
- library.MutatedProperties.BuildDylib = false
- library.MutatedProperties.BuildRlib = false
- library.MutatedProperties.BuildShared = true
- library.MutatedProperties.BuildStatic = true
- }
- func (library *libraryDecorator) BuildOnlyRust() {
- library.MutatedProperties.BuildDylib = true
- library.MutatedProperties.BuildRlib = true
- library.MutatedProperties.BuildShared = false
- library.MutatedProperties.BuildStatic = false
- }
- func (library *libraryDecorator) BuildOnlyDylib() {
- library.MutatedProperties.BuildDylib = true
- library.MutatedProperties.BuildRlib = false
- library.MutatedProperties.BuildShared = false
- library.MutatedProperties.BuildStatic = false
- }
- func (library *libraryDecorator) BuildOnlyRlib() {
- library.MutatedProperties.BuildDylib = false
- library.MutatedProperties.BuildRlib = true
- library.MutatedProperties.BuildShared = false
- library.MutatedProperties.BuildStatic = false
- }
- func (library *libraryDecorator) BuildOnlyStatic() {
- library.MutatedProperties.BuildRlib = false
- library.MutatedProperties.BuildDylib = false
- library.MutatedProperties.BuildShared = false
- library.MutatedProperties.BuildStatic = true
- }
- func (library *libraryDecorator) BuildOnlyShared() {
- library.MutatedProperties.BuildRlib = false
- library.MutatedProperties.BuildDylib = false
- library.MutatedProperties.BuildStatic = false
- library.MutatedProperties.BuildShared = true
- }
- func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
- module := newModule(hod, android.MultilibBoth)
- library := &libraryDecorator{
- MutatedProperties: LibraryMutatedProperties{
- BuildDylib: false,
- BuildRlib: false,
- BuildShared: false,
- BuildStatic: false,
- },
- baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
- flagExporter: NewFlagExporter(),
- }
- module.compiler = library
- return module, library
- }
- func (library *libraryDecorator) compilerProps() []interface{} {
- return append(library.baseCompiler.compilerProps(),
- &library.Properties,
- &library.MutatedProperties,
- &library.stripper.StripProperties)
- }
- func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
- deps = library.baseCompiler.compilerDeps(ctx, deps)
- if library.dylib() || library.shared() {
- if ctx.toolchain().Bionic() {
- deps = bionicDeps(ctx, deps, false)
- deps.CrtBegin = []string{"crtbegin_so"}
- deps.CrtEnd = []string{"crtend_so"}
- } else if ctx.Os() == android.LinuxMusl {
- deps = muslDeps(ctx, deps, false)
- deps.CrtBegin = []string{"libc_musl_crtbegin_so"}
- deps.CrtEnd = []string{"libc_musl_crtend_so"}
- }
- }
- return deps
- }
- func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string {
- return library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
- }
- func (library *libraryDecorator) cfgFlags(ctx ModuleContext, flags Flags) Flags {
- flags = library.baseCompiler.cfgFlags(ctx, flags)
- if library.dylib() {
- // We need to add a dependency on std in order to link crates as dylibs.
- // The hack to add this dependency is guarded by the following cfg so
- // that we don't force a dependency when it isn't needed.
- library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib")
- }
- flags.RustFlags = append(flags.RustFlags, library.baseCompiler.cfgsToFlags()...)
- flags.RustdocFlags = append(flags.RustdocFlags, library.baseCompiler.cfgsToFlags()...)
- return flags
- }
- func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
- flags = library.baseCompiler.compilerFlags(ctx, flags)
- flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName())
- if library.shared() || library.static() {
- library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
- }
- if library.shared() {
- flags.LinkFlags = append(flags.LinkFlags, "-Wl,-soname="+library.sharedLibFilename(ctx))
- }
- return flags
- }
- func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
- var outputFile android.ModuleOutPath
- var ret buildOutput
- var fileName string
- srcPath := library.srcPath(ctx, deps)
- if library.sourceProvider != nil {
- deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
- }
- // Calculate output filename
- if library.rlib() {
- fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
- outputFile = android.PathForModuleOut(ctx, fileName)
- ret.outputFile = outputFile
- } else if library.dylib() {
- fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
- outputFile = android.PathForModuleOut(ctx, fileName)
- ret.outputFile = outputFile
- } else if library.static() {
- fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
- outputFile = android.PathForModuleOut(ctx, fileName)
- ret.outputFile = outputFile
- } else if library.shared() {
- fileName = library.sharedLibFilename(ctx)
- outputFile = android.PathForModuleOut(ctx, fileName)
- ret.outputFile = outputFile
- }
- if !library.rlib() && !library.static() && library.stripper.NeedsStrip(ctx) {
- strippedOutputFile := outputFile
- outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
- library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
- library.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
- }
- library.baseCompiler.unstrippedOutputFile = outputFile
- flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
- if library.dylib() {
- // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
- // https://github.com/rust-lang/rust/issues/19680
- // https://github.com/rust-lang/rust/issues/34909
- flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
- }
- // Call the appropriate builder for this library type
- if library.rlib() {
- ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile
- } else if library.dylib() {
- ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile
- } else if library.static() {
- ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile
- } else if library.shared() {
- ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile
- }
- if library.rlib() || library.dylib() {
- library.flagExporter.exportLinkDirs(deps.linkDirs...)
- library.flagExporter.exportLinkObjects(deps.linkObjects...)
- library.flagExporter.exportLibDeps(deps.LibDeps...)
- }
- if library.static() || library.shared() {
- ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
- IncludeDirs: library.includeDirs,
- })
- }
- if library.shared() {
- // Optimize out relinking against shared libraries whose interface hasn't changed by
- // depending on a table of contents file instead of the library itself.
- tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
- library.tocFile = android.OptionalPathForPath(tocFile)
- cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)
- ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
- TableOfContents: android.OptionalPathForPath(tocFile),
- SharedLibrary: outputFile,
- Target: ctx.Target(),
- })
- }
- if library.static() {
- depSet := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(outputFile).Build()
- ctx.SetProvider(cc.StaticLibraryInfoProvider, cc.StaticLibraryInfo{
- StaticLibrary: outputFile,
- TransitiveStaticLibrariesForOrdering: depSet,
- })
- }
- library.flagExporter.setProvider(ctx)
- return ret
- }
- func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path {
- if library.sourceProvider != nil {
- // Assume the first source from the source provider is the library entry point.
- return library.sourceProvider.Srcs()[0]
- } else {
- path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
- return path
- }
- }
- func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
- deps PathDeps) android.OptionalPath {
- // rustdoc has builtin support for documenting config specific information
- // regardless of the actual config it was given
- // (https://doc.rust-lang.org/rustdoc/advanced-features.html#cfgdoc-documenting-platform-specific-or-feature-specific-information),
- // so we generate the rustdoc for only the primary module so that we have a
- // single set of docs to refer to.
- if ctx.Module() != ctx.PrimaryModule() {
- return android.OptionalPath{}
- }
- return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
- deps, flags))
- }
- func (library *libraryDecorator) getStem(ctx ModuleContext) string {
- stem := library.baseCompiler.getStemWithoutSuffix(ctx)
- validateLibraryStem(ctx, stem, library.crateName())
- return stem + String(library.baseCompiler.Properties.Suffix)
- }
- func (library *libraryDecorator) install(ctx ModuleContext) {
- // Only shared and dylib variants make sense to install.
- if library.shared() || library.dylib() {
- library.baseCompiler.install(ctx)
- }
- }
- func (library *libraryDecorator) Disabled() bool {
- return library.MutatedProperties.VariantIsDisabled
- }
- func (library *libraryDecorator) SetDisabled() {
- library.MutatedProperties.VariantIsDisabled = true
- }
- var validCrateName = regexp.MustCompile("[^a-zA-Z0-9_]+")
- func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name string) {
- if crate_name == "" {
- ctx.PropertyErrorf("crate_name", "crate_name must be defined.")
- }
- // crate_names are used for the library output file, and rustc expects these
- // to be alphanumeric with underscores allowed.
- if validCrateName.MatchString(crate_name) {
- ctx.PropertyErrorf("crate_name",
- "library crate_names must be alphanumeric with underscores allowed")
- }
- // Libraries are expected to begin with "lib" followed by the crate_name
- if !strings.HasPrefix(filename, "lib"+crate_name) {
- ctx.ModuleErrorf("Invalid name or stem property; library filenames must start with lib<crate_name>")
- }
- }
- // LibraryMutator mutates the libraries into variants according to the
- // build{Rlib,Dylib} attributes.
- func LibraryMutator(mctx android.BottomUpMutatorContext) {
- // Only mutate on Rust libraries.
- m, ok := mctx.Module().(*Module)
- if !ok || m.compiler == nil {
- return
- }
- library, ok := m.compiler.(libraryInterface)
- if !ok {
- return
- }
- var variants []string
- // The source variant is used for SourceProvider modules. The other variants (i.e. rlib and dylib)
- // depend on this variant. It must be the first variant to be declared.
- sourceVariant := false
- if m.sourceProvider != nil {
- variants = append(variants, "source")
- sourceVariant = true
- }
- if library.buildRlib() {
- variants = append(variants, rlibVariation)
- }
- if library.buildDylib() {
- variants = append(variants, dylibVariation)
- }
- if len(variants) == 0 {
- return
- }
- modules := mctx.CreateLocalVariations(variants...)
- // The order of the variations (modules) matches the variant names provided. Iterate
- // through the new variation modules and set their mutated properties.
- for i, v := range modules {
- switch variants[i] {
- case rlibVariation:
- v.(*Module).compiler.(libraryInterface).setRlib()
- case dylibVariation:
- v.(*Module).compiler.(libraryInterface).setDylib()
- if v.(*Module).ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
- // TODO(b/165791368)
- // Disable dylib Vendor Ramdisk variations until we support these.
- v.(*Module).Disable()
- }
- variation := v.(*Module).ModuleBase.ImageVariation().Variation
- if strings.HasPrefix(variation, cc.VendorVariationPrefix) {
- // TODO(b/204303985)
- // Disable vendor dylibs until they are supported
- v.(*Module).Disable()
- }
- if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
- m.HasVendorVariant() &&
- !snapshot.IsVendorProprietaryModule(mctx) &&
- strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
- // cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
- // produced for Dylibs; however, dylibs should not be enabled for boardVndkVersion for
- // non-vendor proprietary modules.
- v.(*Module).Disable()
- }
- case "source":
- v.(*Module).compiler.(libraryInterface).setSource()
- // The source variant does not produce any library.
- // Disable the compilation steps.
- v.(*Module).compiler.SetDisabled()
- }
- }
- // If a source variant is created, add an inter-variant dependency
- // between the other variants and the source variant.
- if sourceVariant {
- sv := modules[0]
- for _, v := range modules[1:] {
- if !v.Enabled() {
- continue
- }
- mctx.AddInterVariantDependency(sourceDepTag, v, sv)
- }
- // Alias the source variation so it can be named directly in "srcs" properties.
- mctx.AliasVariation("source")
- }
- }
- func LibstdMutator(mctx android.BottomUpMutatorContext) {
- if m, ok := mctx.Module().(*Module); ok && m.compiler != nil && !m.compiler.Disabled() {
- switch library := m.compiler.(type) {
- case libraryInterface:
- // Only create a variant if a library is actually being built.
- if library.rlib() && !library.sysroot() {
- variants := []string{"rlib-std", "dylib-std"}
- modules := mctx.CreateLocalVariations(variants...)
- rlib := modules[0].(*Module)
- dylib := modules[1].(*Module)
- rlib.compiler.(libraryInterface).setRlibStd()
- dylib.compiler.(libraryInterface).setDylibStd()
- if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation ||
- strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) {
- // TODO(b/165791368)
- // Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib
- // variants are properly supported.
- dylib.Disable()
- }
- rlib.Properties.RustSubName += RlibStdlibSuffix
- }
- }
- }
- }
- func (l *libraryDecorator) snapshotHeaders() android.Paths {
- if l.collectedSnapshotHeaders == nil {
- panic("snapshotHeaders() must be called after collectHeadersForSnapshot()")
- }
- return l.collectedSnapshotHeaders
- }
- // collectHeadersForSnapshot collects all exported headers from library.
- // It globs header files in the source tree for exported include directories,
- // and tracks generated header files separately.
- //
- // This is to be called from GenerateAndroidBuildActions, and then collected
- // header files can be retrieved by snapshotHeaders().
- func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext, deps PathDeps) {
- ret := android.Paths{}
- // Glob together the headers from the modules include_dirs property
- for _, path := range android.CopyOfPaths(l.includeDirs) {
- dir := path.String()
- globDir := dir + "/**/*"
- glob, err := ctx.GlobWithDeps(globDir, nil)
- if err != nil {
- ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
- return
- }
- for _, header := range glob {
- // Filter out only the files with extensions that are headers.
- found := false
- for _, ext := range cc.HeaderExts {
- if strings.HasSuffix(header, ext) {
- found = true
- break
- }
- }
- if !found {
- continue
- }
- ret = append(ret, android.PathForSource(ctx, header))
- }
- }
- // Glob together the headers from C dependencies as well, starting with non-generated headers.
- ret = append(ret, cc.GlobHeadersForSnapshot(ctx, append(android.CopyOfPaths(deps.depIncludePaths), deps.depSystemIncludePaths...))...)
- // Collect generated headers from C dependencies.
- ret = append(ret, cc.GlobGeneratedHeadersForSnapshot(ctx, deps.depGeneratedHeaders)...)
- // TODO(185577950): If support for generated headers is added, they need to be collected here as well.
- l.collectedSnapshotHeaders = ret
- }
|