diff options
Diffstat (limited to 'rust/library.go')
| -rw-r--r-- | rust/library.go | 158 |
1 files changed, 130 insertions, 28 deletions
diff --git a/rust/library.go b/rust/library.go index a44293307..3bba089e6 100644 --- a/rust/library.go +++ b/rust/library.go @@ -15,12 +15,18 @@ package rust import ( + "fmt" "regexp" "strings" "android/soong/android" ) +var ( + DylibStdlibSuffix = ".dylib-std" + RlibStdlibSuffix = ".rlib-std" +) + func init() { android.RegisterModuleType("rust_library", RustLibraryFactory) android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory) @@ -49,6 +55,9 @@ type LibraryCompilerProperties struct { // 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 { @@ -69,10 +78,15 @@ type LibraryMutatedProperties struct { 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 { @@ -91,6 +105,8 @@ type libraryInterface interface { 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 @@ -103,6 +119,11 @@ type libraryInterface interface { setDylib() setShared() setStatic() + setSource() + + // Set libstd linkage + setRlibStd() + setDylibStd() // Build a specific library variant BuildOnlyFFI() @@ -121,6 +142,10 @@ 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 } @@ -133,6 +158,18 @@ func (library *libraryDecorator) static() bool { return library.MutatedProperties.VariantIsStatic } +func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage { + // libraries should only request the RlibLinkage when building a static FFI or when variant is StaticStd + if library.static() || library.MutatedProperties.VariantIsStaticStd { + return RlibLinkage + } + return DefaultLinkage +} + +func (library *libraryDecorator) source() bool { + return library.MutatedProperties.VariantIsSource +} + func (library *libraryDecorator) buildRlib() bool { return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true) } @@ -163,6 +200,14 @@ func (library *libraryDecorator) setDylib() { library.MutatedProperties.VariantIsShared = false } +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 @@ -177,13 +222,17 @@ func (library *libraryDecorator) setStatic() { library.MutatedProperties.VariantIsDylib = false } +func (library *libraryDecorator) setSource() { + library.MutatedProperties.VariantIsSource = true +} + func (library *libraryDecorator) autoDep(ctx BaseModuleContext) autoDep { if library.rlib() || library.static() { return rlibAutoDep } else if library.dylib() || library.shared() { return dylibAutoDep } else { - panic("autoDep called on library" + ctx.ModuleName() + "that has no enabled variants.") + panic(fmt.Errorf("autoDep called on library %q that has no enabled variants.", ctx.ModuleName())) } } @@ -347,7 +396,7 @@ func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { deps = library.baseCompiler.compilerDeps(ctx, deps) if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) { - deps = bionicDeps(deps) + deps = bionicDeps(deps, false) deps.CrtBegin = "crtbegin_so" deps.CrtEnd = "crtend_so" } @@ -450,6 +499,13 @@ func (library *libraryDecorator) getStem(ctx ModuleContext) string { 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 } @@ -478,39 +534,85 @@ func validateLibraryStem(ctx BaseModuleContext, filename string, crate_name stri } } +// LibraryMutator mutates the libraries into variants according to the +// build{Rlib,Dylib} attributes. func LibraryMutator(mctx android.BottomUpMutatorContext) { - if m, ok := mctx.Module().(*Module); ok && m.compiler != nil { + // 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() + 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: - if library.buildRlib() && library.buildDylib() { - variants := []string{"rlib", "dylib"} - if m.sourceProvider != nil { - variants = append(variants, "") - } + // 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).setRlib() - dylib.compiler.(libraryInterface).setDylib() - - if m.sourceProvider != nil { - // This library is SourceProvider generated, so the non-library-producing - // variant needs to disable it's compiler and skip installation. - sourceProvider := modules[2].(*Module) - sourceProvider.compiler.SetDisabled() - } - } else if library.buildRlib() { - modules := mctx.CreateLocalVariations("rlib") - modules[0].(*Module).compiler.(libraryInterface).setRlib() - } else if library.buildDylib() { - modules := mctx.CreateLocalVariations("dylib") - modules[0].(*Module).compiler.(libraryInterface).setDylib() - } - - if m.sourceProvider != nil { - // Alias the non-library variant to the empty-string variant. - mctx.AliasVariation("") + rlib.compiler.(libraryInterface).setRlibStd() + dylib.compiler.(libraryInterface).setDylibStd() + rlib.Properties.SubName += RlibStdlibSuffix + dylib.Properties.SubName += DylibStdlibSuffix } } } |