Merge "rust: Emit toc files for cdylibs" am: 925942127a am: d1d040f36a am: 08f5b6830f

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1879645

Change-Id: I701bb9ff19c78f2358049813e5e68a606b82b82a
This commit is contained in:
Ivan Lozano
2021-11-05 13:49:09 +00:00
committed by Automerger Merge Worker
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)
func transformSharedObjectToToc(ctx android.ModuleContext, inputFile android.Path,
outputFile android.WritablePath, flags builderFlags) {
func TransformSharedObjectToToc(ctx android.ModuleContext, inputFile android.Path, outputFile android.WritablePath) {
var format string
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.
tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.ShlibSuffix()[1:]+".toc")
library.tocFile = android.OptionalPathForPath(tocFile)
transformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags)
TransformSharedObjectToToc(ctx, outputFile, tocFile)
stripFlags := flagsToStripFlags(flags)
needsStrip := library.stripper.NeedsStrip(ctx)

View File

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

View File

@@ -144,7 +144,6 @@ func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
// current VNDK prebuilts are only shared libs.
in := p.singleSourcePath(ctx)
builderFlags := flagsToBuilderFlags(flags)
p.unstrippedOutputFile = in
libName := in.Base()
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.
tocFile := android.PathForModuleOut(ctx, libName+".toc")
p.tocFile = android.OptionalPathForPath(tocFile)
transformSharedObjectToToc(ctx, in, tocFile, builderFlags)
TransformSharedObjectToToc(ctx, in, tocFile)
p.androidMkSuffix = p.NameSuffix()

View File

@@ -137,12 +137,16 @@ func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.An
} else if library.shared() {
ret.Class = "SHARED_LIBRARIES"
}
if library.distFile.Valid() {
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) {
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,
outputFile android.WritablePath, crate_type string) buildOutput {
outputFile android.WritablePath, crateType string) buildOutput {
var inputs android.Paths
var implicits android.Paths
@@ -204,7 +204,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl
// Collect rustc flags
rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
rustcFlags = append(rustcFlags, flags.RustFlags...)
rustcFlags = append(rustcFlags, "--crate-type="+crate_type)
rustcFlags = append(rustcFlags, "--crate-type="+crateType)
if crateName != "" {
rustcFlags = append(rustcFlags, "--crate-name="+crateName)
}

View File

@@ -102,6 +102,9 @@ type libraryDecorator struct {
sourceProvider SourceProvider
collectedSnapshotHeaders android.Paths
// table-of-contents file for cdylib crates to optimize out relinking when possible
tocFile android.OptionalPath
}
type libraryInterface interface {
@@ -137,12 +140,18 @@ type libraryInterface interface {
BuildOnlyDylib()
BuildOnlyStatic()
BuildOnlyShared()
toc() android.OptionalPath
}
func (library *libraryDecorator) nativeCoverage() bool {
return true
}
func (library *libraryDecorator) toc() android.OptionalPath {
return library.tocFile
}
func (library *libraryDecorator) rlib() bool {
return library.MutatedProperties.VariantIsRlib
}
@@ -519,9 +528,16 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
}
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{
SharedLibrary: outputFile,
Target: ctx.Target(),
TableOfContents: android.OptionalPathForPath(tocFile),
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) {
ctx := testRust(t, `
rust_ffi_static {

View File

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