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
This commit is contained in:
Ivan Lozano
2019-10-18 14:49:46 -07:00
parent 183a3218e2
commit 52767be335
18 changed files with 681 additions and 270 deletions

View File

@@ -36,10 +36,10 @@ type AndroidMkContext interface {
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 @@ func (c *Module) AndroidMk() android.AndroidMkData {
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 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
})
}
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"

282
cc/cc.go
View File

@@ -429,14 +429,79 @@ type Module struct {
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) IncludeDirs() 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()
@@ -483,7 +548,7 @@ func (c *Module) CcLibrary() bool {
}
func (c *Module) CcLibraryInterface() bool {
if _, ok := c.compiler.(libraryInterface); ok {
if _, ok := c.linker.(libraryInterface); ok {
return true
}
return false
@@ -493,12 +558,25 @@ 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 {
@@ -511,7 +589,7 @@ func (c *Module) SetStubsVersions(version string) {
func (c *Module) SetStatic() {
if c.linker != nil {
if library, ok := c.linker.(*libraryDecorator); ok {
if library, ok := c.linker.(libraryInterface); ok {
library.setStatic()
return
}
@@ -521,7 +599,7 @@ func (c *Module) SetStatic() {
func (c *Module) SetShared() {
if c.linker != nil {
if library, ok := c.linker.(*libraryDecorator); ok {
if library, ok := c.linker.(libraryInterface); ok {
library.setShared()
return
}
@@ -531,7 +609,7 @@ func (c *Module) SetShared() {
func (c *Module) BuildStaticVariant() bool {
if c.linker != nil {
if library, ok := c.linker.(*libraryDecorator); ok {
if library, ok := c.linker.(libraryInterface); ok {
return library.buildStatic()
}
}
@@ -540,7 +618,7 @@ func (c *Module) BuildStaticVariant() bool {
func (c *Module) BuildSharedVariant() bool {
if c.linker != nil {
if library, ok := c.linker.(*libraryDecorator); ok {
if library, ok := c.linker.(libraryInterface); ok {
return library.buildShared()
}
}
@@ -551,10 +629,6 @@ func (c *Module) Module() android.Module {
return c
}
func (c *Module) InRecovery() bool {
return c.inRecovery()
}
func (c *Module) OutputFile() android.OptionalPath {
return c.outputFile
}
@@ -657,7 +731,7 @@ func (c *Module) isDependencyRoot() bool {
return false
}
func (c *Module) useVndk() bool {
func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@@ -684,7 +758,7 @@ func (c *Module) isVndkPrivate(config android.Config) bool {
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()
}
@@ -723,7 +797,7 @@ func (c *Module) isVndkExt() bool {
return false
}
func (c *Module) mustUseVendorVariant() bool {
func (c *Module) MustUseVendorVariant() bool {
return c.isVndkSp() || c.Properties.MustUseVendorVariant
}
@@ -736,15 +810,15 @@ func (c *Module) getVndkExtendsModuleName() string {
// 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()
}
@@ -815,7 +889,7 @@ type moduleContext struct {
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 {
@@ -865,7 +939,7 @@ func (ctx *moduleContextImpl) sdkVersion() string {
}
func (ctx *moduleContextImpl) useVndk() bool {
return ctx.mod.useVndk()
return ctx.mod.UseVndk()
}
func (ctx *moduleContextImpl) isNdk() bool {
@@ -885,7 +959,7 @@ func (ctx *moduleContextImpl) isVndkPrivate(config android.Config) bool {
}
func (ctx *moduleContextImpl) isVndk() bool {
return ctx.mod.isVndk()
return ctx.mod.IsVndk()
}
func (ctx *moduleContextImpl) isPgoCompile() bool {
@@ -905,11 +979,11 @@ func (ctx *moduleContextImpl) isVndkExt() bool {
}
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.
@@ -1114,7 +1188,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
// .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
@@ -1125,7 +1199,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
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
}
@@ -1235,7 +1309,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
// 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
@@ -1524,7 +1598,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
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})
@@ -1637,52 +1711,58 @@ func BeginMutator(ctx android.BottomUpMutatorContext) {
// 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
}
@@ -1692,36 +1772,36 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag Depe
// 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" {
@@ -1730,8 +1810,8 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag Depe
// 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())
}
}
@@ -1753,7 +1833,7 @@ func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
}
// if target lib has no vendor variant, keep checking dependency graph
if !to.hasVendorVariant() {
if !to.HasVendorVariant() {
return true
}
@@ -1800,8 +1880,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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:
@@ -1859,9 +1940,10 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// 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
@@ -1869,7 +1951,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
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
}
@@ -1891,8 +1974,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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)
@@ -1909,7 +1992,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// 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
@@ -1925,7 +2008,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
}
if i, ok := ccDep.linker.(exportedFlagsProducer); ok {
// 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()...)
@@ -1942,32 +2027,32 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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:
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()
depFile = ccDep.Toc()
case StaticDepTag, staticExportDepTag:
ptr = nil
directStaticDeps = append(directStaticDeps, ccDep)
@@ -1975,12 +2060,15 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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
}
// 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 {
@@ -1989,6 +2077,11 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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
}
case headerDepTag:
// Nothing
case objDepTag:
@@ -2003,8 +2096,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
switch depTag {
case StaticDepTag, staticExportDepTag, lateStaticDepTag:
staticLib, ok := ccDep.linker.(libraryInterface)
if !ok || !staticLib.static() {
if !ccDep.CcLibraryInterface() || !ccDep.Static() {
ctx.ModuleErrorf("module %q not a static library", depName)
return
}
@@ -2012,11 +2104,14 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// 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.
// 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 {
@@ -2045,13 +2140,13 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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
@@ -2065,9 +2160,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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
@@ -2077,8 +2172,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
// 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) {
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) {
@@ -2093,10 +2188,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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)
depName+"."+ccDep.ApiLevel())
case StaticDepTag, staticExportDepTag, lateStaticDepTag:
c.Properties.AndroidMkStaticLibs = append(
c.Properties.AndroidMkStaticLibs, makeLibName(depName))
@@ -2147,7 +2241,7 @@ func (c *Module) InstallInSanitizerDir() bool {
}
func (c *Module) InstallInRecovery() bool {
return c.inRecovery()
return c.InRecovery()
}
func (c *Module) HostToolPath() android.OptionalPath {
@@ -2201,28 +2295,28 @@ func (c *Module) header() bool {
}
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"
@@ -2257,9 +2351,9 @@ func (c *Module) installable() bool {
}
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
@@ -2434,8 +2528,16 @@ func ImageMutator(mctx android.BottomUpMutatorContext) {
}
}
//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
}
@@ -2525,12 +2627,12 @@ func ImageMutator(mctx android.BottomUpMutatorContext) {
// 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) == "" {

View File

@@ -213,7 +213,7 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string
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 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string
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)

View File

@@ -207,7 +207,7 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
// 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
}

View File

@@ -1227,9 +1227,13 @@ func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Mod
}
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:
_, cc_prebuilt = m.linker.(prebuiltLibraryInterface)
}
if cc_prebuilt {
library := mctx.Module().(*Module).linker.(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.
@@ -1246,26 +1250,36 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
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"}
case libraryInterface:
if library.buildStatic() && library.buildShared() {
modules := mctx.CreateLocalVariations("static", "shared")
static := modules[0].(*Module)
shared := modules[1].(*Module)
// Non-cc.Modules need an empty variant for their mutators.
if _, ok := mctx.Module().(*Module); !ok {
variations = append(variations, "")
}
static.linker.(libraryInterface).setStatic()
shared.linker.(libraryInterface).setShared()
modules := mctx.CreateLocalVariations(variations...)
static := modules[0].(LinkableInterface)
shared := modules[1].(LinkableInterface)
reuseStaticLibrary(mctx, static, shared)
static.SetStatic()
shared.SetShared()
} else if library.buildStatic() {
if _, ok := library.(*Module); ok {
reuseStaticLibrary(mctx, static.(*Module), shared.(*Module))
}
} else if library.BuildStaticVariant() {
modules := mctx.CreateLocalVariations("static")
modules[0].(*Module).linker.(libraryInterface).setStatic()
} else if library.buildShared() {
modules[0].(LinkableInterface).SetStatic()
} else if library.BuildSharedVariant() {
modules := mctx.CreateLocalVariations("shared")
modules[0].(*Module).linker.(libraryInterface).setShared()
}
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 @@ func latestStubsVersionFor(config android.Config, name string) string {
// 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 @@ func VersionMutator(mctx android.BottomUpMutatorContext) {
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 {

View File

@@ -11,10 +11,9 @@ type LinkableInterface interface {
CcLibrary() bool
CcLibraryInterface() bool
InRecovery() bool
OutputFile() android.OptionalPath
IncludeDirs() android.Paths
IncludeDirs(ctx android.BaseModuleContext) android.Paths
SetDepsInLinkOrder([]android.Path)
GetDepsInLinkOrder() []android.Path
@@ -22,13 +21,34 @@ type LinkableInterface interface {
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 {

View File

@@ -78,7 +78,7 @@ func (sabimod *sabi) flags(ctx ModuleContext, flags Flags) Flags {
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)

View File

@@ -873,7 +873,7 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
}
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
}
@@ -963,7 +963,7 @@ func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
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 {

View File

@@ -20,13 +20,13 @@ import (
"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"

View File

@@ -125,7 +125,7 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, ta
// 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 @@ func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
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 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
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 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton
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 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton
if c.isVndkPrivate(config) {
vndkprivate = append(vndkprivate, filename)
}
if ctx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() {
if ctx.DeviceConfig().VndkUseCoreVariant() && !c.MustUseVendorVariant() {
vndkcorevariant = append(vndkcorevariant, filename)
}
}

View File

@@ -92,7 +92,12 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
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() {

View File

@@ -53,6 +53,14 @@ func TransformSrctoDylib(ctx android.ModuleContext, mainSrc android.Path, deps P
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)
}

View File

@@ -95,7 +95,7 @@ func (toolchainBase) RlibSuffix() string {
return ".rlib"
}
func (toolchainBase) DylibSuffix() string {
return ".so"
return ".dylib.so"
}
func (toolchainBase) ProcMacroSuffix() string {

View File

@@ -25,8 +25,10 @@ func init() {
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 {
@@ -36,23 +38,34 @@ type VariantLibraryProperties struct {
type LibraryCompilerProperties struct {
Rlib VariantLibraryProperties `android:"arch_variant"`
Dylib VariantLibraryProperties `android:"arch_variant"`
Shared VariantLibraryProperties `android:"arch_variant"`
Static VariantLibraryProperties `android:"arch_variant"`
// path to 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 libraryDecorator struct {
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 @@ func (library *libraryDecorator) dylib() bool {
return library.MutatedProperties.VariantIsDylib
}
func (library *libraryDecorator) shared() bool {
return library.MutatedProperties.VariantIsShared
}
func (library *libraryDecorator) static() bool {
return library.MutatedProperties.VariantIsStatic
}
func (library *libraryDecorator) buildRlib() bool {
return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
}
@@ -109,17 +142,44 @@ func (library *libraryDecorator) buildDylib() bool {
return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
}
func (library *libraryDecorator) buildShared() bool {
return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
}
func (library *libraryDecorator) buildStatic() bool {
return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
}
func (library *libraryDecorator) setRlib() {
library.MutatedProperties.VariantIsRlib = true
library.MutatedProperties.VariantIsDylib = false
library.MutatedProperties.VariantIsStatic = false
library.MutatedProperties.VariantIsShared = false
}
func (library *libraryDecorator) setDylib() {
library.MutatedProperties.VariantIsRlib = false
library.MutatedProperties.VariantIsDylib = true
library.MutatedProperties.VariantIsStatic = false
library.MutatedProperties.VariantIsShared = false
}
func (library *libraryDecorator) 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 @@ func RustLibraryRlibFactory() android.Module {
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 @@ func RustLibraryRlibHostFactory() android.Module {
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) {
@@ -176,6 +282,8 @@ func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorat
MutatedProperties: LibraryMutatedProperties{
BuildDylib: true,
BuildRlib: true,
BuildShared: true,
BuildStatic: true,
},
baseCompiler: NewBaseCompiler("lib", "lib64"),
}
@@ -194,7 +302,7 @@ func (library *libraryDecorator) compilerProps() []interface{} {
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 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
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 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
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)
}
if library.rlib() || library.dylib() {
library.reexportDirs(deps.linkDirs...)
library.reexportDepFlags(deps.depFlags...)
}
library.unstrippedOutputFile = outputFile
return outputFile
@@ -236,6 +358,11 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok && m.compiler != nil {
switch library := m.compiler.(type) {
case libraryInterface:
// 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)
@@ -252,4 +379,5 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
}
}
}
}
}

View File

@@ -29,19 +29,37 @@ func TestLibraryVariants(t *testing.T) {
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 @@ func TestDylibPreferDynamic(t *testing.T) {
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"])

View File

@@ -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,17 +559,20 @@ 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() {
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.Target().Arch.ArchType != ctx.Arch().ArchType {
if ccDep.Module().Target().Arch.ArchType != ctx.Arch().ArchType {
ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
return
}
}
linkFile := ccDep.OutputFile()
linkPath := linkPathFromFilePath(linkFile.Path())
@@ -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.

View File

@@ -101,12 +101,20 @@ func testRustError(t *testing.T, pattern string, bp string) {
// 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 @@ func TestDefaultCrateName(t *testing.T) {
// 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 @@ func TestDepsTracking(t *testing.T) {
}
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 @@ func TestDepsTracking(t *testing.T) {
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.

View File

@@ -174,18 +174,23 @@ func CreateTestContext(bp string) *android.TestContext {
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{