Merge "rust: Emit toc files for cdylibs" am: 925942127a
am: d1d040f36a
am: 08f5b6830f
am: 15737511a5
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1879645 Change-Id: Iee1d1d424271c1b5531a9221673d82725fa00141
This commit is contained in:
@@ -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() {
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
|
@@ -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()
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
|
@@ -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(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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()))
|
||||||
|
Reference in New Issue
Block a user