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
diff --git a/rust/rust.go b/rust/rust.go
index a9321be..ce81b91 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -75,6 +75,85 @@
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 @@
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) 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) 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) 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) 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 @@
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 @@
}
}
- } 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 @@
}
// 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 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 @@
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.