Link device binaries dynamically by default.
Device binaries currently are linked statically by default. Instead we should be linking these dynamic by default. To avoid conflicts when manually specifying rlib dependencies on modules, we always link libstd dynamically for all device modules except static libraries. This removes the "prefer_dynamic" property entirely to avoid confusion. Bug: 165161105 Test: m profcollectd is built dynamically. Test: cd external/rust/; mma Test: cd external/crosvm/; mma Change-Id: I25ac897040acbcc2d97c791a33e8e01610632272
This commit is contained in:
parent
f5a2b8a641
commit
042504f7d6
|
@ -24,9 +24,6 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BinaryCompilerProperties struct {
|
type BinaryCompilerProperties struct {
|
||||||
// passes -C prefer-dynamic to rustc, which tells it to dynamically link the stdlib
|
|
||||||
// (assuming it has no dylib dependencies already)
|
|
||||||
Prefer_dynamic *bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type binaryDecorator struct {
|
type binaryDecorator struct {
|
||||||
|
@ -60,10 +57,6 @@ func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator
|
||||||
return module, binary
|
return module, binary
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryDecorator) preferDynamic() bool {
|
|
||||||
return Bool(binary.Properties.Prefer_dynamic)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
flags = binary.baseCompiler.compilerFlags(ctx, flags)
|
flags = binary.baseCompiler.compilerFlags(ctx, flags)
|
||||||
|
|
||||||
|
@ -76,9 +69,6 @@ func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Fla
|
||||||
"-Wl,--no-undefined-version")
|
"-Wl,--no-undefined-version")
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary.preferDynamic() {
|
|
||||||
flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
|
|
||||||
}
|
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +122,9 @@ func (binary *binaryDecorator) coverageOutputZipPath() android.OptionalPath {
|
||||||
return binary.coverageOutputZipFile
|
return binary.coverageOutputZipFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func (binary *binaryDecorator) autoDep() autoDep {
|
func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||||
if binary.preferDynamic() {
|
// Binaries default to dylib dependencies for device, rlib for host.
|
||||||
|
if ctx.Device() {
|
||||||
return dylibAutoDep
|
return dylibAutoDep
|
||||||
} else {
|
} else {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
|
|
|
@ -17,44 +17,64 @@ package rust
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test that the prefer_dynamic property is handled correctly.
|
// Test that rustlibs default linkage is correct for binaries.
|
||||||
func TestPreferDynamicBinary(t *testing.T) {
|
func TestBinaryLinkage(t *testing.T) {
|
||||||
|
ctx := testRust(t, `
|
||||||
|
rust_binary {
|
||||||
|
name: "fizz-buzz",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
rustlibs: ["libfoo"],
|
||||||
|
host_supported: true,
|
||||||
|
}
|
||||||
|
rust_library {
|
||||||
|
name: "libfoo",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
crate_name: "foo",
|
||||||
|
host_supported: true,
|
||||||
|
}`)
|
||||||
|
|
||||||
|
fizzBuzzHost := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
|
||||||
|
fizzBuzzDevice := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Module().(*Module)
|
||||||
|
|
||||||
|
if !android.InList("libfoo", fizzBuzzHost.Properties.AndroidMkRlibs) {
|
||||||
|
t.Errorf("rustlibs dependency libfoo should be an rlib dep for host modules")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !android.InList("libfoo", fizzBuzzDevice.Properties.AndroidMkDylibs) {
|
||||||
|
t.Errorf("rustlibs dependency libfoo should be an dylib dep for device modules")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the path returned by HostToolPath is correct
|
||||||
|
func TestHostToolPath(t *testing.T) {
|
||||||
ctx := testRust(t, `
|
ctx := testRust(t, `
|
||||||
rust_binary_host {
|
rust_binary_host {
|
||||||
name: "fizz-buzz-dynamic",
|
name: "fizz-buzz",
|
||||||
srcs: ["foo.rs"],
|
srcs: ["foo.rs"],
|
||||||
prefer_dynamic: true,
|
}`)
|
||||||
}
|
|
||||||
|
|
||||||
|
path := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module).HostToolPath()
|
||||||
|
if g, w := path.String(), "/host/linux-x86/bin/fizz-buzz"; !strings.Contains(g, w) {
|
||||||
|
t.Errorf("wrong host tool path, expected %q got %q", w, g)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that the flags being passed to rust_binary modules are as expected
|
||||||
|
func TestBinaryFlags(t *testing.T) {
|
||||||
|
ctx := testRust(t, `
|
||||||
rust_binary_host {
|
rust_binary_host {
|
||||||
name: "fizz-buzz",
|
name: "fizz-buzz",
|
||||||
srcs: ["foo.rs"],
|
srcs: ["foo.rs"],
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Output("fizz-buzz")
|
fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Output("fizz-buzz")
|
||||||
fizzBuzzDynamic := ctx.ModuleForTests("fizz-buzz-dynamic", "linux_glibc_x86_64").Output("fizz-buzz-dynamic")
|
|
||||||
|
|
||||||
path := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module).HostToolPath()
|
flags := fizzBuzz.Args["rustcFlags"]
|
||||||
if g, w := path.String(), "/host/linux-x86/bin/fizz-buzz"; !strings.Contains(g, w) {
|
|
||||||
t.Errorf("wrong host tool path, expected %q got %q", w, g)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not compile binary modules with the --test flag.
|
|
||||||
flags := fizzBuzzDynamic.Args["rustcFlags"]
|
|
||||||
if strings.Contains(flags, "--test") {
|
if strings.Contains(flags, "--test") {
|
||||||
t.Errorf("extra --test flag, rustcFlags: %#v", flags)
|
t.Errorf("extra --test flag, rustcFlags: %#v", flags)
|
||||||
}
|
}
|
||||||
if !strings.Contains(flags, "prefer-dynamic") {
|
|
||||||
t.Errorf("missing prefer-dynamic flag, rustcFlags: %#v", flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = fizzBuzz.Args["rustcFlags"]
|
|
||||||
if strings.Contains(flags, "--test") {
|
|
||||||
t.Errorf("extra --test flag, rustcFlags: %#v", flags)
|
|
||||||
}
|
|
||||||
if strings.Contains(flags, "prefer-dynamic") {
|
|
||||||
t.Errorf("unexpected prefer-dynamic flag, rustcFlags: %#v", flags)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,10 @@ func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
|
||||||
panic("baseCompiler does not implement coverageOutputZipPath()")
|
panic("baseCompiler does not implement coverageOutputZipPath()")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (compiler *baseCompiler) static() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var _ compiler = (*baseCompiler)(nil)
|
var _ compiler = (*baseCompiler)(nil)
|
||||||
|
|
||||||
func (compiler *baseCompiler) inData() bool {
|
func (compiler *baseCompiler) inData() bool {
|
||||||
|
@ -216,7 +220,15 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
|
||||||
stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
|
stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
|
||||||
}
|
}
|
||||||
|
|
||||||
deps.Rustlibs = append(deps.Rustlibs, stdlib)
|
// For devices, we always link stdlibs in as dylibs except for ffi static libraries.
|
||||||
|
// (rustc does not support linking libstd as a dylib for ffi static libraries)
|
||||||
|
if ctx.Host() {
|
||||||
|
deps.Rustlibs = append(deps.Rustlibs, stdlib)
|
||||||
|
} else if ctx.RustModule().compiler.static() {
|
||||||
|
deps.Rlibs = append(deps.Rlibs, stdlib)
|
||||||
|
} else {
|
||||||
|
deps.Dylibs = append(deps.Dylibs, stdlib)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return deps
|
return deps
|
||||||
|
|
|
@ -177,3 +177,30 @@ func TestLints(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that devices are linking the stdlib dynamically
|
||||||
|
func TestStdDeviceLinkage(t *testing.T) {
|
||||||
|
ctx := testRust(t, `
|
||||||
|
rust_binary {
|
||||||
|
name: "fizz",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
}
|
||||||
|
rust_library {
|
||||||
|
name: "libfoo",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
crate_name: "foo",
|
||||||
|
}`)
|
||||||
|
fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
|
||||||
|
fooRlib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib").Module().(*Module)
|
||||||
|
fooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
|
||||||
|
|
||||||
|
if !android.InList("libstd", fizz.Properties.AndroidMkDylibs) {
|
||||||
|
t.Errorf("libstd is not linked dynamically for device binaries")
|
||||||
|
}
|
||||||
|
if !android.InList("libstd", fooRlib.Properties.AndroidMkDylibs) {
|
||||||
|
t.Errorf("libstd is not linked dynamically for rlibs")
|
||||||
|
}
|
||||||
|
if !android.InList("libstd", fooDylib.Properties.AndroidMkDylibs) {
|
||||||
|
t.Errorf("libstd is not linked dynamically for dylibs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -176,13 +176,13 @@ func (library *libraryDecorator) setStatic() {
|
||||||
library.MutatedProperties.VariantIsDylib = false
|
library.MutatedProperties.VariantIsDylib = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (library *libraryDecorator) autoDep() autoDep {
|
func (library *libraryDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||||
if library.rlib() || library.static() {
|
if library.rlib() || library.static() {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
} else if library.dylib() || library.shared() {
|
} else if library.dylib() || library.shared() {
|
||||||
return dylibAutoDep
|
return dylibAutoDep
|
||||||
} else {
|
} else {
|
||||||
return rlibAutoDep
|
panic("autoDep called on library" + ctx.ModuleName() + "that has no enabled variants.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,22 @@ func TestSharedLibrary(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStaticLibraryLinkage(t *testing.T) {
|
||||||
|
ctx := testRust(t, `
|
||||||
|
rust_ffi_static {
|
||||||
|
name: "libfoo",
|
||||||
|
srcs: ["foo.rs"],
|
||||||
|
crate_name: "foo",
|
||||||
|
}`)
|
||||||
|
|
||||||
|
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
|
||||||
|
|
||||||
|
if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) {
|
||||||
|
t.Errorf("Static libstd rlib expected to be a dependency of Rust static libraries. Rlib deps are: %#v",
|
||||||
|
libfoo.Module().(*Module).Properties.AndroidMkDylibs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test that variants pull in the right type of rustlib autodep
|
// Test that variants pull in the right type of rustlib autodep
|
||||||
func TestAutoDeps(t *testing.T) {
|
func TestAutoDeps(t *testing.T) {
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,6 @@ func (procMacro *procMacroDecorator) getStem(ctx ModuleContext) string {
|
||||||
return stem + String(procMacro.baseCompiler.Properties.Suffix)
|
return stem + String(procMacro.baseCompiler.Properties.Suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (procMacro *procMacroDecorator) autoDep() autoDep {
|
func (procMacro *procMacroDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,6 +289,8 @@ type compiler interface {
|
||||||
|
|
||||||
Disabled() bool
|
Disabled() bool
|
||||||
SetDisabled()
|
SetDisabled()
|
||||||
|
|
||||||
|
static() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type exportedFlagsProducer interface {
|
type exportedFlagsProducer interface {
|
||||||
|
@ -740,7 +742,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type autoDeppable interface {
|
type autoDeppable interface {
|
||||||
autoDep() autoDep
|
autoDep(ctx BaseModuleContext) autoDep
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) begin(ctx BaseModuleContext) {
|
func (mod *Module) begin(ctx BaseModuleContext) {
|
||||||
|
@ -988,8 +990,8 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||||
{Mutator: "rust_libraries", Variation: "dylib"}}...),
|
{Mutator: "rust_libraries", Variation: "dylib"}}...),
|
||||||
dylibDepTag, deps.Dylibs...)
|
dylibDepTag, deps.Dylibs...)
|
||||||
|
|
||||||
if deps.Rustlibs != nil {
|
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
|
||||||
autoDep := mod.compiler.(autoDeppable).autoDep()
|
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
|
||||||
actx.AddVariationDependencies(
|
actx.AddVariationDependencies(
|
||||||
append(commonDepVariations, []blueprint.Variation{
|
append(commonDepVariations, []blueprint.Variation{
|
||||||
{Mutator: "rust_libraries", Variation: autoDep.variation}}...),
|
{Mutator: "rust_libraries", Variation: autoDep.variation}}...),
|
||||||
|
|
|
@ -114,7 +114,7 @@ func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (test *testDecorator) autoDep() autoDep {
|
func (test *testDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||||
return rlibAutoDep
|
return rlibAutoDep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue