From 52767be335c200dfbf2af3da802e24a1cc91f1bf Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Fri, 18 Oct 2019 14:49:46 -0700 Subject: Add support for Rust C libraries. Adds the ability for rust modules to be compiled as C libraries, and allows cc modules to depend on these rust-generated modules. This also means that soong-rust should not have any dependencies on soong-cc aside from what's required for testing. There's a couple small fixes included as well: - A bug in libNameFromFilePath that caused issues when library's had "lib" in their name. - VariantName is removed from rust library MutatedProperties since this was unused. Bug: 140726209 Test: Soong tests pass. Test: Example cc_binary can include a rust shared library as a dep. Test: m crosvm.experimental Change-Id: Ia7deed1345d2423001089014cc65ce7934123da4 --- rust/rust.go | 172 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 132 insertions(+), 40 deletions(-) (limited to 'rust/rust.go') diff --git a/rust/rust.go b/rust/rust.go index a9321bef2..ce81b9152 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -75,6 +75,85 @@ type Module struct { outputFile android.OptionalPath } +func (mod *Module) BuildStubs() bool { + return false +} + +func (mod *Module) HasStubsVariants() bool { + return false +} + +func (mod *Module) SelectedStl() string { + return "" +} + +func (mod *Module) ApiLevel() string { + panic(fmt.Errorf("Called ApiLevel on Rust module %q; stubs libraries are not yet supported.", mod.BaseModuleName())) +} + +func (mod *Module) Static() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok { + return library.static() + } + } + panic(fmt.Errorf("Static called on non-library module: %q", mod.BaseModuleName())) +} + +func (mod *Module) Shared() bool { + if mod.compiler != nil { + if library, ok := mod.compiler.(libraryInterface); ok { + return library.static() + } + } + panic(fmt.Errorf("Shared called on non-library module: %q", mod.BaseModuleName())) +} + +func (mod *Module) Toc() android.OptionalPath { + if mod.compiler != nil { + if _, ok := mod.compiler.(libraryInterface); ok { + return android.OptionalPath{} + } + } + panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName())) +} + +func (mod *Module) OnlyInRecovery() bool { + return false +} + +func (mod *Module) UseVndk() bool { + return false +} + +func (mod *Module) MustUseVendorVariant() bool { + return false +} + +func (mod *Module) IsVndk() bool { + return false +} + +func (mod *Module) HasVendorVariant() bool { + return false +} + +func (mod *Module) SdkVersion() string { + return "" +} + +func (mod *Module) ToolchainLibrary() bool { + return false +} + +func (mod *Module) NdkPrebuiltStl() bool { + return false +} + +func (mod *Module) StubDecorator() bool { + return false +} + type Deps struct { Dylibs []string Rlibs []string @@ -169,11 +248,10 @@ func (mod *Module) CcLibraryInterface() bool { return false } -func (mod *Module) IncludeDirs() android.Paths { +func (mod *Module) IncludeDirs(ctx android.BaseModuleContext) android.Paths { if mod.compiler != nil { - if _, ok := mod.compiler.(*libraryDecorator); ok { - //TODO add Include_dirs to libraryDecorator for C libraries. - return android.Paths{} + if library, ok := mod.compiler.(*libraryDecorator); ok { + return android.PathsForSource(ctx, library.Properties.Include_dirs) } } panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName())) @@ -181,8 +259,8 @@ func (mod *Module) IncludeDirs() android.Paths { func (mod *Module) SetStatic() { if mod.compiler != nil { - if _, ok := mod.compiler.(*libraryDecorator); ok { - //TODO add support for static variants. + if library, ok := mod.compiler.(libraryInterface); ok { + library.setStatic() return } } @@ -191,8 +269,8 @@ func (mod *Module) SetStatic() { func (mod *Module) SetShared() { if mod.compiler != nil { - if _, ok := mod.compiler.(*libraryDecorator); ok { - //TODO add support for shared variants. + if library, ok := mod.compiler.(libraryInterface); ok { + library.setShared() return } } @@ -209,9 +287,8 @@ func (mod *Module) SetStubsVersions(string) { func (mod *Module) BuildStaticVariant() bool { if mod.compiler != nil { - if _, ok := mod.compiler.(*libraryDecorator); ok { - //TODO add support for static variants. - return false + if library, ok := mod.compiler.(libraryInterface); ok { + return library.buildStatic() } } panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName())) @@ -219,9 +296,8 @@ func (mod *Module) BuildStaticVariant() bool { func (mod *Module) BuildSharedVariant() bool { if mod.compiler != nil { - if _, ok := mod.compiler.(*libraryDecorator); ok { - //TODO add support for shared variants. - return false + if library, ok := mod.compiler.(libraryInterface); ok { + return library.buildShared() } } panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName())) @@ -430,13 +506,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { directRlibDeps := []*Module{} directDylibDeps := []*Module{} directProcMacroDeps := []*Module{} - directSharedLibDeps := []*(cc.Module){} - directStaticLibDeps := []*(cc.Module){} + directSharedLibDeps := [](cc.LinkableInterface){} + directStaticLibDeps := [](cc.LinkableInterface){} ctx.VisitDirectDeps(func(dep android.Module) { depName := ctx.OtherModuleName(dep) depTag := ctx.OtherModuleDependencyTag(dep) - if rustDep, ok := dep.(*Module); ok { //Handle Rust Modules @@ -484,16 +559,19 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } } - } else if ccDep, ok := dep.(*cc.Module); ok { - //Handle C dependencies + } - if ccDep.Target().Os != ctx.Os() { - ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) - return - } - if ccDep.Target().Arch.ArchType != ctx.Arch().ArchType { - ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) - return + if ccDep, ok := dep.(cc.LinkableInterface); ok { + //Handle C dependencies + if _, ok := ccDep.(*Module); !ok { + if ccDep.Module().Target().Os != ctx.Os() { + ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) + return + } + if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType { + ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) + return + } } linkFile := ccDep.OutputFile() @@ -524,7 +602,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps { } // Make sure these dependencies are propagated - if lib, ok := mod.compiler.(*libraryDecorator); ok && (exportDep || lib.rlib()) { + if lib, ok := mod.compiler.(*libraryDecorator); ok && exportDep { lib.linkDirs = append(lib.linkDirs, linkPath) lib.depFlags = append(lib.depFlags, "-l"+libName) } else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok && exportDep { @@ -576,8 +654,8 @@ func linkPathFromFilePath(filepath android.Path) string { } func libNameFromFilePath(filepath android.Path) string { libName := strings.Split(filepath.Base(), filepath.Ext())[0] - if strings.Contains(libName, "lib") { - libName = strings.Split(libName, "lib")[1] + if strings.HasPrefix(libName, "lib") { + libName = libName[3:] } return libName } @@ -591,23 +669,37 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { ctx.ctx = ctx deps := mod.deps(ctx) - - actx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}, rlibDepTag, deps.Rlibs...) - actx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "dylib"}}, dylibDepTag, deps.Dylibs...) - - ccDepVariations := []blueprint.Variation{} - ccDepVariations = append(ccDepVariations, blueprint.Variation{Mutator: "version", Variation: ""}) + commonDepVariations := []blueprint.Variation{} + commonDepVariations = append(commonDepVariations, + blueprint.Variation{Mutator: "version", Variation: ""}) if !mod.Host() { - ccDepVariations = append(ccDepVariations, blueprint.Variation{Mutator: "image", Variation: "core"}) + commonDepVariations = append(commonDepVariations, + blueprint.Variation{Mutator: "image", Variation: "core"}) } - actx.AddVariationDependencies(append(ccDepVariations, blueprint.Variation{Mutator: "link", Variation: "shared"}), cc.SharedDepTag, deps.SharedLibs...) - actx.AddVariationDependencies(append(ccDepVariations, blueprint.Variation{Mutator: "link", Variation: "static"}), cc.StaticDepTag, deps.StaticLibs...) + + actx.AddVariationDependencies( + append(commonDepVariations, []blueprint.Variation{ + {Mutator: "rust_libraries", Variation: "rlib"}, + {Mutator: "link", Variation: ""}}...), + rlibDepTag, deps.Rlibs...) + actx.AddVariationDependencies( + append(commonDepVariations, []blueprint.Variation{ + {Mutator: "rust_libraries", Variation: "dylib"}, + {Mutator: "link", Variation: ""}}...), + dylibDepTag, deps.Dylibs...) + + actx.AddVariationDependencies(append(commonDepVariations, + blueprint.Variation{Mutator: "link", Variation: "shared"}), + cc.SharedDepTag, deps.SharedLibs...) + actx.AddVariationDependencies(append(commonDepVariations, + blueprint.Variation{Mutator: "link", Variation: "static"}), + cc.StaticDepTag, deps.StaticLibs...) if deps.CrtBegin != "" { - actx.AddVariationDependencies(ccDepVariations, cc.CrtBeginDepTag, deps.CrtBegin) + actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin) } if deps.CrtEnd != "" { - actx.AddVariationDependencies(ccDepVariations, cc.CrtEndDepTag, deps.CrtEnd) + actx.AddVariationDependencies(commonDepVariations, cc.CrtEndDepTag, deps.CrtEnd) } // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy. -- cgit v1.2.3-59-g8ed1b