Merge changes Ia7deed13,I7378a46f
* changes:
Add support for Rust C libraries.
Add a common interface for cc linkable libraries.
diff --git a/Android.bp b/Android.bp
index 714ce37..05972fd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -157,6 +157,7 @@
"cc/check.go",
"cc/coverage.go",
"cc/gen.go",
+ "cc/linkable.go",
"cc/lto.go",
"cc/makevars.go",
"cc/pgo.go",
diff --git a/cc/androidmk.go b/cc/androidmk.go
index f278d6f..54cd722 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -36,10 +36,10 @@
Arch() android.Arch
Os() android.OsType
Host() bool
- useVndk() bool
+ UseVndk() bool
vndkVersion() string
static() bool
- inRecovery() bool
+ InRecovery() bool
}
type subAndroidMkProvider interface {
@@ -89,9 +89,9 @@
fmt.Fprintln(w, "LOCAL_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " "))
}
fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.makeLinkType)
- if c.useVndk() {
+ if c.UseVndk() {
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
- if c.isVndk() && !c.static() {
+ if c.IsVndk() && !c.static() {
fmt.Fprintln(w, "LOCAL_SOONG_VNDK_VERSION := "+c.vndkVersion())
}
}
@@ -224,7 +224,7 @@
})
}
if len(library.Properties.Stubs.Versions) > 0 &&
- android.DirectlyInAnyApex(ctx, ctx.Name()) && !ctx.inRecovery() && !ctx.useVndk() &&
+ android.DirectlyInAnyApex(ctx, ctx.Name()) && !ctx.InRecovery() && !ctx.UseVndk() &&
!ctx.static() {
if !library.buildStubs() {
ret.SubName = ".bootstrap"
diff --git a/cc/cc.go b/cc/cc.go
index 67132e4..f90f1e8 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -338,81 +338,50 @@
relativeInstallPath() string
}
-type dependencyTag struct {
- blueprint.BaseDependencyTag
- name string
- library bool
- shared bool
-
- reexportFlags bool
-
- explicitlyVersioned bool
-}
-
type xref interface {
XrefCcFiles() android.Paths
}
var (
- sharedDepTag = dependencyTag{name: "shared", library: true, shared: true}
- sharedExportDepTag = dependencyTag{name: "shared", library: true, shared: true, reexportFlags: true}
- earlySharedDepTag = dependencyTag{name: "early_shared", library: true, shared: true}
- lateSharedDepTag = dependencyTag{name: "late shared", library: true, shared: true}
- staticDepTag = dependencyTag{name: "static", library: true}
- staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
- lateStaticDepTag = dependencyTag{name: "late static", library: true}
- wholeStaticDepTag = dependencyTag{name: "whole static", library: true, reexportFlags: true}
- headerDepTag = dependencyTag{name: "header", library: true}
- headerExportDepTag = dependencyTag{name: "header", library: true, reexportFlags: true}
- genSourceDepTag = dependencyTag{name: "gen source"}
- genHeaderDepTag = dependencyTag{name: "gen header"}
- genHeaderExportDepTag = dependencyTag{name: "gen header", reexportFlags: true}
- objDepTag = dependencyTag{name: "obj"}
- crtBeginDepTag = dependencyTag{name: "crtbegin"}
- crtEndDepTag = dependencyTag{name: "crtend"}
- linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
- dynamicLinkerDepTag = dependencyTag{name: "dynamic linker"}
- reuseObjTag = dependencyTag{name: "reuse objects"}
- staticVariantTag = dependencyTag{name: "static variant"}
- ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
- ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
- vndkExtDepTag = dependencyTag{name: "vndk extends", library: true}
- runtimeDepTag = dependencyTag{name: "runtime lib"}
- coverageDepTag = dependencyTag{name: "coverage"}
- testPerSrcDepTag = dependencyTag{name: "test_per_src"}
+ sharedExportDepTag = DependencyTag{Name: "shared", Library: true, Shared: true, ReexportFlags: true}
+ earlySharedDepTag = DependencyTag{Name: "early_shared", Library: true, Shared: true}
+ lateSharedDepTag = DependencyTag{Name: "late shared", Library: true, Shared: true}
+ staticExportDepTag = DependencyTag{Name: "static", Library: true, ReexportFlags: true}
+ lateStaticDepTag = DependencyTag{Name: "late static", Library: true}
+ wholeStaticDepTag = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true}
+ headerDepTag = DependencyTag{Name: "header", Library: true}
+ headerExportDepTag = DependencyTag{Name: "header", Library: true, ReexportFlags: true}
+ genSourceDepTag = DependencyTag{Name: "gen source"}
+ genHeaderDepTag = DependencyTag{Name: "gen header"}
+ genHeaderExportDepTag = DependencyTag{Name: "gen header", ReexportFlags: true}
+ objDepTag = DependencyTag{Name: "obj"}
+ linkerFlagsDepTag = DependencyTag{Name: "linker flags file"}
+ dynamicLinkerDepTag = DependencyTag{Name: "dynamic linker"}
+ reuseObjTag = DependencyTag{Name: "reuse objects"}
+ staticVariantTag = DependencyTag{Name: "static variant"}
+ ndkStubDepTag = DependencyTag{Name: "ndk stub", Library: true}
+ ndkLateStubDepTag = DependencyTag{Name: "ndk late stub", Library: true}
+ vndkExtDepTag = DependencyTag{Name: "vndk extends", Library: true}
+ runtimeDepTag = DependencyTag{Name: "runtime lib"}
+ coverageDepTag = DependencyTag{Name: "coverage"}
+ testPerSrcDepTag = DependencyTag{Name: "test_per_src"}
)
func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
- return ok && ccDepTag.shared
+ ccDepTag, ok := depTag.(DependencyTag)
+ return ok && ccDepTag.Shared
}
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
+ ccDepTag, ok := depTag.(DependencyTag)
return ok && ccDepTag == runtimeDepTag
}
func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
+ ccDepTag, ok := depTag.(DependencyTag)
return ok && ccDepTag == testPerSrcDepTag
}
-func SharedDepTag() dependencyTag {
- return sharedDepTag
-}
-
-func StaticDepTag() dependencyTag {
- return staticDepTag
-}
-
-func CrtBeginDepTag() dependencyTag {
- return crtBeginDepTag
-}
-
-func CrtEndDepTag() dependencyTag {
- return crtEndDepTag
-}
-
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer interface
@@ -460,17 +429,212 @@
depsInLinkOrder android.Paths
// only non-nil when this is a shared library that reuses the objects of a static library
- staticVariant *Module
+ staticVariant LinkableInterface
makeLinkType string
// Kythe (source file indexer) paths for this compilation module
kytheFiles android.Paths
}
+func (c *Module) Toc() android.OptionalPath {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ return library.toc()
+ }
+ }
+ panic(fmt.Errorf("Toc() called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) ApiLevel() string {
+ if c.linker != nil {
+ if stub, ok := c.linker.(*stubDecorator); ok {
+ return stub.properties.ApiLevel
+ }
+ }
+ panic(fmt.Errorf("ApiLevel() called on non-stub library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) Static() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ return library.static()
+ }
+ }
+ panic(fmt.Errorf("Static() called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) Shared() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ return library.shared()
+ }
+ }
+ panic(fmt.Errorf("Shared() called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SelectedStl() string {
+ return c.stl.Properties.SelectedStl
+}
+
+func (c *Module) ToolchainLibrary() bool {
+ if _, ok := c.linker.(*toolchainLibraryDecorator); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) NdkPrebuiltStl() bool {
+ if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) StubDecorator() bool {
+ if _, ok := c.linker.(*stubDecorator); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) SdkVersion() string {
+ return String(c.Properties.Sdk_version)
+}
+
+func (c *Module) IncludeDirs(ctx android.BaseModuleContext) android.Paths {
+ if c.linker != nil {
+ if library, ok := c.linker.(exportedFlagsProducer); ok {
+ return library.exportedDirs()
+ }
+ }
+ panic(fmt.Errorf("IncludeDirs called on non-exportedFlagsProducer module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) HasStaticVariant() bool {
+ if c.staticVariant != nil {
+ return true
+ }
+ return false
+}
+
+func (c *Module) GetStaticVariant() LinkableInterface {
+ return c.staticVariant
+}
+
+func (c *Module) SetDepsInLinkOrder(depsInLinkOrder []android.Path) {
+ c.depsInLinkOrder = depsInLinkOrder
+}
+
+func (c *Module) GetDepsInLinkOrder() []android.Path {
+ return c.depsInLinkOrder
+}
+
+func (c *Module) StubsVersions() []string {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ return library.Properties.Stubs.Versions
+ }
+ }
+ panic(fmt.Errorf("StubsVersions called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) CcLibrary() bool {
+ if c.linker != nil {
+ if _, ok := c.linker.(*libraryDecorator); ok {
+ return true
+ }
+ }
+ return false
+}
+
+func (c *Module) CcLibraryInterface() bool {
+ if _, ok := c.linker.(libraryInterface); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) SetBuildStubs() {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ library.MutatedProperties.BuildStubs = true
+ c.Properties.HideFromMake = true
+ c.sanitize = nil
+ c.stl = nil
+ c.Properties.PreventInstall = true
+ return
+ }
+ }
+ panic(fmt.Errorf("SetBuildStubs called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) BuildStubs() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ return library.buildStubs()
+ }
+ }
+ panic(fmt.Errorf("BuildStubs called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SetStubsVersions(version string) {
+ if c.linker != nil {
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ library.MutatedProperties.StubsVersion = version
+ return
+ }
+ }
+ panic(fmt.Errorf("SetStubsVersions called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SetStatic() {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ library.setStatic()
+ return
+ }
+ }
+ panic(fmt.Errorf("SetStatic called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) SetShared() {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ library.setShared()
+ return
+ }
+ }
+ panic(fmt.Errorf("SetShared called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) BuildStaticVariant() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ return library.buildStatic()
+ }
+ }
+ panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) BuildSharedVariant() bool {
+ if c.linker != nil {
+ if library, ok := c.linker.(libraryInterface); ok {
+ return library.buildShared()
+ }
+ }
+ panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", c.BaseModuleName()))
+}
+
+func (c *Module) Module() android.Module {
+ return c
+}
+
func (c *Module) OutputFile() android.OptionalPath {
return c.outputFile
}
+var _ LinkableInterface = (*Module)(nil)
+
func (c *Module) UnstrippedOutputFile() android.Path {
if c.linker != nil {
return c.linker.unstrippedOutputFilePath()
@@ -567,7 +731,7 @@
return false
}
-func (c *Module) useVndk() bool {
+func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@@ -594,7 +758,7 @@
return inList(c.BaseModuleName(), *vndkPrivateLibraries(config))
}
-func (c *Module) isVndk() bool {
+func (c *Module) IsVndk() bool {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndk()
}
@@ -633,7 +797,7 @@
return false
}
-func (c *Module) mustUseVendorVariant() bool {
+func (c *Module) MustUseVendorVariant() bool {
return c.isVndkSp() || c.Properties.MustUseVendorVariant
}
@@ -646,15 +810,15 @@
// Returns true only when this module is configured to have core and vendor
// variants.
-func (c *Module) hasVendorVariant() bool {
- return c.isVndk() || Bool(c.VendorProperties.Vendor_available)
+func (c *Module) HasVendorVariant() bool {
+ return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
}
-func (c *Module) inRecovery() bool {
+func (c *Module) InRecovery() bool {
return c.Properties.InRecovery || c.ModuleBase.InstallInRecovery()
}
-func (c *Module) onlyInRecovery() bool {
+func (c *Module) OnlyInRecovery() bool {
return c.ModuleBase.InstallInRecovery()
}
@@ -725,7 +889,7 @@
func (ctx *moduleContext) SocSpecific() bool {
return ctx.ModuleContext.SocSpecific() ||
- (ctx.mod.hasVendorVariant() && ctx.mod.useVndk() && !ctx.mod.isVndk())
+ (ctx.mod.HasVendorVariant() && ctx.mod.UseVndk() && !ctx.mod.IsVndk())
}
type moduleContextImpl struct {
@@ -775,7 +939,7 @@
}
func (ctx *moduleContextImpl) useVndk() bool {
- return ctx.mod.useVndk()
+ return ctx.mod.UseVndk()
}
func (ctx *moduleContextImpl) isNdk() bool {
@@ -795,7 +959,7 @@
}
func (ctx *moduleContextImpl) isVndk() bool {
- return ctx.mod.isVndk()
+ return ctx.mod.IsVndk()
}
func (ctx *moduleContextImpl) isPgoCompile() bool {
@@ -815,11 +979,11 @@
}
func (ctx *moduleContextImpl) mustUseVendorVariant() bool {
- return ctx.mod.mustUseVendorVariant()
+ return ctx.mod.MustUseVendorVariant()
}
func (ctx *moduleContextImpl) inRecovery() bool {
- return ctx.mod.inRecovery()
+ return ctx.mod.InRecovery()
}
// Check whether ABI dumps should be created for this module.
@@ -971,25 +1135,27 @@
return orderedAllDeps, orderedDeclaredDeps
}
-func orderStaticModuleDeps(module *Module, staticDeps []*Module, sharedDeps []*Module) (results []android.Path) {
+func orderStaticModuleDeps(module LinkableInterface, staticDeps []LinkableInterface, sharedDeps []LinkableInterface) (results []android.Path) {
// convert Module to Path
+ var depsInLinkOrder []android.Path
allTransitiveDeps := make(map[android.Path][]android.Path, len(staticDeps))
staticDepFiles := []android.Path{}
for _, dep := range staticDeps {
- allTransitiveDeps[dep.outputFile.Path()] = dep.depsInLinkOrder
- staticDepFiles = append(staticDepFiles, dep.outputFile.Path())
+ allTransitiveDeps[dep.OutputFile().Path()] = dep.GetDepsInLinkOrder()
+ staticDepFiles = append(staticDepFiles, dep.OutputFile().Path())
}
sharedDepFiles := []android.Path{}
for _, sharedDep := range sharedDeps {
- staticAnalogue := sharedDep.staticVariant
- if staticAnalogue != nil {
- allTransitiveDeps[staticAnalogue.outputFile.Path()] = staticAnalogue.depsInLinkOrder
- sharedDepFiles = append(sharedDepFiles, staticAnalogue.outputFile.Path())
+ if sharedDep.HasStaticVariant() {
+ staticAnalogue := sharedDep.GetStaticVariant()
+ allTransitiveDeps[staticAnalogue.OutputFile().Path()] = staticAnalogue.GetDepsInLinkOrder()
+ sharedDepFiles = append(sharedDepFiles, staticAnalogue.OutputFile().Path())
}
}
// reorder the dependencies based on transitive dependencies
- module.depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps)
+ depsInLinkOrder, results = orderDeps(staticDepFiles, sharedDepFiles, allTransitiveDeps)
+ module.SetDepsInLinkOrder(depsInLinkOrder)
return results
}
@@ -1022,7 +1188,7 @@
// .vendor suffix is added for backward compatibility with VNDK snapshot whose names with
// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp.
c.Properties.SubName += vendorSuffix
- } else if _, ok := c.linker.(*llndkStubDecorator); ok || (c.useVndk() && c.hasVendorVariant()) {
+ } else if _, ok := c.linker.(*llndkStubDecorator); ok || (c.UseVndk() && c.HasVendorVariant()) {
// .vendor.{version} suffix is added only when we will have two variants: core and vendor.
// The suffix is not added for vendor-only module.
c.Properties.SubName += vendorSuffix
@@ -1033,7 +1199,7 @@
if c.Properties.VndkVersion != vendorVersion {
c.Properties.SubName += "." + c.Properties.VndkVersion
}
- } else if c.inRecovery() && !c.onlyInRecovery() {
+ } else if c.InRecovery() && !c.OnlyInRecovery() {
c.Properties.SubName += recoverySuffix
}
@@ -1143,7 +1309,7 @@
// module is marked with 'bootstrap: true').
if c.HasStubsVariants() &&
android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) &&
- !c.inRecovery() && !c.useVndk() && !c.static() && !c.isCoverageVariant() &&
+ !c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() &&
c.IsStubs() {
c.Properties.HideFromMake = false // unhide
// Note: this is still non-installable
@@ -1411,7 +1577,7 @@
}
for _, lib := range deps.StaticLibs {
- depTag := staticDepTag
+ depTag := StaticDepTag
if inList(lib, deps.ReexportStaticLibHeaders) {
depTag = staticExportDepTag
}
@@ -1429,14 +1595,14 @@
{Mutator: "link", Variation: "static"},
}, lateStaticDepTag, deps.LateStaticLibs...)
- addSharedLibDependencies := func(depTag dependencyTag, name string, version string) {
+ addSharedLibDependencies := func(depTag DependencyTag, name string, version string) {
var variations []blueprint.Variation
variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
- versionVariantAvail := !ctx.useVndk() && !c.inRecovery()
+ versionVariantAvail := !ctx.useVndk() && !c.InRecovery()
if version != "" && versionVariantAvail {
// Version is explicitly specified. i.e. libFoo#30
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
- depTag.explicitlyVersioned = true
+ depTag.ExplicitlyVersioned = true
}
actx.AddVariationDependencies(variations, depTag, name)
@@ -1449,7 +1615,7 @@
{Mutator: "link", Variation: "shared"},
{Mutator: "version", Variation: latestVersion},
}, depTag, name)
- // Note that depTag.explicitlyVersioned is false in this case.
+ // Note that depTag.ExplicitlyVersioned is false in this case.
}
}
@@ -1457,7 +1623,7 @@
var sharedLibNames []string
for _, lib := range deps.SharedLibs {
- depTag := sharedDepTag
+ depTag := SharedDepTag
if inList(lib, deps.ReexportSharedLibHeaders) {
depTag = sharedExportDepTag
}
@@ -1499,10 +1665,10 @@
actx.AddVariationDependencies(nil, objDepTag, deps.ObjFiles...)
if deps.CrtBegin != "" {
- actx.AddVariationDependencies(nil, crtBeginDepTag, deps.CrtBegin)
+ actx.AddVariationDependencies(nil, CrtBeginDepTag, deps.CrtBegin)
}
if deps.CrtEnd != "" {
- actx.AddVariationDependencies(nil, crtEndDepTag, deps.CrtEnd)
+ actx.AddVariationDependencies(nil, CrtEndDepTag, deps.CrtEnd)
}
if deps.LinkerFlagsFile != "" {
actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
@@ -1545,52 +1711,58 @@
// Whether a module can link to another module, taking into
// account NDK linking.
-func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag dependencyTag) {
- if from.Target().Os != android.Android {
+func checkLinkType(ctx android.ModuleContext, from LinkableInterface, to LinkableInterface, tag DependencyTag) {
+ if from.Module().Target().Os != android.Android {
// Host code is not restricted
return
}
- if from.useVndk() {
+
+ // VNDK is cc.Module supported only for now.
+ if ccFrom, ok := from.(*Module); ok && from.UseVndk() {
// Though vendor code is limited by the vendor mutator,
// each vendor-available module needs to check
// link-type for VNDK.
- if from.vndkdep != nil {
- from.vndkdep.vndkCheckLinkType(ctx, to, tag)
+ if ccTo, ok := to.(*Module); ok {
+ if ccFrom.vndkdep != nil {
+ ccFrom.vndkdep.vndkCheckLinkType(ctx, ccTo, tag)
+ }
+ } else {
+ ctx.ModuleErrorf("Attempting to link VNDK cc.Module with unsupported module type")
}
return
}
- if String(from.Properties.Sdk_version) == "" {
+ if from.SdkVersion() == "" {
// Platform code can link to anything
return
}
- if from.inRecovery() {
+ if from.InRecovery() {
// Recovery code is not NDK
return
}
- if _, ok := to.linker.(*toolchainLibraryDecorator); ok {
+ if to.ToolchainLibrary() {
// These are always allowed
return
}
- if _, ok := to.linker.(*ndkPrebuiltStlLinker); ok {
+ if to.NdkPrebuiltStl() {
// These are allowed, but they don't set sdk_version
return
}
- if _, ok := to.linker.(*stubDecorator); ok {
+ if to.StubDecorator() {
// These aren't real libraries, but are the stub shared libraries that are included in
// the NDK.
return
}
- if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Name() == "libc++" {
+ if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" {
// Bug: http://b/121358700 - Allow libclang_rt.* shared libraries (with sdk_version)
// to link to libc++ (non-NDK and without sdk_version).
return
}
- if String(to.Properties.Sdk_version) == "" {
+ if to.SdkVersion() == "" {
// NDK code linking to platform code is never okay.
ctx.ModuleErrorf("depends on non-NDK-built library %q",
- ctx.OtherModuleName(to))
+ ctx.OtherModuleName(to.Module()))
return
}
@@ -1600,36 +1772,36 @@
// APIs.
// Current can link against anything.
- if String(from.Properties.Sdk_version) != "current" {
+ if from.SdkVersion() != "current" {
// Otherwise we need to check.
- if String(to.Properties.Sdk_version) == "current" {
+ if to.SdkVersion() == "current" {
// Current can't be linked against by anything else.
ctx.ModuleErrorf("links %q built against newer API version %q",
- ctx.OtherModuleName(to), "current")
+ ctx.OtherModuleName(to.Module()), "current")
} else {
- fromApi, err := strconv.Atoi(String(from.Properties.Sdk_version))
+ fromApi, err := strconv.Atoi(from.SdkVersion())
if err != nil {
ctx.PropertyErrorf("sdk_version",
"Invalid sdk_version value (must be int or current): %q",
- String(from.Properties.Sdk_version))
+ from.SdkVersion())
}
- toApi, err := strconv.Atoi(String(to.Properties.Sdk_version))
+ toApi, err := strconv.Atoi(to.SdkVersion())
if err != nil {
ctx.PropertyErrorf("sdk_version",
"Invalid sdk_version value (must be int or current): %q",
- String(to.Properties.Sdk_version))
+ to.SdkVersion())
}
if toApi > fromApi {
ctx.ModuleErrorf("links %q built against newer API version %q",
- ctx.OtherModuleName(to), String(to.Properties.Sdk_version))
+ ctx.OtherModuleName(to.Module()), to.SdkVersion())
}
}
}
// Also check that the two STL choices are compatible.
- fromStl := from.stl.Properties.SelectedStl
- toStl := to.stl.Properties.SelectedStl
+ fromStl := from.SelectedStl()
+ toStl := to.SelectedStl()
if fromStl == "" || toStl == "" {
// Libraries that don't use the STL are unrestricted.
} else if fromStl == "ndk_system" || toStl == "ndk_system" {
@@ -1638,8 +1810,8 @@
// using either libc++ or nothing.
} else if getNdkStlFamily(from) != getNdkStlFamily(to) {
ctx.ModuleErrorf("uses %q and depends on %q which uses incompatible %q",
- from.stl.Properties.SelectedStl, ctx.OtherModuleName(to),
- to.stl.Properties.SelectedStl)
+ from.SelectedStl(), ctx.OtherModuleName(to.Module()),
+ to.SelectedStl())
}
}
@@ -1661,7 +1833,7 @@
}
// if target lib has no vendor variant, keep checking dependency graph
- if !to.hasVendorVariant() {
+ if !to.HasVendorVariant() {
return true
}
@@ -1691,8 +1863,8 @@
func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
- directStaticDeps := []*Module{}
- directSharedDeps := []*Module{}
+ directStaticDeps := []LinkableInterface{}
+ directSharedDeps := []LinkableInterface{}
llndkLibraries := llndkLibraries(ctx.Config())
vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
@@ -1708,8 +1880,9 @@
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
- ccDep, _ := dep.(*Module)
- if ccDep == nil {
+ ccDep, ok := dep.(LinkableInterface)
+ if !ok {
+
// handling for a few module types that aren't cc Module but that are also supported
switch depTag {
case genSourceDepTag:
@@ -1767,9 +1940,10 @@
// re-exporting flags
if depTag == reuseObjTag {
- if l, ok := ccDep.compiler.(libraryInterface); ok {
+ // reusing objects only make sense for cc.Modules.
+ if ccReuseDep, ok := ccDep.(*Module); ok && ccDep.CcLibraryInterface() {
c.staticVariant = ccDep
- objs, exporter := l.reuseObjs()
+ objs, exporter := ccReuseDep.compiler.(libraryInterface).reuseObjs()
depPaths.Objs = depPaths.Objs.Append(objs)
reexportExporter(exporter)
return
@@ -1777,30 +1951,31 @@
}
if depTag == staticVariantTag {
- if _, ok := ccDep.compiler.(libraryInterface); ok {
+ // staticVariants are a cc.Module specific concept.
+ if _, ok := ccDep.(*Module); ok && ccDep.CcLibraryInterface() {
c.staticVariant = ccDep
return
}
}
- // Extract explicitlyVersioned field from the depTag and reset it inside the struct.
- // Otherwise, sharedDepTag and lateSharedDepTag with explicitlyVersioned set to true
- // won't be matched to sharedDepTag and lateSharedDepTag.
+ // Extract ExplicitlyVersioned field from the depTag and reset it inside the struct.
+ // Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true
+ // won't be matched to SharedDepTag and lateSharedDepTag.
explicitlyVersioned := false
- if t, ok := depTag.(dependencyTag); ok {
- explicitlyVersioned = t.explicitlyVersioned
- t.explicitlyVersioned = false
+ if t, ok := depTag.(DependencyTag); ok {
+ explicitlyVersioned = t.ExplicitlyVersioned
+ t.ExplicitlyVersioned = false
depTag = t
}
- if t, ok := depTag.(dependencyTag); ok && t.library {
+ if t, ok := depTag.(DependencyTag); ok && t.Library {
depIsStatic := false
switch depTag {
- case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
depIsStatic = true
}
- if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok && !depIsStatic {
- depIsStubs := dependentLibrary.buildStubs()
+ if ccDep.CcLibrary() && !depIsStatic {
+ depIsStubs := ccDep.BuildStubs()
depHasStubs := ccDep.HasStubsVariants()
depInSameApex := android.DirectlyInApex(c.ApexName(), depName)
depInPlatform := !android.DirectlyInAnyApex(ctx, depName)
@@ -1817,7 +1992,7 @@
// If not building for APEX, use stubs only when it is from
// an APEX (and not from platform)
useThisDep = (depInPlatform != depIsStubs)
- if c.inRecovery() || c.bootstrap() {
+ if c.InRecovery() || c.bootstrap() {
// However, for recovery or bootstrap modules,
// always link to non-stub variant
useThisDep = !depIsStubs
@@ -1833,85 +2008,95 @@
}
}
- if i, ok := ccDep.linker.(exportedFlagsProducer); ok {
- depPaths.IncludeDirs = append(depPaths.IncludeDirs, i.exportedDirs()...)
- depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, i.exportedSystemDirs()...)
- depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, i.exportedDeps()...)
- depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...)
+ // Exporting flags only makes sense for cc.Modules
+ if _, ok := ccDep.(*Module); ok {
+ if i, ok := ccDep.(*Module).linker.(exportedFlagsProducer); ok {
+ depPaths.IncludeDirs = append(depPaths.IncludeDirs, i.exportedDirs()...)
+ depPaths.SystemIncludeDirs = append(depPaths.SystemIncludeDirs, i.exportedSystemDirs()...)
+ depPaths.GeneratedHeaders = append(depPaths.GeneratedHeaders, i.exportedDeps()...)
+ depPaths.Flags = append(depPaths.Flags, i.exportedFlags()...)
- if t.reexportFlags {
- reexportExporter(i)
- // Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
- // Re-exported shared library headers must be included as well since they can help us with type information
- // about template instantiations (instantiated from their headers).
- // -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
- // scripts.
- c.sabi.Properties.ReexportedIncludes = append(
- c.sabi.Properties.ReexportedIncludes, i.exportedDirs().Strings()...)
+ if t.ReexportFlags {
+ reexportExporter(i)
+ // Add these re-exported flags to help header-abi-dumper to infer the abi exported by a library.
+ // Re-exported shared library headers must be included as well since they can help us with type information
+ // about template instantiations (instantiated from their headers).
+ // -isystem headers are not included since for bionic libraries, abi-filtering is taken care of by version
+ // scripts.
+ c.sabi.Properties.ReexportedIncludes = append(
+ c.sabi.Properties.ReexportedIncludes, i.exportedDirs().Strings()...)
+ }
}
}
-
checkLinkType(ctx, c, ccDep, t)
}
var ptr *android.Paths
var depPtr *android.Paths
- linkFile := ccDep.outputFile
+ linkFile := ccDep.OutputFile()
depFile := android.OptionalPath{}
switch depTag {
- case ndkStubDepTag, sharedDepTag, sharedExportDepTag:
+ case ndkStubDepTag, SharedDepTag, sharedExportDepTag:
ptr = &depPaths.SharedLibs
depPtr = &depPaths.SharedLibsDeps
- depFile = ccDep.linker.(libraryInterface).toc()
+ depFile = ccDep.Toc()
directSharedDeps = append(directSharedDeps, ccDep)
+
case earlySharedDepTag:
ptr = &depPaths.EarlySharedLibs
depPtr = &depPaths.EarlySharedLibsDeps
- depFile = ccDep.linker.(libraryInterface).toc()
+ depFile = ccDep.Toc()
directSharedDeps = append(directSharedDeps, ccDep)
case lateSharedDepTag, ndkLateStubDepTag:
ptr = &depPaths.LateSharedLibs
depPtr = &depPaths.LateSharedLibsDeps
- depFile = ccDep.linker.(libraryInterface).toc()
- case staticDepTag, staticExportDepTag:
+ depFile = ccDep.Toc()
+ case StaticDepTag, staticExportDepTag:
ptr = nil
directStaticDeps = append(directStaticDeps, ccDep)
case lateStaticDepTag:
ptr = &depPaths.LateStaticLibs
case wholeStaticDepTag:
ptr = &depPaths.WholeStaticLibs
- staticLib, ok := ccDep.linker.(libraryInterface)
- if !ok || !staticLib.static() {
+ if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName)
return
}
- if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
- postfix := " (required by " + ctx.OtherModuleName(dep) + ")"
- for i := range missingDeps {
- missingDeps[i] += postfix
+ // Because the static library objects are included, this only makes sense
+ // in the context of proper cc.Modules.
+ if ccWholeStaticLib, ok := ccDep.(*Module); ok {
+ staticLib := ccWholeStaticLib.linker.(libraryInterface)
+ if missingDeps := staticLib.getWholeStaticMissingDeps(); missingDeps != nil {
+ postfix := " (required by " + ctx.OtherModuleName(dep) + ")"
+ for i := range missingDeps {
+ missingDeps[i] += postfix
+ }
+ ctx.AddMissingDependencies(missingDeps)
}
- ctx.AddMissingDependencies(missingDeps)
+ depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
+ } else {
+ ctx.ModuleErrorf(
+ "non-cc.Modules cannot be included as whole static libraries.", depName)
+ return
}
- depPaths.WholeStaticLibObjs = depPaths.WholeStaticLibObjs.Append(staticLib.objs())
case headerDepTag:
// Nothing
case objDepTag:
depPaths.Objs.objFiles = append(depPaths.Objs.objFiles, linkFile.Path())
- case crtBeginDepTag:
+ case CrtBeginDepTag:
depPaths.CrtBegin = linkFile
- case crtEndDepTag:
+ case CrtEndDepTag:
depPaths.CrtEnd = linkFile
case dynamicLinkerDepTag:
depPaths.DynamicLinker = linkFile
}
switch depTag {
- case staticDepTag, staticExportDepTag, lateStaticDepTag:
- staticLib, ok := ccDep.linker.(libraryInterface)
- if !ok || !staticLib.static() {
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag:
+ if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName)
return
}
@@ -1919,11 +2104,14 @@
// When combining coverage files for shared libraries and executables, coverage files
// in static libraries act as if they were whole static libraries. The same goes for
// source based Abi dump files.
- depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
- staticLib.objs().coverageFiles...)
- depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
- staticLib.objs().sAbiDumpFiles...)
-
+ // This should only be done for cc.Modules
+ if c, ok := ccDep.(*Module); ok {
+ staticLib := c.linker.(libraryInterface)
+ depPaths.StaticLibObjs.coverageFiles = append(depPaths.StaticLibObjs.coverageFiles,
+ staticLib.objs().coverageFiles...)
+ depPaths.StaticLibObjs.sAbiDumpFiles = append(depPaths.StaticLibObjs.sAbiDumpFiles,
+ staticLib.objs().sAbiDumpFiles...)
+ }
}
if ptr != nil {
@@ -1952,13 +2140,13 @@
libName = strings.TrimPrefix(libName, "prebuilt_")
isLLndk := inList(libName, *llndkLibraries)
isVendorPublicLib := inList(libName, *vendorPublicLibraries)
- bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
+ bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk
- if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.isVndk() && !ccDep.mustUseVendorVariant() && !c.inRecovery() {
+ if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && !c.InRecovery() {
// The vendor module is a no-vendor-variant VNDK library. Depend on the
// core module instead.
return libName
- } else if c.useVndk() && bothVendorAndCoreVariantsExist {
+ } else if c.UseVndk() && bothVendorAndCoreVariantsExist {
// The vendor module in Make will have been renamed to not conflict with the core
// module, so update the dependency name here accordingly.
ret := libName + vendorSuffix
@@ -1972,9 +2160,9 @@
return ret
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
return libName + vendorPublicLibrarySuffix
- } else if ccDep.inRecovery() && !ccDep.onlyInRecovery() {
+ } else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
return libName + recoverySuffix
- } else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled {
+ } else if ccDep.Module().Target().NativeBridge == android.NativeBridgeEnabled {
return libName + nativeBridgeSuffix
} else {
return libName
@@ -1983,9 +2171,9 @@
// Export the shared libs to Make.
switch depTag {
- case sharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
- if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok {
- if dependentLibrary.buildStubs() && android.InAnyApex(depName) {
+ case SharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
+ if ccDep.CcLibrary() {
+ if ccDep.BuildStubs() && android.InAnyApex(depName) {
// Add the dependency to the APEX(es) providing the library so that
// m <module> can trigger building the APEXes as well.
for _, an := range android.GetApexesForModule(depName) {
@@ -2000,11 +2188,10 @@
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName(depName))
case ndkStubDepTag, ndkLateStubDepTag:
- ndkStub := ccDep.linker.(*stubDecorator)
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs,
- depName+"."+ndkStub.properties.ApiLevel)
- case staticDepTag, staticExportDepTag, lateStaticDepTag:
+ depName+"."+ccDep.ApiLevel())
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag:
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName(depName))
case runtimeDepTag:
@@ -2054,7 +2241,7 @@
}
func (c *Module) InstallInRecovery() bool {
- return c.inRecovery()
+ return c.InRecovery()
}
func (c *Module) HostToolPath() android.OptionalPath {
@@ -2108,28 +2295,28 @@
}
func (c *Module) getMakeLinkType(actx android.ModuleContext) string {
- if c.useVndk() {
+ if c.UseVndk() {
if lib, ok := c.linker.(*llndkStubDecorator); ok {
if Bool(lib.Properties.Vendor_available) {
return "native:vndk"
}
return "native:vndk_private"
}
- if c.isVndk() && !c.isVndkExt() {
+ if c.IsVndk() && !c.isVndkExt() {
if Bool(c.VendorProperties.Vendor_available) {
return "native:vndk"
}
return "native:vndk_private"
}
return "native:vendor"
- } else if c.inRecovery() {
+ } else if c.InRecovery() {
return "native:recovery"
} else if c.Target().Os == android.Android && String(c.Properties.Sdk_version) != "" {
return "native:ndk:none:none"
// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
//family, link := getNdkStlFamilyAndLinkType(c)
//return fmt.Sprintf("native:ndk:%s:%s", family, link)
- } else if actx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() {
+ } else if actx.DeviceConfig().VndkUseCoreVariant() && !c.MustUseVendorVariant() {
return "native:platform_vndk"
} else {
return "native:platform"
@@ -2164,9 +2351,9 @@
}
func (c *Module) imageVariation() string {
- if c.useVndk() {
+ if c.UseVndk() {
return vendorMode + "." + c.Properties.VndkVersion
- } else if c.inRecovery() {
+ } else if c.InRecovery() {
return recoveryMode
}
return coreMode
@@ -2189,8 +2376,8 @@
}
func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
- if depTag, ok := ctx.OtherModuleDependencyTag(dep).(dependencyTag); ok {
- if cc, ok := dep.(*Module); ok && cc.IsStubs() && depTag.shared {
+ if depTag, ok := ctx.OtherModuleDependencyTag(dep).(DependencyTag); ok {
+ if cc, ok := dep.(*Module); ok && cc.IsStubs() && depTag.Shared {
// dynamic dep to a stubs lib crosses APEX boundary
return false
}
@@ -2341,8 +2528,16 @@
}
}
+ //TODO When LinkableInterface supports VNDK, this should be mctx.Module().(LinkableInterface)
m, ok := mctx.Module().(*Module)
if !ok {
+ if linkable, ok := mctx.Module().(LinkableInterface); ok {
+ variations := []string{coreMode}
+ if linkable.InRecovery() {
+ variations = append(variations, recoveryMode)
+ }
+ mctx.CreateVariations(variations...)
+ }
return
}
@@ -2432,12 +2627,12 @@
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
vendorVariants = append(vendorVariants, lib.version())
- } else if m.hasVendorVariant() && !vendorSpecific {
+ } else if m.HasVendorVariant() && !vendorSpecific {
// This will be available in both /system and /vendor
// or a /system directory that is available to vendor.
coreVariantNeeded = true
vendorVariants = append(vendorVariants, platformVndkVersion)
- if m.isVndk() {
+ if m.IsVndk() {
vendorVariants = append(vendorVariants, deviceVndkVersion)
}
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 635e7d0..064b1a2 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -213,7 +213,7 @@
t.Helper()
mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
- if !mod.hasVendorVariant() {
+ if !mod.HasVendorVariant() {
t.Errorf("%q must have vendor variant", name)
}
@@ -230,8 +230,8 @@
if mod.vndkdep == nil {
t.Fatalf("%q must have `vndkdep`", name)
}
- if !mod.isVndk() {
- t.Errorf("%q isVndk() must equal to true", name)
+ if !mod.IsVndk() {
+ t.Errorf("%q IsVndk() must equal to true", name)
}
if mod.isVndkSp() != isVndkSp {
t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 4d38526..2c3b973 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -245,7 +245,7 @@
// Discard vendor-NDK-linked modules, they're duplicates of fuzz targets
// we're going to package anyway.
- if ccModule.useVndk() || !ccModule.Enabled() {
+ if ccModule.UseVndk() || !ccModule.Enabled() {
return
}
diff --git a/cc/library.go b/cc/library.go
index 1943e89..5a08879 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1227,45 +1227,59 @@
}
func LinkageMutator(mctx android.BottomUpMutatorContext) {
+ cc_prebuilt := false
if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
- switch library := m.linker.(type) {
- case prebuiltLibraryInterface:
- // Always create both the static and shared variants for prebuilt libraries, and then disable the one
- // that is not being used. This allows them to share the name of a cc_library module, which requires that
- // all the variants of the cc_library also exist on the prebuilt.
- modules := mctx.CreateLocalVariations("static", "shared")
- static := modules[0].(*Module)
- shared := modules[1].(*Module)
+ _, cc_prebuilt = m.linker.(prebuiltLibraryInterface)
+ }
+ if cc_prebuilt {
+ library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface)
- static.linker.(prebuiltLibraryInterface).setStatic()
- shared.linker.(prebuiltLibraryInterface).setShared()
+ // Always create both the static and shared variants for prebuilt libraries, and then disable the one
+ // that is not being used. This allows them to share the name of a cc_library module, which requires that
+ // all the variants of the cc_library also exist on the prebuilt.
+ modules := mctx.CreateLocalVariations("static", "shared")
+ static := modules[0].(*Module)
+ shared := modules[1].(*Module)
- if !library.buildStatic() {
- static.linker.(prebuiltLibraryInterface).disablePrebuilt()
- }
- if !library.buildShared() {
- shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
- }
+ static.linker.(prebuiltLibraryInterface).setStatic()
+ shared.linker.(prebuiltLibraryInterface).setShared()
- case libraryInterface:
- if library.buildStatic() && library.buildShared() {
- modules := mctx.CreateLocalVariations("static", "shared")
- static := modules[0].(*Module)
- shared := modules[1].(*Module)
-
- static.linker.(libraryInterface).setStatic()
- shared.linker.(libraryInterface).setShared()
-
- reuseStaticLibrary(mctx, static, shared)
-
- } else if library.buildStatic() {
- modules := mctx.CreateLocalVariations("static")
- modules[0].(*Module).linker.(libraryInterface).setStatic()
- } else if library.buildShared() {
- modules := mctx.CreateLocalVariations("shared")
- modules[0].(*Module).linker.(libraryInterface).setShared()
- }
+ if !library.buildStatic() {
+ static.linker.(prebuiltLibraryInterface).disablePrebuilt()
}
+ if !library.buildShared() {
+ shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
+ }
+ } else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
+ if library.BuildStaticVariant() && library.BuildSharedVariant() {
+ variations := []string{"static", "shared"}
+
+ // Non-cc.Modules need an empty variant for their mutators.
+ if _, ok := mctx.Module().(*Module); !ok {
+ variations = append(variations, "")
+ }
+
+ modules := mctx.CreateLocalVariations(variations...)
+ static := modules[0].(LinkableInterface)
+ shared := modules[1].(LinkableInterface)
+
+ static.SetStatic()
+ shared.SetShared()
+
+ if _, ok := library.(*Module); ok {
+ reuseStaticLibrary(mctx, static.(*Module), shared.(*Module))
+ }
+ } else if library.BuildStaticVariant() {
+ modules := mctx.CreateLocalVariations("static")
+ modules[0].(LinkableInterface).SetStatic()
+ } else if library.BuildSharedVariant() {
+ modules := mctx.CreateLocalVariations("shared")
+ modules[0].(LinkableInterface).SetShared()
+ } else if _, ok := mctx.Module().(*Module); !ok {
+ // Non-cc.Modules need an empty variant for their mutators.
+ mctx.CreateLocalVariations("")
+ }
+
}
}
@@ -1292,11 +1306,10 @@
// Version mutator splits a module into the mandatory non-stubs variant
// (which is unnamed) and zero or more stubs variants.
func VersionMutator(mctx android.BottomUpMutatorContext) {
- if m, ok := mctx.Module().(*Module); ok && !m.inRecovery() && m.linker != nil {
- if library, ok := m.linker.(*libraryDecorator); ok && library.buildShared() &&
- len(library.Properties.Stubs.Versions) > 0 {
+ if library, ok := mctx.Module().(LinkableInterface); ok && !library.InRecovery() {
+ if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
versions := []string{}
- for _, v := range library.Properties.Stubs.Versions {
+ for _, v := range library.StubsVersions() {
if _, err := strconv.Atoi(v); err != nil {
mctx.PropertyErrorf("versions", "%q is not a number", v)
}
@@ -1320,14 +1333,9 @@
modules := mctx.CreateVariations(versions...)
for i, m := range modules {
- l := m.(*Module).linker.(*libraryDecorator)
if versions[i] != "" {
- l.MutatedProperties.BuildStubs = true
- l.MutatedProperties.StubsVersion = versions[i]
- m.(*Module).Properties.HideFromMake = true
- m.(*Module).sanitize = nil
- m.(*Module).stl = nil
- m.(*Module).Properties.PreventInstall = true
+ m.(LinkableInterface).SetBuildStubs()
+ m.(LinkableInterface).SetStubsVersions(versions[i])
}
}
} else {
@@ -1353,7 +1361,7 @@
injectBoringSSLHash := Bool(inject)
ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep)
- if tag == staticDepTag || tag == staticExportDepTag || tag == wholeStaticDepTag || tag == lateStaticDepTag {
+ if tag == StaticDepTag || tag == staticExportDepTag || tag == wholeStaticDepTag || tag == lateStaticDepTag {
if cc, ok := dep.(*Module); ok {
if library, ok := cc.linker.(*libraryDecorator); ok {
if Bool(library.Properties.Inject_bssl_hash) {
diff --git a/cc/linkable.go b/cc/linkable.go
new file mode 100644
index 0000000..cfbaffe
--- /dev/null
+++ b/cc/linkable.go
@@ -0,0 +1,71 @@
+package cc
+
+import (
+ "github.com/google/blueprint"
+
+ "android/soong/android"
+)
+
+type LinkableInterface interface {
+ Module() android.Module
+ CcLibrary() bool
+ CcLibraryInterface() bool
+
+ OutputFile() android.OptionalPath
+
+ IncludeDirs(ctx android.BaseModuleContext) android.Paths
+ SetDepsInLinkOrder([]android.Path)
+ GetDepsInLinkOrder() []android.Path
+
+ HasStaticVariant() bool
+ GetStaticVariant() LinkableInterface
+
+ StubsVersions() []string
+ BuildStubs() bool
+ SetBuildStubs()
+ SetStubsVersions(string)
+ HasStubsVariants() bool
+ SelectedStl() string
+ ApiLevel() string
+
+ BuildStaticVariant() bool
+ BuildSharedVariant() bool
+ SetStatic()
+ SetShared()
+ Static() bool
+ Shared() bool
+ Toc() android.OptionalPath
+
+ InRecovery() bool
+ OnlyInRecovery() bool
+
+ UseVndk() bool
+ MustUseVendorVariant() bool
+ IsVndk() bool
+ HasVendorVariant() bool
+
+ SdkVersion() string
+
+ ToolchainLibrary() bool
+ NdkPrebuiltStl() bool
+ StubDecorator() bool
+}
+
+type DependencyTag struct {
+ blueprint.BaseDependencyTag
+ Name string
+ Library bool
+ Shared bool
+
+ ReexportFlags bool
+
+ ExplicitlyVersioned bool
+}
+
+var (
+ SharedDepTag = DependencyTag{Name: "shared", Library: true, Shared: true}
+ StaticDepTag = DependencyTag{Name: "static", Library: true}
+
+ CrtBeginDepTag = DependencyTag{Name: "crtbegin"}
+ CrtEndDepTag = DependencyTag{Name: "crtend"}
+)
diff --git a/cc/lto.go b/cc/lto.go
index 431d70d..580bb09 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -148,7 +148,7 @@
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
tag := mctx.OtherModuleDependencyTag(dep)
switch tag {
- case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag, objDepTag, reuseObjTag:
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag, objDepTag, reuseObjTag:
if dep, ok := dep.(*Module); ok && dep.lto != nil &&
!dep.lto.Disabled() {
if full && !Bool(dep.lto.Properties.Lto.Full) {
diff --git a/cc/sabi.go b/cc/sabi.go
index 0999151..8a9eff0 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -78,12 +78,12 @@
func sabiDepsMutator(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok &&
- ((c.isVndk() && c.useVndk()) || inList(c.Name(), *llndkLibraries(mctx.Config())) ||
+ ((c.IsVndk() && c.UseVndk()) || inList(c.Name(), *llndkLibraries(mctx.Config())) ||
(c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) {
mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m)
switch tag {
- case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
+ case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
cc, _ := m.(*Module)
if cc == nil {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 3f0f0f4..e4c6b1c 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -678,8 +678,8 @@
}
func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
- t, ok := tag.(dependencyTag)
- return ok && t.library || t == reuseObjTag || t == objDepTag
+ t, ok := tag.(DependencyTag)
+ return ok && t.Library || t == reuseObjTag || t == objDepTag
}
// Propagate sanitizer requirements down from binaries
@@ -873,7 +873,7 @@
}
if mctx.Device() && runtimeLibrary != "" {
- if inList(runtimeLibrary, *llndkLibraries(mctx.Config())) && !c.static() && c.useVndk() {
+ if inList(runtimeLibrary, *llndkLibraries(mctx.Config())) && !c.static() && c.UseVndk() {
runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
}
@@ -889,7 +889,7 @@
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "static"},
{Mutator: "image", Variation: c.imageVariation()},
- }...), staticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...)
+ }...), StaticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...)
} else if !c.static() && !c.header() {
// dynamic executable and shared libs get shared runtime libs
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
@@ -963,7 +963,7 @@
if t == cfi {
appendStringSync(c.Name(), cfiStaticLibs(mctx.Config()), &cfiStaticLibsMutex)
} else if t == hwasan {
- if c.useVndk() {
+ if c.UseVndk() {
appendStringSync(c.Name(), hwasanVendorStaticLibs(mctx.Config()),
&hwasanStaticLibsMutex)
} else {
diff --git a/cc/stl.go b/cc/stl.go
index f9273e1..101519b 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -20,13 +20,13 @@
"strconv"
)
-func getNdkStlFamily(m *Module) string {
+func getNdkStlFamily(m LinkableInterface) string {
family, _ := getNdkStlFamilyAndLinkType(m)
return family
}
-func getNdkStlFamilyAndLinkType(m *Module) (string, string) {
- stl := m.stl.Properties.SelectedStl
+func getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
+ stl := m.SelectedStl()
switch stl {
case "ndk_libc++_shared":
return "libc++", "shared"
diff --git a/cc/vndk.go b/cc/vndk.go
index 2997204..ec8f023 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -98,7 +98,7 @@
return "native:vendor:vndkspext"
}
-func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag dependencyTag) {
+func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag DependencyTag) {
if to.linker == nil {
return
}
@@ -125,7 +125,7 @@
// Other (static and LL-NDK) libraries are allowed to link.
return
}
- if !to.useVndk() {
+ if !to.UseVndk() {
ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
vndk.typeName(), to.Name())
return
@@ -352,7 +352,7 @@
useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
mctx.DeviceConfig().VndkUseCoreVariant() &&
!inList(m.BaseModuleName(), config.VndkMustUseVendorVariantList)
- return lib.shared() && m.useVndk() && m.isVndk() && !m.isVndkExt() && !useCoreVariant
+ return lib.shared() && m.UseVndk() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant
}
return false
}
@@ -536,7 +536,7 @@
if m.Target().NativeBridge == android.NativeBridgeEnabled {
return nil, "", false
}
- if !m.useVndk() || !m.IsForPlatform() || !m.installable() {
+ if !m.UseVndk() || !m.IsForPlatform() || !m.installable() {
return nil, "", false
}
l, ok := m.linker.(vndkSnapshotLibraryInterface)
@@ -699,7 +699,7 @@
if c.isVndkPrivate(config) {
vndkprivate = append(vndkprivate, filename)
}
- } else if c.vndkVersion() == vndkVersion && c.isVndk() && !c.isVndkExt() {
+ } else if c.vndkVersion() == vndkVersion && c.IsVndk() && !c.isVndkExt() {
if c.isVndkSp() {
vndksp = append(vndksp, filename)
} else {
@@ -708,7 +708,7 @@
if c.isVndkPrivate(config) {
vndkprivate = append(vndkprivate, filename)
}
- if ctx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() {
+ if ctx.DeviceConfig().VndkUseCoreVariant() && !c.MustUseVendorVariant() {
vndkcorevariant = append(vndkcorevariant, filename)
}
}
diff --git a/rust/androidmk.go b/rust/androidmk.go
index a6208db..f933cfb 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -92,7 +92,12 @@
ret.Class = "RLIB_LIBRARIES"
} else if library.dylib() {
ret.Class = "DYLIB_LIBRARIES"
+ } else if library.static() {
+ ret.Class = "STATIC_LIBRARIES"
+ } else if library.shared() {
+ ret.Class = "SHARED_LIBRARIES"
}
+
ret.DistFile = library.distFile
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
if !library.rlib() {
diff --git a/rust/builder.go b/rust/builder.go
index 104313f..2a7643d 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -53,6 +53,14 @@
transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "dylib", includeDirs)
}
+func TransformSrctoStatic(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
+ transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "staticlib", includeDirs)
+}
+
+func TransformSrctoShared(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
+ transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "cdylib", includeDirs)
+}
+
func TransformSrctoProcMacro(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "proc-macro", includeDirs)
}
diff --git a/rust/config/toolchain.go b/rust/config/toolchain.go
index 328bca3..616d88b 100644
--- a/rust/config/toolchain.go
+++ b/rust/config/toolchain.go
@@ -95,7 +95,7 @@
return ".rlib"
}
func (toolchainBase) DylibSuffix() string {
- return ".so"
+ return ".dylib.so"
}
func (toolchainBase) ProcMacroSuffix() string {
diff --git a/rust/library.go b/rust/library.go
index c831727..273a3ce 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -25,8 +25,10 @@
android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
-
- //TODO: Add support for generating standard shared/static libraries.
+ android.RegisterModuleType("rust_library_shared", RustLibrarySharedFactory)
+ android.RegisterModuleType("rust_library_static", RustLibraryStaticFactory)
+ android.RegisterModuleType("rust_library_host_shared", RustLibrarySharedHostFactory)
+ android.RegisterModuleType("rust_library_host_static", RustLibraryStaticHostFactory)
}
type VariantLibraryProperties struct {
@@ -34,25 +36,36 @@
}
type LibraryCompilerProperties struct {
- Rlib VariantLibraryProperties `android:"arch_variant"`
- Dylib VariantLibraryProperties `android:"arch_variant"`
+ Rlib VariantLibraryProperties `android:"arch_variant"`
+ Dylib VariantLibraryProperties `android:"arch_variant"`
+ Shared VariantLibraryProperties `android:"arch_variant"`
+ Static VariantLibraryProperties `android:"arch_variant"`
// path to the source file that is the main entry point of the program (e.g. src/lib.rs)
Srcs []string `android:"path,arch_variant"`
+
+ // path to include directories to pass to cc_* modules, only relevant for static/shared variants.
+ Include_dirs []string `android:"path,arch_variant"`
}
type LibraryMutatedProperties struct {
- VariantName string `blueprint:"mutated"`
-
// 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"`
}
type libraryDecorator struct {
@@ -67,14 +80,26 @@
type libraryInterface interface {
rlib() bool
dylib() bool
+ static() bool
+ shared() 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()
+
+ // Build a specific library variant
+ BuildOnlyRlib()
+ BuildOnlyDylib()
+ BuildOnlyStatic()
+ BuildOnlyShared()
}
func (library *libraryDecorator) exportedDirs() []string {
@@ -101,6 +126,14 @@
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) buildRlib() bool {
return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
}
@@ -109,17 +142,44 @@
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) 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
}
var _ compiler = (*libraryDecorator)(nil)
+var _ libraryInterface = (*libraryDecorator)(nil)
// rust_library produces all variants.
func RustLibraryFactory() android.Module {
@@ -141,6 +201,20 @@
return module.Init()
}
+// rust_library_shared produces a shared library.
+func RustLibrarySharedFactory() android.Module {
+ module, library := NewRustLibrary(android.HostAndDeviceSupported)
+ library.BuildOnlyShared()
+ return module.Init()
+}
+
+// rust_library_static produces a static library.
+func RustLibraryStaticFactory() android.Module {
+ module, library := NewRustLibrary(android.HostAndDeviceSupported)
+ library.BuildOnlyStatic()
+ return module.Init()
+}
+
// rust_library_host produces all variants.
func RustLibraryHostFactory() android.Module {
module, _ := NewRustLibrary(android.HostSupported)
@@ -161,12 +235,44 @@
return module.Init()
}
+// rust_library_static_host produces a static library.
+func RustLibraryStaticHostFactory() android.Module {
+ module, library := NewRustLibrary(android.HostSupported)
+ library.BuildOnlyStatic()
+ return module.Init()
+}
+
+// rust_library_shared_host produces an shared library.
+func RustLibrarySharedHostFactory() android.Module {
+ module, library := NewRustLibrary(android.HostSupported)
+ library.BuildOnlyShared()
+ return module.Init()
+}
+
func (library *libraryDecorator) BuildOnlyDylib() {
library.MutatedProperties.BuildRlib = false
+ library.MutatedProperties.BuildShared = false
+ library.MutatedProperties.BuildStatic = false
+
}
func (library *libraryDecorator) BuildOnlyRlib() {
library.MutatedProperties.BuildDylib = false
+ library.MutatedProperties.BuildShared = false
+ library.MutatedProperties.BuildStatic = false
+}
+
+func (library *libraryDecorator) BuildOnlyStatic() {
+ library.MutatedProperties.BuildShared = false
+ library.MutatedProperties.BuildRlib = false
+ library.MutatedProperties.BuildDylib = false
+
+}
+
+func (library *libraryDecorator) BuildOnlyShared() {
+ library.MutatedProperties.BuildStatic = false
+ library.MutatedProperties.BuildRlib = false
+ library.MutatedProperties.BuildDylib = false
}
func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
@@ -174,8 +280,10 @@
library := &libraryDecorator{
MutatedProperties: LibraryMutatedProperties{
- BuildDylib: true,
- BuildRlib: true,
+ BuildDylib: true,
+ BuildRlib: true,
+ BuildShared: true,
+ BuildStatic: true,
},
baseCompiler: NewBaseCompiler("lib", "lib64"),
}
@@ -194,7 +302,7 @@
func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
deps = library.baseCompiler.compilerDeps(ctx, deps)
- if ctx.toolchain().Bionic() && library.dylib() {
+ if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
deps = library.baseCompiler.bionicDeps(ctx, deps)
}
@@ -208,6 +316,13 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
+ if library.dylib() || library.shared() {
+ // 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")
+ }
+
if library.rlib() {
fileName := library.getStem(ctx) + ctx.toolchain().RlibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName)
@@ -217,16 +332,23 @@
fileName := library.getStem(ctx) + ctx.toolchain().DylibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName)
- // 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")
-
TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+ } else if library.static() {
+ fileName := library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
+ outputFile = android.PathForModuleOut(ctx, fileName)
+
+ TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+ } else if library.shared() {
+ fileName := library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
+ outputFile = android.PathForModuleOut(ctx, fileName)
+
+ TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
}
- library.reexportDirs(deps.linkDirs...)
- library.reexportDepFlags(deps.depFlags...)
+ if library.rlib() || library.dylib() {
+ library.reexportDirs(deps.linkDirs...)
+ library.reexportDepFlags(deps.depFlags...)
+ }
library.unstrippedOutputFile = outputFile
return outputFile
@@ -236,19 +358,25 @@
if m, ok := mctx.Module().(*Module); ok && m.compiler != nil {
switch library := m.compiler.(type) {
case libraryInterface:
- if library.buildRlib() && library.buildDylib() {
- modules := mctx.CreateLocalVariations("rlib", "dylib")
- rlib := modules[0].(*Module)
- dylib := modules[1].(*Module)
- rlib.compiler.(libraryInterface).setRlib()
- dylib.compiler.(libraryInterface).setDylib()
- } 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()
+ // We only build the rust library variants here. This assumes that
+ // LinkageMutator runs first and there's an empty variant
+ // if rust variants are required.
+ if !library.static() && !library.shared() {
+ if library.buildRlib() && library.buildDylib() {
+ modules := mctx.CreateLocalVariations("rlib", "dylib")
+ rlib := modules[0].(*Module)
+ dylib := modules[1].(*Module)
+
+ rlib.compiler.(libraryInterface).setRlib()
+ dylib.compiler.(libraryInterface).setDylib()
+ } 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()
+ }
}
}
}
diff --git a/rust/library_test.go b/rust/library_test.go
index bf8643e..66bcd20 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -29,19 +29,37 @@
crate_name: "foo",
}`)
- // Test both variants are being built.
+ // Test all variants are being built.
libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib").Output("libfoo.rlib")
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.so")
+ libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so")
+ libfooStatic := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_static").Output("libfoo.a")
+ libfooShared := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_shared").Output("libfoo.so")
+
+ rlibCrateType := "rlib"
+ dylibCrateType := "dylib"
+ sharedCrateType := "cdylib"
+ staticCrateType := "static"
// Test crate type for rlib is correct.
- if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type=rlib") {
- t.Errorf("missing crate-type for libfoo rlib, rustcFlags: %#v", libfooRlib.Args["rustcFlags"])
+ if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
+ t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.Args["rustcFlags"])
}
// Test crate type for dylib is correct.
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type=dylib") {
- t.Errorf("missing crate-type for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
+ if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type="+dylibCrateType) {
+ t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.Args["rustcFlags"])
}
+
+ // Test crate type for C static libraries is correct.
+ if !strings.Contains(libfooStatic.Args["rustcFlags"], "crate-type="+staticCrateType) {
+ t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.Args["rustcFlags"])
+ }
+
+ // Test crate type for C shared libraries is correct.
+ if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
+ t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
+ }
+
}
// Test that dylibs are not statically linking the standard library.
@@ -53,7 +71,7 @@
crate_name: "foo",
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.so")
+ libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so")
if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
diff --git a/rust/rust.go b/rust/rust.go
index 707de4b..ce81b91 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -15,6 +15,7 @@
package rust
import (
+ "fmt"
"strings"
"github.com/google/blueprint"
@@ -74,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
@@ -150,6 +230,121 @@
return strings.Replace(mod.BaseModuleName(), "-", "_", -1)
}
+func (mod *Module) CcLibrary() bool {
+ if mod.compiler != nil {
+ if _, ok := mod.compiler.(*libraryDecorator); ok {
+ return true
+ }
+ }
+ return false
+}
+
+func (mod *Module) CcLibraryInterface() bool {
+ if mod.compiler != nil {
+ if _, ok := mod.compiler.(libraryInterface); ok {
+ return true
+ }
+ }
+ return false
+}
+
+func (mod *Module) IncludeDirs(ctx android.BaseModuleContext) android.Paths {
+ if mod.compiler != nil {
+ 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()))
+}
+
+func (mod *Module) SetStatic() {
+ if mod.compiler != nil {
+ if library, ok := mod.compiler.(libraryInterface); ok {
+ library.setStatic()
+ return
+ }
+ }
+ panic(fmt.Errorf("SetStatic called on non-library module: %q", mod.BaseModuleName()))
+}
+
+func (mod *Module) SetShared() {
+ if mod.compiler != nil {
+ if library, ok := mod.compiler.(libraryInterface); ok {
+ library.setShared()
+ return
+ }
+ }
+ panic(fmt.Errorf("SetShared called on non-library module: %q", mod.BaseModuleName()))
+}
+
+func (mod *Module) SetBuildStubs() {
+ panic("SetBuildStubs not yet implemented for rust modules")
+}
+
+func (mod *Module) SetStubsVersions(string) {
+ panic("SetStubsVersions not yet implemented for rust modules")
+}
+
+func (mod *Module) BuildStaticVariant() bool {
+ if mod.compiler != nil {
+ if library, ok := mod.compiler.(libraryInterface); ok {
+ return library.buildStatic()
+ }
+ }
+ panic(fmt.Errorf("BuildStaticVariant called on non-library module: %q", mod.BaseModuleName()))
+}
+
+func (mod *Module) BuildSharedVariant() bool {
+ if mod.compiler != nil {
+ if library, ok := mod.compiler.(libraryInterface); ok {
+ return library.buildShared()
+ }
+ }
+ panic(fmt.Errorf("BuildSharedVariant called on non-library module: %q", mod.BaseModuleName()))
+}
+
+// Rust module deps don't have a link order (?)
+func (mod *Module) SetDepsInLinkOrder([]android.Path) {}
+
+func (mod *Module) GetDepsInLinkOrder() []android.Path {
+ return []android.Path{}
+}
+
+func (mod *Module) GetStaticVariant() cc.LinkableInterface {
+ return nil
+}
+
+func (mod *Module) Module() android.Module {
+ return mod
+}
+
+func (mod *Module) StubsVersions() []string {
+ // For now, Rust has no stubs versions.
+ if mod.compiler != nil {
+ if _, ok := mod.compiler.(*libraryDecorator); ok {
+ return []string{}
+ }
+ }
+ panic(fmt.Errorf("StubsVersions called on non-library module: %q", mod.BaseModuleName()))
+}
+
+func (mod *Module) OutputFile() android.OptionalPath {
+ return mod.outputFile
+}
+
+func (mod *Module) InRecovery() bool {
+ // For now, Rust has no notion of the recovery image
+ return false
+}
+func (mod *Module) HasStaticVariant() bool {
+ if mod.GetStaticVariant() != nil {
+ return true
+ }
+ return false
+}
+
+var _ cc.LinkableInterface = (*Module)(nil)
+
func (mod *Module) Init() android.Module {
mod.AddProperties(&mod.Properties)
@@ -311,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
@@ -365,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()
@@ -387,25 +584,25 @@
exportDep := false
switch depTag {
- case cc.StaticDepTag():
+ case cc.StaticDepTag:
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, "-l"+libName)
directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
- case cc.SharedDepTag():
+ case cc.SharedDepTag:
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, "-l"+libName)
directSharedLibDeps = append(directSharedLibDeps, ccDep)
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true
- case cc.CrtBeginDepTag():
+ case cc.CrtBeginDepTag:
depPaths.CrtBegin = linkFile
- case cc.CrtEndDepTag():
+ case cc.CrtEndDepTag:
depPaths.CrtEnd = linkFile
}
// 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 {
@@ -457,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
}
@@ -472,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.
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 0c8d355..eb04e72 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -101,12 +101,20 @@
// Test that we can extract the lib name from a lib path.
func TestLibNameFromFilePath(t *testing.T) {
- barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
- libName := libNameFromFilePath(barPath)
- expectedResult := "bar"
+ libBarPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
+ libLibPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/liblib.dylib.so")
- if libName != expectedResult {
- t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
+ libBarName := libNameFromFilePath(libBarPath)
+ libLibName := libNameFromFilePath(libLibPath)
+
+ expectedResult := "bar"
+ if libBarName != expectedResult {
+ t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libBarName)
+ }
+
+ expectedResult = "lib.dylib"
+ if libLibName != expectedResult {
+ t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libLibPath)
}
}
@@ -140,12 +148,20 @@
// Test to make sure dependencies are being picked up correctly.
func TestDepsTracking(t *testing.T) {
ctx := testRust(t, `
+ rust_library_host_static {
+ name: "libstatic",
+ srcs: ["foo.rs"],
+ }
+ rust_library_host_shared {
+ name: "libshared",
+ srcs: ["foo.rs"],
+ }
rust_library_host_dylib {
- name: "libfoo",
+ name: "libdylib",
srcs: ["foo.rs"],
}
rust_library_host_rlib {
- name: "libbar",
+ name: "librlib",
srcs: ["foo.rs"],
}
rust_proc_macro {
@@ -154,20 +170,22 @@
}
rust_binary_host {
name: "fizz-buzz",
- dylibs: ["libfoo"],
- rlibs: ["libbar"],
+ dylibs: ["libdylib"],
+ rlibs: ["librlib"],
proc_macros: ["libpm"],
+ static_libs: ["libstatic"],
+ shared_libs: ["libshared"],
srcs: ["foo.rs"],
}
`)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
- if !android.InList("libfoo", module.Properties.AndroidMkDylibs) {
+ if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
t.Errorf("Dylib dependency not detected (dependency missing from AndroidMkDylibs)")
}
- if !android.InList("libbar", module.Properties.AndroidMkRlibs) {
+ if !android.InList("librlib", module.Properties.AndroidMkRlibs) {
t.Errorf("Rlib dependency not detected (dependency missing from AndroidMkRlibs)")
}
@@ -175,6 +193,13 @@
t.Errorf("Proc_macro dependency not detected (dependency missing from AndroidMkProcMacroLibs)")
}
+ if !android.InList("libshared", module.Properties.AndroidMkSharedLibs) {
+ t.Errorf("Shared library dependency not detected (dependency missing from AndroidMkSharedLibs)")
+ }
+
+ if !android.InList("libstatic", module.Properties.AndroidMkStaticLibs) {
+ t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
+ }
}
// Test to make sure proc_macros use host variants when building device modules.
diff --git a/rust/testing.go b/rust/testing.go
index 92347f1..cd63084 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -174,18 +174,23 @@
ctx.RegisterModuleType("rust_library_host_dylib", android.ModuleFactoryAdaptor(RustLibraryDylibHostFactory))
ctx.RegisterModuleType("rust_library_rlib", android.ModuleFactoryAdaptor(RustLibraryRlibFactory))
ctx.RegisterModuleType("rust_library_dylib", android.ModuleFactoryAdaptor(RustLibraryDylibFactory))
+ ctx.RegisterModuleType("rust_library_shared", android.ModuleFactoryAdaptor(RustLibrarySharedFactory))
+ ctx.RegisterModuleType("rust_library_static", android.ModuleFactoryAdaptor(RustLibraryStaticFactory))
+ ctx.RegisterModuleType("rust_library_host_shared", android.ModuleFactoryAdaptor(RustLibrarySharedHostFactory))
+ ctx.RegisterModuleType("rust_library_host_static", android.ModuleFactoryAdaptor(RustLibraryStaticHostFactory))
ctx.RegisterModuleType("rust_proc_macro", android.ModuleFactoryAdaptor(ProcMacroFactory))
ctx.RegisterModuleType("rust_prebuilt_dylib", android.ModuleFactoryAdaptor(PrebuiltDylibFactory))
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
-
+ // cc mutators
ctx.BottomUp("image", cc.ImageMutator).Parallel()
ctx.BottomUp("link", cc.LinkageMutator).Parallel()
ctx.BottomUp("version", cc.VersionMutator).Parallel()
ctx.BottomUp("begin", cc.BeginMutator).Parallel()
- })
+ // rust mutators
+ ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
+ })
bp = bp + GatherRequiredDepsForTest()
mockFS := map[string][]byte{