Merge "[rust] Pass cc dependencies as linker flags." am: b0e99edab1

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

Change-Id: If88108a6ae5959ea57833f163f8d0c460a343d23
This commit is contained in:
Ivan Lozano 2020-08-27 21:53:11 +00:00 committed by Automerger Merge Worker
commit 61b6656332
5 changed files with 54 additions and 50 deletions

View File

@ -102,6 +102,7 @@ func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps Path
binary.unstrippedOutputFile = outputFile binary.unstrippedOutputFile = outputFile
flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
outputs := TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs) outputs := TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
binary.coverageFile = outputs.coverageFile binary.coverageFile = outputs.coverageFile

View File

@ -78,3 +78,21 @@ func TestBinaryFlags(t *testing.T) {
t.Errorf("extra --test flag, rustcFlags: %#v", flags) t.Errorf("extra --test flag, rustcFlags: %#v", flags)
} }
} }
func TestLinkObjects(t *testing.T) {
ctx := testRust(t, `
rust_binary {
name: "fizz-buzz",
srcs: ["foo.rs"],
shared_libs: ["libfoo"],
}
cc_library {
name: "libfoo",
}`)
fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Output("fizz-buzz")
linkFlags := fizzBuzz.Args["linkFlags"]
if !strings.Contains(linkFlags, "/libfoo.so") {
t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
}
}

View File

