Merge changes Ia7deed13,I7378a46f

* changes:
  Add support for Rust C libraries.
  Add a common interface for cc linkable libraries.
This commit is contained in:
Ivan Lozano
2019-10-29 21:47:14 +00:00
committed by Gerrit Code Review
20 changed files with 1021 additions and 346 deletions

View File

@@ -157,6 +157,7 @@ bootstrap_go_package {
"cc/check.go", "cc/check.go",
"cc/coverage.go", "cc/coverage.go",
"cc/gen.go", "cc/gen.go",
"cc/linkable.go",
"cc/lto.go", "cc/lto.go",
"cc/makevars.go", "cc/makevars.go",
"cc/pgo.go", "cc/pgo.go",

View File

@@ -36,10 +36,10 @@ type AndroidMkContext interface {
Arch() android.Arch Arch() android.Arch
Os() android.OsType Os() android.OsType
Host() bool Host() bool
useVndk() bool UseVndk() bool
vndkVersion() string vndkVersion() string
static() bool static() bool
inRecovery() bool InRecovery() bool
} }
type subAndroidMkProvider interface { 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_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " "))
} }
fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.makeLinkType) fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.makeLinkType)
if c.useVndk() { if c.UseVndk() {
fmt.Fprintln(w, "LOCAL_USE_VNDK := true") 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()) 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 && 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() { !ctx.static() {
if !library.buildStubs() { if !library.buildStubs() {
ret.SubName = ".bootstrap" ret.SubName = ".bootstrap"

583
cc/cc.go

File diff suppressed because it is too large Load Diff

View File

@@ -213,7 +213,7 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string
t.Helper() t.Helper()
mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module) mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
if !mod.hasVendorVariant() { if !mod.HasVendorVariant() {
t.Errorf("%q must have vendor variant", name) 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 { if mod.vndkdep == nil {
t.Fatalf("%q must have `vndkdep`", name) t.Fatalf("%q must have `vndkdep`", name)
} }
if !mod.isVndk() { if !mod.IsVndk() {
t.Errorf("%q isVndk() must equal to true", name) t.Errorf("%q IsVndk() must equal to true", name)
} }
if mod.isVndkSp() != isVndkSp { if mod.isVndkSp() != isVndkSp {
t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp) t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)

View File

@@ -245,7 +245,7 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
// Discard vendor-NDK-linked modules, they're duplicates of fuzz targets // Discard vendor-NDK-linked modules, they're duplicates of fuzz targets
// we're going to package anyway. // we're going to package anyway.
if ccModule.useVndk() || !ccModule.Enabled() { if ccModule.UseVndk() || !ccModule.Enabled() {
return return
} }

View File

@@ -1227,45 +1227,59 @@ func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Mod
} }
func LinkageMutator(mctx android.BottomUpMutatorContext) { func LinkageMutator(mctx android.BottomUpMutatorContext) {
cc_prebuilt := false
if m, ok := mctx.Module().(*Module); ok && m.linker != nil { if m, ok := mctx.Module().(*Module); ok && m.linker != nil {
switch library := m.linker.(type) { _, cc_prebuilt = m.linker.(prebuiltLibraryInterface)
case prebuiltLibraryInterface: }
// Always create both the static and shared variants for prebuilt libraries, and then disable the one if cc_prebuilt {
// that is not being used. This allows them to share the name of a cc_library module, which requires that library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface)
// 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)
static.linker.(prebuiltLibraryInterface).setStatic() // Always create both the static and shared variants for prebuilt libraries, and then disable the one
shared.linker.(prebuiltLibraryInterface).setShared() // 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).setStatic()
static.linker.(prebuiltLibraryInterface).disablePrebuilt() shared.linker.(prebuiltLibraryInterface).setShared()
}
if !library.buildShared() {
shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
}
case libraryInterface: if !library.buildStatic() {
if library.buildStatic() && library.buildShared() { static.linker.(prebuiltLibraryInterface).disablePrebuilt()
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.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 @@ func latestStubsVersionFor(config android.Config, name string) string {
// Version mutator splits a module into the mandatory non-stubs variant // Version mutator splits a module into the mandatory non-stubs variant
// (which is unnamed) and zero or more stubs variants. // (which is unnamed) and zero or more stubs variants.
func VersionMutator(mctx android.BottomUpMutatorContext) { func VersionMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok && !m.inRecovery() && m.linker != nil { if library, ok := mctx.Module().(LinkableInterface); ok && !library.InRecovery() {
if library, ok := m.linker.(*libraryDecorator); ok && library.buildShared() && if library.CcLibrary() && library.BuildSharedVariant() && len(library.StubsVersions()) > 0 {
len(library.Properties.Stubs.Versions) > 0 {
versions := []string{} versions := []string{}
for _, v := range library.Properties.Stubs.Versions { for _, v := range library.StubsVersions() {
if _, err := strconv.Atoi(v); err != nil { if _, err := strconv.Atoi(v); err != nil {
mctx.PropertyErrorf("versions", "%q is not a number", v) mctx.PropertyErrorf("versions", "%q is not a number", v)
} }
@@ -1320,14 +1333,9 @@ func VersionMutator(mctx android.BottomUpMutatorContext) {
modules := mctx.CreateVariations(versions...) modules := mctx.CreateVariations(versions...)
for i, m := range modules { for i, m := range modules {
l := m.(*Module).linker.(*libraryDecorator)
if versions[i] != "" { if versions[i] != "" {
l.MutatedProperties.BuildStubs = true m.(LinkableInterface).SetBuildStubs()
l.MutatedProperties.StubsVersion = versions[i] m.(LinkableInterface).SetStubsVersions(versions[i])
m.(*Module).Properties.HideFromMake = true
m.(*Module).sanitize = nil
m.(*Module).stl = nil
m.(*Module).Properties.PreventInstall = true
} }
} }
} else { } else {
@@ -1353,7 +1361,7 @@ func maybeInjectBoringSSLHash(ctx android.ModuleContext, outputFile android.Modu
injectBoringSSLHash := Bool(inject) injectBoringSSLHash := Bool(inject)
ctx.VisitDirectDeps(func(dep android.Module) { ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep) 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 cc, ok := dep.(*Module); ok {
if library, ok := cc.linker.(*libraryDecorator); ok { if library, ok := cc.linker.(*libraryDecorator); ok {
if Bool(library.Properties.Inject_bssl_hash) { if Bool(library.Properties.Inject_bssl_hash) {

71
cc/linkable.go Normal file
View File

@@ -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"}
)

View File

@@ -148,7 +148,7 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) {
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
tag := mctx.OtherModuleDependencyTag(dep) tag := mctx.OtherModuleDependencyTag(dep)
switch tag { 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 && if dep, ok := dep.(*Module); ok && dep.lto != nil &&
!dep.lto.Disabled() { !dep.lto.Disabled() {
if full && !Bool(dep.lto.Properties.Lto.Full) { if full && !Bool(dep.lto.Properties.Lto.Full) {

View File

@@ -78,12 +78,12 @@ func (sabimod *sabi) flags(ctx ModuleContext, flags Flags) Flags {
func sabiDepsMutator(mctx android.TopDownMutatorContext) { func sabiDepsMutator(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && 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)) { (c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) {
mctx.VisitDirectDeps(func(m android.Module) { mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m) tag := mctx.OtherModuleDependencyTag(m)
switch tag { switch tag {
case staticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag: case StaticDepTag, staticExportDepTag, lateStaticDepTag, wholeStaticDepTag:
cc, _ := m.(*Module) cc, _ := m.(*Module)
if cc == nil { if cc == nil {

View File

@@ -678,8 +678,8 @@ func (sanitize *sanitize) isSanitizerEnabled(t sanitizerType) bool {
} }
func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool { func isSanitizableDependencyTag(tag blueprint.DependencyTag) bool {
t, ok := tag.(dependencyTag) t, ok := tag.(DependencyTag)
return ok && t.library || t == reuseObjTag || t == objDepTag return ok && t.Library || t == reuseObjTag || t == objDepTag
} }
// Propagate sanitizer requirements down from binaries // Propagate sanitizer requirements down from binaries
@@ -873,7 +873,7 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
} }
if mctx.Device() && runtimeLibrary != "" { 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 runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
} }
@@ -889,7 +889,7 @@ func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "static"}, {Mutator: "link", Variation: "static"},
{Mutator: "image", Variation: c.imageVariation()}, {Mutator: "image", Variation: c.imageVariation()},
}...), staticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...) }...), StaticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...)
} else if !c.static() && !c.header() { } else if !c.static() && !c.header() {
// dynamic executable and shared libs get shared runtime libs // dynamic executable and shared libs get shared runtime libs
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{ mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
@@ -963,7 +963,7 @@ func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
if t == cfi { if t == cfi {
appendStringSync(c.Name(), cfiStaticLibs(mctx.Config()), &cfiStaticLibsMutex) appendStringSync(c.Name(), cfiStaticLibs(mctx.Config()), &cfiStaticLibsMutex)
} else if t == hwasan { } else if t == hwasan {
if c.useVndk() { if c.UseVndk() {
appendStringSync(c.Name(), hwasanVendorStaticLibs(mctx.Config()), appendStringSync(c.Name(), hwasanVendorStaticLibs(mctx.Config()),
&hwasanStaticLibsMutex) &hwasanStaticLibsMutex)
} else { } else {

View File

@@ -20,13 +20,13 @@ import (
"strconv" "strconv"
) )
func getNdkStlFamily(m *Module) string { func getNdkStlFamily(m LinkableInterface) string {
family, _ := getNdkStlFamilyAndLinkType(m) family, _ := getNdkStlFamilyAndLinkType(m)
return family return family
} }
func getNdkStlFamilyAndLinkType(m *Module) (string, string) { func getNdkStlFamilyAndLinkType(m LinkableInterface) (string, string) {
stl := m.stl.Properties.SelectedStl stl := m.SelectedStl()
switch stl { switch stl {
case "ndk_libc++_shared": case "ndk_libc++_shared":
return "libc++", "shared" return "libc++", "shared"

View File

@@ -98,7 +98,7 @@ func (vndk *vndkdep) typeName() string {
return "native:vendor:vndkspext" 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 { if to.linker == nil {
return return
} }
@@ -125,7 +125,7 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, ta
// Other (static and LL-NDK) libraries are allowed to link. // Other (static and LL-NDK) libraries are allowed to link.
return return
} }
if !to.useVndk() { if !to.UseVndk() {
ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library", ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
vndk.typeName(), to.Name()) vndk.typeName(), to.Name())
return return
@@ -352,7 +352,7 @@ func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() && useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
mctx.DeviceConfig().VndkUseCoreVariant() && mctx.DeviceConfig().VndkUseCoreVariant() &&
!inList(m.BaseModuleName(), config.VndkMustUseVendorVariantList) !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 return false
} }
@@ -536,7 +536,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
if m.Target().NativeBridge == android.NativeBridgeEnabled { if m.Target().NativeBridge == android.NativeBridgeEnabled {
return nil, "", false return nil, "", false
} }
if !m.useVndk() || !m.IsForPlatform() || !m.installable() { if !m.UseVndk() || !m.IsForPlatform() || !m.installable() {
return nil, "", false return nil, "", false
} }
l, ok := m.linker.(vndkSnapshotLibraryInterface) l, ok := m.linker.(vndkSnapshotLibraryInterface)
@@ -699,7 +699,7 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton
if c.isVndkPrivate(config) { if c.isVndkPrivate(config) {
vndkprivate = append(vndkprivate, filename) 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() { if c.isVndkSp() {
vndksp = append(vndksp, filename) vndksp = append(vndksp, filename)
} else { } else {
@@ -708,7 +708,7 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton
if c.isVndkPrivate(config) { if c.isVndkPrivate(config) {
vndkprivate = append(vndkprivate, filename) vndkprivate = append(vndkprivate, filename)
} }
if ctx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() { if ctx.DeviceConfig().VndkUseCoreVariant() && !c.MustUseVendorVariant() {
vndkcorevariant = append(vndkcorevariant, filename) vndkcorevariant = append(vndkcorevariant, filename)
} }
} }

View File

@@ -92,7 +92,12 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
ret.Class = "RLIB_LIBRARIES" ret.Class = "RLIB_LIBRARIES"
} else if library.dylib() { } else if library.dylib() {
ret.Class = "DYLIB_LIBRARIES" 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.DistFile = library.distFile
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
if !library.rlib() { 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) 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) { 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) 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" return ".rlib"
} }
func (toolchainBase) DylibSuffix() string { func (toolchainBase) DylibSuffix() string {
return ".so" return ".dylib.so"
} }
func (toolchainBase) ProcMacroSuffix() string { func (toolchainBase) ProcMacroSuffix() string {

View File

@@ -25,8 +25,10 @@ func init() {
android.RegisterModuleType("rust_library_host", RustLibraryHostFactory) android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory) android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory) android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
android.RegisterModuleType("rust_library_shared", RustLibrarySharedFactory)
//TODO: Add support for generating standard shared/static libraries. android.RegisterModuleType("rust_library_static", RustLibraryStaticFactory)
android.RegisterModuleType("rust_library_host_shared", RustLibrarySharedHostFactory)
android.RegisterModuleType("rust_library_host_static", RustLibraryStaticHostFactory)
} }
type VariantLibraryProperties struct { type VariantLibraryProperties struct {
@@ -34,25 +36,36 @@ type VariantLibraryProperties struct {
} }
type LibraryCompilerProperties struct { type LibraryCompilerProperties struct {
Rlib VariantLibraryProperties `android:"arch_variant"` Rlib VariantLibraryProperties `android:"arch_variant"`
Dylib 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) // 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"` 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 { type LibraryMutatedProperties struct {
VariantName string `blueprint:"mutated"`
// Build a dylib variant // Build a dylib variant
BuildDylib bool `blueprint:"mutated"` BuildDylib bool `blueprint:"mutated"`
// Build an rlib variant // Build an rlib variant
BuildRlib bool `blueprint:"mutated"` 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 // This variant is a dylib
VariantIsDylib bool `blueprint:"mutated"` VariantIsDylib bool `blueprint:"mutated"`
// This variant is an rlib // This variant is an rlib
VariantIsRlib bool `blueprint:"mutated"` 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 { type libraryDecorator struct {
@@ -67,14 +80,26 @@ type libraryDecorator struct {
type libraryInterface interface { type libraryInterface interface {
rlib() bool rlib() bool
dylib() bool dylib() bool
static() bool
shared() bool
// Returns true if the build options for the module have selected a particular build type // Returns true if the build options for the module have selected a particular build type
buildRlib() bool buildRlib() bool
buildDylib() bool buildDylib() bool
buildShared() bool
buildStatic() bool
// Sets a particular variant type // Sets a particular variant type
setRlib() setRlib()
setDylib() setDylib()
setShared()
setStatic()
// Build a specific library variant
BuildOnlyRlib()
BuildOnlyDylib()
BuildOnlyStatic()
BuildOnlyShared()
} }
func (library *libraryDecorator) exportedDirs() []string { func (library *libraryDecorator) exportedDirs() []string {
@@ -101,6 +126,14 @@ func (library *libraryDecorator) dylib() bool {
return library.MutatedProperties.VariantIsDylib 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 { func (library *libraryDecorator) buildRlib() bool {
return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true) 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) 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() { func (library *libraryDecorator) setRlib() {
library.MutatedProperties.VariantIsRlib = true library.MutatedProperties.VariantIsRlib = true
library.MutatedProperties.VariantIsDylib = false library.MutatedProperties.VariantIsDylib = false
library.MutatedProperties.VariantIsStatic = false
library.MutatedProperties.VariantIsShared = false
} }
func (library *libraryDecorator) setDylib() { func (library *libraryDecorator) setDylib() {
library.MutatedProperties.VariantIsRlib = false library.MutatedProperties.VariantIsRlib = false
library.MutatedProperties.VariantIsDylib = true 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 _ compiler = (*libraryDecorator)(nil)
var _ libraryInterface = (*libraryDecorator)(nil)
// rust_library produces all variants. // rust_library produces all variants.
func RustLibraryFactory() android.Module { func RustLibraryFactory() android.Module {
@@ -141,6 +201,20 @@ func RustLibraryRlibFactory() android.Module {
return module.Init() 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. // rust_library_host produces all variants.
func RustLibraryHostFactory() android.Module { func RustLibraryHostFactory() android.Module {
module, _ := NewRustLibrary(android.HostSupported) module, _ := NewRustLibrary(android.HostSupported)
@@ -161,12 +235,44 @@ func RustLibraryRlibHostFactory() android.Module {
return module.Init() 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() { func (library *libraryDecorator) BuildOnlyDylib() {
library.MutatedProperties.BuildRlib = false library.MutatedProperties.BuildRlib = false
library.MutatedProperties.BuildShared = false
library.MutatedProperties.BuildStatic = false
} }
func (library *libraryDecorator) BuildOnlyRlib() { func (library *libraryDecorator) BuildOnlyRlib() {
library.MutatedProperties.BuildDylib = false 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) { func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
@@ -174,8 +280,10 @@ func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorat
library := &libraryDecorator{ library := &libraryDecorator{
MutatedProperties: LibraryMutatedProperties{ MutatedProperties: LibraryMutatedProperties{
BuildDylib: true, BuildDylib: true,
BuildRlib: true, BuildRlib: true,
BuildShared: true,
BuildStatic: true,
}, },
baseCompiler: NewBaseCompiler("lib", "lib64"), baseCompiler: NewBaseCompiler("lib", "lib64"),
} }
@@ -194,7 +302,7 @@ func (library *libraryDecorator) compilerProps() []interface{} {
func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
deps = library.baseCompiler.compilerDeps(ctx, 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) 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...) 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() { if library.rlib() {
fileName := library.getStem(ctx) + ctx.toolchain().RlibSuffix() fileName := library.getStem(ctx) + ctx.toolchain().RlibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName) 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() fileName := library.getStem(ctx) + ctx.toolchain().DylibSuffix()
outputFile = android.PathForModuleOut(ctx, fileName) 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) 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...) if library.rlib() || library.dylib() {
library.reexportDepFlags(deps.depFlags...) library.reexportDirs(deps.linkDirs...)
library.reexportDepFlags(deps.depFlags...)
}
library.unstrippedOutputFile = outputFile library.unstrippedOutputFile = outputFile
return outputFile return outputFile
@@ -236,19 +358,25 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok && m.compiler != nil { if m, ok := mctx.Module().(*Module); ok && m.compiler != nil {
switch library := m.compiler.(type) { switch library := m.compiler.(type) {
case libraryInterface: case libraryInterface:
if library.buildRlib() && library.buildDylib() {
modules := mctx.CreateLocalVariations("rlib", "dylib")
rlib := modules[0].(*Module)
dylib := modules[1].(*Module)
rlib.compiler.(libraryInterface).setRlib() // We only build the rust library variants here. This assumes that
dylib.compiler.(libraryInterface).setDylib() // LinkageMutator runs first and there's an empty variant
} else if library.buildRlib() { // if rust variants are required.
modules := mctx.CreateLocalVariations("rlib") if !library.static() && !library.shared() {
modules[0].(*Module).compiler.(libraryInterface).setRlib() if library.buildRlib() && library.buildDylib() {
} else if library.buildDylib() { modules := mctx.CreateLocalVariations("rlib", "dylib")
modules := mctx.CreateLocalVariations("dylib") rlib := modules[0].(*Module)
modules[0].(*Module).compiler.(libraryInterface).setDylib() 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()
}
} }
} }
} }

View File

@@ -29,19 +29,37 @@ func TestLibraryVariants(t *testing.T) {
crate_name: "foo", 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") 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. // Test crate type for rlib is correct.
if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type=rlib") { if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
t.Errorf("missing crate-type for libfoo rlib, rustcFlags: %#v", libfooRlib.Args["rustcFlags"]) t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.Args["rustcFlags"])
} }
// Test crate type for dylib is correct. // Test crate type for dylib is correct.
if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type=dylib") { if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type="+dylibCrateType) {
t.Errorf("missing crate-type for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) 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. // Test that dylibs are not statically linking the standard library.
@@ -53,7 +71,7 @@ func TestDylibPreferDynamic(t *testing.T) {
crate_name: "foo", 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") { if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])

View File

@@ -15,6 +15,7 @@
package rust package rust
import ( import (
"fmt"
"strings" "strings"
"github.com/google/blueprint" "github.com/google/blueprint"
@@ -74,6 +75,85 @@ type Module struct {
outputFile android.OptionalPath 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 { type Deps struct {
Dylibs []string Dylibs []string
Rlibs []string Rlibs []string
@@ -150,6 +230,121 @@ func (mod *Module) CrateName() string {
return strings.Replace(mod.BaseModuleName(), "-", "_", -1) 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 { func (mod *Module) Init() android.Module {
mod.AddProperties(&mod.Properties) mod.AddProperties(&mod.Properties)
@@ -311,13 +506,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directRlibDeps := []*Module{} directRlibDeps := []*Module{}
directDylibDeps := []*Module{} directDylibDeps := []*Module{}
directProcMacroDeps := []*Module{} directProcMacroDeps := []*Module{}
directSharedLibDeps := []*(cc.Module){} directSharedLibDeps := [](cc.LinkableInterface){}
directStaticLibDeps := []*(cc.Module){} directStaticLibDeps := [](cc.LinkableInterface){}
ctx.VisitDirectDeps(func(dep android.Module) { ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep) depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep) depTag := ctx.OtherModuleDependencyTag(dep)
if rustDep, ok := dep.(*Module); ok { if rustDep, ok := dep.(*Module); ok {
//Handle Rust Modules //Handle Rust Modules
@@ -365,16 +559,19 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
} }
} }
} else if ccDep, ok := dep.(*cc.Module); ok { }
//Handle C dependencies
if ccDep.Target().Os != ctx.Os() { if ccDep, ok := dep.(cc.LinkableInterface); ok {
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName) //Handle C dependencies
return if _, ok := ccDep.(*Module); !ok {
} if ccDep.Module().Target().Os != ctx.Os() {
if ccDep.Target().Arch.ArchType != ctx.Arch().ArchType { ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName) return
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() linkFile := ccDep.OutputFile()
@@ -387,25 +584,25 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
exportDep := false exportDep := false
switch depTag { switch depTag {
case cc.StaticDepTag(): case cc.StaticDepTag:
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, "-l"+libName) depPaths.depFlags = append(depPaths.depFlags, "-l"+libName)
directStaticLibDeps = append(directStaticLibDeps, ccDep) directStaticLibDeps = append(directStaticLibDeps, ccDep)
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName) mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
case cc.SharedDepTag(): case cc.SharedDepTag:
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, "-l"+libName) depPaths.depFlags = append(depPaths.depFlags, "-l"+libName)
directSharedLibDeps = append(directSharedLibDeps, ccDep) directSharedLibDeps = append(directSharedLibDeps, ccDep)
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName) mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true exportDep = true
case cc.CrtBeginDepTag(): case cc.CrtBeginDepTag:
depPaths.CrtBegin = linkFile depPaths.CrtBegin = linkFile
case cc.CrtEndDepTag(): case cc.CrtEndDepTag:
depPaths.CrtEnd = linkFile depPaths.CrtEnd = linkFile
} }
// Make sure these dependencies are propagated // 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.linkDirs = append(lib.linkDirs, linkPath)
lib.depFlags = append(lib.depFlags, "-l"+libName) lib.depFlags = append(lib.depFlags, "-l"+libName)
} else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok && exportDep { } else if procMacro, ok := mod.compiler.(*procMacroDecorator); ok && exportDep {
@@ -457,8 +654,8 @@ func linkPathFromFilePath(filepath android.Path) string {
} }
func libNameFromFilePath(filepath android.Path) string { func libNameFromFilePath(filepath android.Path) string {
libName := strings.Split(filepath.Base(), filepath.Ext())[0] libName := strings.Split(filepath.Base(), filepath.Ext())[0]
if strings.Contains(libName, "lib") { if strings.HasPrefix(libName, "lib") {
libName = strings.Split(libName, "lib")[1] libName = libName[3:]
} }
return libName return libName
} }
@@ -472,23 +669,37 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
ctx.ctx = ctx ctx.ctx = ctx
deps := mod.deps(ctx) deps := mod.deps(ctx)
commonDepVariations := []blueprint.Variation{}
actx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}, rlibDepTag, deps.Rlibs...) commonDepVariations = append(commonDepVariations,
actx.AddVariationDependencies([]blueprint.Variation{{Mutator: "rust_libraries", Variation: "dylib"}}, dylibDepTag, deps.Dylibs...) blueprint.Variation{Mutator: "version", Variation: ""})
ccDepVariations := []blueprint.Variation{}
ccDepVariations = append(ccDepVariations, blueprint.Variation{Mutator: "version", Variation: ""})
if !mod.Host() { 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 != "" { if deps.CrtBegin != "" {
actx.AddVariationDependencies(ccDepVariations, cc.CrtBeginDepTag(), deps.CrtBegin) actx.AddVariationDependencies(commonDepVariations, cc.CrtBeginDepTag, deps.CrtBegin)
} }
if deps.CrtEnd != "" { 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. // 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. // Test that we can extract the lib name from a lib path.
func TestLibNameFromFilePath(t *testing.T) { func TestLibNameFromFilePath(t *testing.T) {
barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so") libBarPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
libName := libNameFromFilePath(barPath) libLibPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/liblib.dylib.so")
expectedResult := "bar"
if libName != expectedResult { libBarName := libNameFromFilePath(libBarPath)
t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName) 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. // Test to make sure dependencies are being picked up correctly.
func TestDepsTracking(t *testing.T) { func TestDepsTracking(t *testing.T) {
ctx := testRust(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 { rust_library_host_dylib {
name: "libfoo", name: "libdylib",
srcs: ["foo.rs"], srcs: ["foo.rs"],
} }
rust_library_host_rlib { rust_library_host_rlib {
name: "libbar", name: "librlib",
srcs: ["foo.rs"], srcs: ["foo.rs"],
} }
rust_proc_macro { rust_proc_macro {
@@ -154,20 +170,22 @@ func TestDepsTracking(t *testing.T) {
} }
rust_binary_host { rust_binary_host {
name: "fizz-buzz", name: "fizz-buzz",
dylibs: ["libfoo"], dylibs: ["libdylib"],
rlibs: ["libbar"], rlibs: ["librlib"],
proc_macros: ["libpm"], proc_macros: ["libpm"],
static_libs: ["libstatic"],
shared_libs: ["libshared"],
srcs: ["foo.rs"], srcs: ["foo.rs"],
} }
`) `)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module) 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. // 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)") 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)") 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)") 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. // 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_host_dylib", android.ModuleFactoryAdaptor(RustLibraryDylibHostFactory))
ctx.RegisterModuleType("rust_library_rlib", android.ModuleFactoryAdaptor(RustLibraryRlibFactory)) ctx.RegisterModuleType("rust_library_rlib", android.ModuleFactoryAdaptor(RustLibraryRlibFactory))
ctx.RegisterModuleType("rust_library_dylib", android.ModuleFactoryAdaptor(RustLibraryDylibFactory)) 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_proc_macro", android.ModuleFactoryAdaptor(ProcMacroFactory))
ctx.RegisterModuleType("rust_prebuilt_dylib", android.ModuleFactoryAdaptor(PrebuiltDylibFactory)) ctx.RegisterModuleType("rust_prebuilt_dylib", android.ModuleFactoryAdaptor(PrebuiltDylibFactory))
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory)) ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel() // cc mutators
ctx.BottomUp("image", cc.ImageMutator).Parallel() ctx.BottomUp("image", cc.ImageMutator).Parallel()
ctx.BottomUp("link", cc.LinkageMutator).Parallel() ctx.BottomUp("link", cc.LinkageMutator).Parallel()
ctx.BottomUp("version", cc.VersionMutator).Parallel() ctx.BottomUp("version", cc.VersionMutator).Parallel()
ctx.BottomUp("begin", cc.BeginMutator).Parallel() ctx.BottomUp("begin", cc.BeginMutator).Parallel()
})
// rust mutators
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
})
bp = bp + GatherRequiredDepsForTest() bp = bp + GatherRequiredDepsForTest()
mockFS := map[string][]byte{ mockFS := map[string][]byte{