Merge "rust: Emit toc files for cdylibs"

This commit is contained in:
Ivan Lozano
2021-11-05 13:09:20 +00:00
committed by Gerrit Code Review
10 changed files with 53 additions and 18 deletions

View File

@@ -949,8 +949,7 @@ func sourceAbiDiff(ctx android.ModuleContext, inputDump android.Path, referenceD
} }
// Generate a rule for extracting a table of contents from a shared library (.so) // Generate a rule for extracting a table of contents from a shared library (.so)
func transformSharedObjectToToc(ctx android.ModuleContext, inputFile android.Path, func TransformSharedObjectToToc(ctx android.ModuleContext, inputFile android.Path, outputFile android.WritablePath) {
outputFile android.WritablePath, flags builderFlags) {
var format string var format string
if ctx.Darwin() { if ctx.Darwin() {

View File

@@ -1377,7 +1377,7 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
// depending on a table of contents file instead of the library itself. // depending on a table of contents file instead of the library itself.
tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc") tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc")
library.tocFile = android.OptionalPathForPath(tocFile) library.tocFile = android.OptionalPathForPath(tocFile)
transformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags) TransformSharedObjectToToc(ctx, outputFile, tocFile)
stripFlags := flagsToStripFlags(flags) stripFlags := flagsToStripFlags(flags)
needsStrip := library.stripper.NeedsStrip(ctx) needsStrip := library.stripper.NeedsStrip(ctx)

View File

@@ -114,8 +114,6 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
// TODO(ccross): verify shared library dependencies // TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs(ctx) srcs := p.prebuiltSrcs(ctx)
if len(srcs) > 0 { if len(srcs) > 0 {
builderFlags := flagsToBuilderFlags(flags)
if len(srcs) > 1 { if len(srcs) > 1 {
ctx.PropertyErrorf("srcs", "multiple prebuilt source files") ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
return nil return nil
@@ -152,7 +150,7 @@ func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
// depending on a table of contents file instead of the library itself. // depending on a table of contents file instead of the library itself.
tocFile := android.PathForModuleOut(ctx, libName+".toc") tocFile := android.PathForModuleOut(ctx, libName+".toc")
p.tocFile = android.OptionalPathForPath(tocFile) p.tocFile = android.OptionalPathForPath(tocFile)
transformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags) TransformSharedObjectToToc(ctx, outputFile, tocFile)
if ctx.Windows() && p.properties.Windows_import_lib != nil { if ctx.Windows() && p.properties.Windows_import_lib != nil {
// Consumers of this library actually links to the import library in build // Consumers of this library actually links to the import library in build

View File

@@ -476,13 +476,12 @@ func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps Pat
if p.shared() { if p.shared() {
libName := in.Base() libName := in.Base()
builderFlags := flagsToBuilderFlags(flags)
// Optimize out relinking against shared libraries whose interface hasn't changed by // Optimize out relinking against shared libraries whose interface hasn't changed by
// depending on a table of contents file instead of the library itself. // depending on a table of contents file instead of the library itself.
tocFile := android.PathForModuleOut(ctx, libName+".toc") tocFile := android.PathForModuleOut(ctx, libName+".toc")
p.tocFile = android.OptionalPathForPath(tocFile) p.tocFile = android.OptionalPathForPath(tocFile)
transformSharedObjectToToc(ctx, in, tocFile, builderFlags) TransformSharedObjectToToc(ctx, in, tocFile)
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: in, SharedLibrary: in,

View File

@@ -144,7 +144,6 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
// current VNDK prebuilts are only shared libs. // current VNDK prebuilts are only shared libs.
in := p.singleSourcePath(ctx) in := p.singleSourcePath(ctx)
builderFlags := flagsToBuilderFlags(flags)
p.unstrippedOutputFile = in p.unstrippedOutputFile = in
libName := in.Base() libName := in.Base()
if p.stripper.NeedsStrip(ctx) { if p.stripper.NeedsStrip(ctx) {
@@ -158,7 +157,7 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
// depending on a table of contents file instead of the library itself. // depending on a table of contents file instead of the library itself.
tocFile := android.PathForModuleOut(ctx, libName+".toc") tocFile := android.PathForModuleOut(ctx, libName+".toc")
p.tocFile = android.OptionalPathForPath(tocFile) p.tocFile = android.OptionalPathForPath(tocFile)
transformSharedObjectToToc(ctx, in, tocFile, builderFlags) TransformSharedObjectToToc(ctx, in, tocFile)
p.androidMkSuffix = p.NameSuffix() p.androidMkSuffix = p.NameSuffix()

View File

@@ -137,12 +137,16 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
} else if library.shared() { } else if library.shared() {
ret.Class = "SHARED_LIBRARIES" ret.Class = "SHARED_LIBRARIES"
} }
if library.distFile.Valid() { if library.distFile.Valid() {
ret.DistFiles = android.MakeDefaultDistFiles(library.distFile.Path()) ret.DistFiles = android.MakeDefaultDistFiles(library.distFile.Path())
} }
ret.ExtraEntries = append(ret.ExtraEntries,
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
if library.tocFile.Valid() {
entries.SetString("LOCAL_SOONG_TOC", library.tocFile.String())
}
})
} }
func (procMacro *procMacroDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) { func (procMacro *procMacroDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
ctx.SubAndroidMk(ret, procMacro.baseCompiler) ctx.SubAndroidMk(ret, procMacro.baseCompiler)

View File

@@ -185,7 +185,7 @@ func rustEnvVars(ctx ModuleContext, deps PathDeps) []string {
} }
func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags, func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath, crate_type string) buildOutput { outputFile android.WritablePath, crateType string) buildOutput {
var inputs android.Paths var inputs android.Paths
var implicits android.Paths var implicits android.Paths
@@ -204,7 +204,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl
// Collect rustc flags // Collect rustc flags
rustcFlags = append(rustcFlags, flags.GlobalRustFlags...) rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
rustcFlags = append(rustcFlags, flags.RustFlags...) rustcFlags = append(rustcFlags, flags.RustFlags...)
rustcFlags = append(rustcFlags, "--crate-type="+crate_type) rustcFlags = append(rustcFlags, "--crate-type="+crateType)
if crateName != "" { if crateName != "" {
rustcFlags = append(rustcFlags, "--crate-name="+crateName) rustcFlags = append(rustcFlags, "--crate-name="+crateName)
} }

View File

@@ -102,6 +102,9 @@ type libraryDecorator struct {
sourceProvider SourceProvider sourceProvider SourceProvider
collectedSnapshotHeaders android.Paths collectedSnapshotHeaders android.Paths
// table-of-contents file for cdylib crates to optimize out relinking when possible
tocFile android.OptionalPath
} }
type libraryInterface interface { type libraryInterface interface {
@@ -137,12 +140,18 @@ type libraryInterface interface {
BuildOnlyDylib() BuildOnlyDylib()
BuildOnlyStatic() BuildOnlyStatic()
BuildOnlyShared() BuildOnlyShared()
toc() android.OptionalPath
} }
func (library *libraryDecorator) nativeCoverage() bool { func (library *libraryDecorator) nativeCoverage() bool {
return true return true
} }
func (library *libraryDecorator) toc() android.OptionalPath {
return library.tocFile
}
func (library *libraryDecorator) rlib() bool { func (library *libraryDecorator) rlib() bool {
return library.MutatedProperties.VariantIsRlib return library.MutatedProperties.VariantIsRlib
} }
@@ -519,9 +528,16 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
} }
if library.shared() { if library.shared() {
// Optimize out relinking against shared libraries whose interface hasn't changed by
// depending on a table of contents file instead of the library itself.
tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
library.tocFile = android.OptionalPathForPath(tocFile)
cc.TransformSharedObjectToToc(ctx, outputFile, tocFile)
ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{ ctx.SetProvider(cc.SharedLibraryInfoProvider, cc.SharedLibraryInfo{
SharedLibrary: outputFile, TableOfContents: android.OptionalPathForPath(tocFile),
Target: ctx.Target(), SharedLibrary: outputFile,
Target: ctx.Target(),
}) })
} }

View File

@@ -160,6 +160,26 @@ func TestSharedLibrary(t *testing.T) {
} }
} }
func TestSharedLibraryToc(t *testing.T) {
ctx := testRust(t, `
rust_ffi_shared {
name: "libfoo",
srcs: ["foo.rs"],
crate_name: "foo",
}
cc_binary {
name: "fizzbuzz",
shared_libs: ["libfoo"],
}`)
fizzbuzz := ctx.ModuleForTests("fizzbuzz", "android_arm64_armv8-a").Rule("ld")
if !android.SuffixInList(fizzbuzz.Implicits.Strings(), "libfoo.so.toc") {
t.Errorf("missing expected libfoo.so.toc implicit dependency, instead found: %#v",
fizzbuzz.Implicits.Strings())
}
}
func TestStaticLibraryLinkage(t *testing.T) { func TestStaticLibraryLinkage(t *testing.T) {
ctx := testRust(t, ` ctx := testRust(t, `
rust_ffi_static { rust_ffi_static {

View File

@@ -281,8 +281,8 @@ func (mod *Module) Object() bool {
func (mod *Module) Toc() android.OptionalPath { func (mod *Module) Toc() android.OptionalPath {
if mod.compiler != nil { if mod.compiler != nil {
if _, ok := mod.compiler.(libraryInterface); ok { if lib, ok := mod.compiler.(libraryInterface); ok {
return android.OptionalPath{} return lib.toc()
} }
} }
panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName())) panic(fmt.Errorf("Toc() called on non-library module: %q", mod.BaseModuleName()))