@ -381,6 +381,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
} }
flags.RustFlags = append(flags.RustFlags, deps.depFlags...) flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if library.dylib() { if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See: // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
@ -427,6 +428,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
if library.rlib() || library.dylib() { if library.rlib() || library.dylib() {
library.exportLinkDirs(deps.linkDirs...) library.exportLinkDirs(deps.linkDirs...)
library.exportDepFlags(deps.depFlags...) library.exportDepFlags(deps.depFlags...)
library.exportLinkObjects(deps.linkObjects...)
} }
library.unstrippedOutputFile = outputFile library.unstrippedOutputFile = outputFile

View File

@ -244,13 +244,14 @@ type Deps struct {
} }
type PathDeps struct { type PathDeps struct {
DyLibs RustLibraries DyLibs RustLibraries
RLibs RustLibraries RLibs RustLibraries
SharedLibs android.Paths SharedLibs android.Paths
StaticLibs android.Paths StaticLibs android.Paths
ProcMacros RustLibraries ProcMacros RustLibraries
linkDirs []string linkDirs []string
depFlags []string depFlags []string
linkObjects []string
//ReexportedDeps android.Paths //ReexportedDeps android.Paths
// Used by bindgen modules which call clang // Used by bindgen modules which call clang
@ -296,13 +297,16 @@ type compiler interface {
type exportedFlagsProducer interface { type exportedFlagsProducer interface {
exportedLinkDirs() []string exportedLinkDirs() []string
exportedDepFlags() []string exportedDepFlags() []string
exportedLinkObjects() []string
exportLinkDirs(...string) exportLinkDirs(...string)
exportDepFlags(...string) exportDepFlags(...string)
exportLinkObjects(...string)
} }
type flagExporter struct { type flagExporter struct {
depFlags []string depFlags []string
linkDirs []string linkDirs []string
linkObjects []string
} }
func (flagExporter *flagExporter) exportedLinkDirs() []string { func (flagExporter *flagExporter) exportedLinkDirs() []string {
@ -313,6 +317,10 @@ func (flagExporter *flagExporter) exportedDepFlags() []string {
return flagExporter.depFlags return flagExporter.depFlags
} }
func (flagExporter *flagExporter) exportedLinkObjects() []string {
return flagExporter.linkObjects
}
func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) { func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...)) flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
} }
@ -321,12 +329,17 @@ func (flagExporter *flagExporter) exportDepFlags(flags ...string) {
flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...)) flagExporter.depFlags = android.FirstUniqueStrings(append(flagExporter.depFlags, flags...))
} }
func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
}
var _ exportedFlagsProducer = (*flagExporter)(nil) var _ exportedFlagsProducer = (*flagExporter)(nil)
func NewFlagExporter() *flagExporter { func NewFlagExporter() *flagExporter {
return &flagExporter{ return &flagExporter{
depFlags: []string{}, depFlags: []string{},
linkDirs: []string{}, linkDirs: []string{},
linkObjects: []string{},
} }
} }
@ -813,6 +826,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok && depTag != procMacroDepTag { if lib, ok := rustDep.compiler.(exportedFlagsProducer); ok && depTag != procMacroDepTag {
depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...) depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedLinkDirs()...)
depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...) depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...)
depPaths.linkObjects = append(depPaths.linkObjects, lib.exportedLinkObjects()...)
} }
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag { if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
@ -840,21 +854,18 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
return return
} }
} }
linkFile := ccDep.OutputFile() linkObject := ccDep.OutputFile()
linkPath := linkPathFromFilePath(linkFile.Path()) linkPath := linkPathFromFilePath(linkObject.Path())
libName := libNameFromFilePath(linkFile.Path())
depFlag := "-l" + libName
if !linkFile.Valid() { if !linkObject.Valid() {
ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName()) ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
} }
exportDep := false exportDep := false
switch { switch {
case cc.IsStaticDepTag(depTag): case cc.IsStaticDepTag(depTag):
depFlag = "-lstatic=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, depFlag) depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...) depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
if mod, ok := ccDep.(*cc.Module); ok { if mod, ok := ccDep.(*cc.Module); ok {
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
@ -864,9 +875,8 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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.IsSharedDepTag(depTag): case cc.IsSharedDepTag(depTag):
depFlag = "-ldylib=" + libName
depPaths.linkDirs = append(depPaths.linkDirs, linkPath) depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.depFlags = append(depPaths.depFlags, depFlag) depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...) depPaths.depIncludePaths = append(depPaths.depIncludePaths, ccDep.IncludeDirs()...)
if mod, ok := ccDep.(*cc.Module); ok { if mod, ok := ccDep.(*cc.Module); ok {
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...) depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, mod.ExportedSystemIncludeDirs()...)
@ -876,15 +886,15 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName) mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true exportDep = true
case depTag == cc.CrtBeginDepTag: case depTag == cc.CrtBeginDepTag:
depPaths.CrtBegin = linkFile depPaths.CrtBegin = linkObject
case depTag == cc.CrtEndDepTag: case depTag == cc.CrtEndDepTag:
depPaths.CrtEnd = linkFile depPaths.CrtEnd = linkObject
} }
// Make sure these dependencies are propagated // Make sure these dependencies are propagated
if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep { if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
lib.exportLinkDirs(linkPath) lib.exportLinkDirs(linkPath)
lib.exportDepFlags(depFlag) lib.exportLinkObjects(linkObject.String())
} }
} }
@ -958,14 +968,6 @@ func linkPathFromFilePath(filepath android.Path) string {
return strings.Split(filepath.String(), filepath.Base())[0] return strings.Split(filepath.String(), filepath.Base())[0]
} }
func libNameFromFilePath(filepath android.Path) string {
libName := strings.TrimSuffix(filepath.Base(), filepath.Ext())
if strings.HasPrefix(libName, "lib") {
libName = libName[3:]
}
return libName
}
func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) { func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
ctx := &depsContext{ ctx := &depsContext{
BottomUpMutatorContext: actx, BottomUpMutatorContext: actx,

View File

@ -132,25 +132,6 @@ func testRustError(t *testing.T, pattern string, bp string) {
t.Fatalf("missing expected error %q (0 errors are returned)", pattern) t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
} }
// Test that we can extract the lib name from a lib path.
func TestLibNameFromFilePath(t *testing.T) {
libBarPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so.so")
libLibPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/liblib.dylib.so")
libBarName := libNameFromFilePath(libBarPath)
libLibName := libNameFromFilePath(libLibPath)
expectedResult := "bar.so"
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)
}
}
// Test that we can extract the link path from a lib path. // Test that we can extract the link path from a lib path.
func TestLinkPathFromFilePath(t *testing.T) { func TestLinkPathFromFilePath(t *testing.T) {
barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so") barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")