Merge "Link device binaries dynamically by default." am: 4d947f0ea8
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1403871 Change-Id: Ic617ce674f03c9cacaba90519694b437f66e1626
This commit is contained in:
commit
8ee04afe36
|
@ -24,9 +24,6 @@ func init() {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -60,10 +57,6 @@ func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator
|
|||
return module, binary
|
||||
}
|
||||
|
||||
func (binary *binaryDecorator) preferDynamic() bool {
|
||||
return Bool(binary.Properties.Prefer_dynamic)
|
||||
}
|
||||
|
||||
func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||
flags = binary.baseCompiler.compilerFlags(ctx, flags)
|
||||
|
||||
|
@ -76,9 +69,6 @@ func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Fla
|
|||
"-Wl,--no-undefined-version")
|
||||
}
|
||||
|
||||
if binary.preferDynamic() {
|
||||
flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
|
@ -132,8 +122,9 @@ func (binary *binaryDecorator) coverageOutputZipPath() android.OptionalPath {
|
|||
return binary.coverageOutputZipFile
|
||||
}
|
||||
|
||||
func (binary *binaryDecorator) autoDep() autoDep {
|
||||
if binary.preferDynamic() {
|
||||
func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||
// Binaries default to dylib dependencies for device, rlib for host.
|
||||
if ctx.Device() {
|
||||
return dylibAutoDep
|
||||
} else {
|
||||
return rlibAutoDep
|
||||
|
|
|
@ -17,44 +17,64 @@ package rust
|
|||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
// Test that the prefer_dynamic property is handled correctly.
|
||||
func TestPreferDynamicBinary(t *testing.T) {
|
||||
// Test that rustlibs default linkage is correct for binaries.
|
||||
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, `
|
||||
rust_binary_host {
|
||||
name: "fizz-buzz-dynamic",
|
||||
name: "fizz-buzz",
|
||||
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 {
|
||||
name: "fizz-buzz",
|
||||
srcs: ["foo.rs"],
|
||||
}`)
|
||||
|
||||
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()
|
||||
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"]
|
||||
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("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()")
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) static() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var _ compiler = (*baseCompiler)(nil)
|
||||
|
||||
func (compiler *baseCompiler) inData() bool {
|
||||
|
@ -216,7 +220,15 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
|
|||
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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
func (library *libraryDecorator) autoDep() autoDep {
|
||||
func (library *libraryDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||
if library.rlib() || library.static() {
|
||||
return rlibAutoDep
|
||||
} else if library.dylib() || library.shared() {
|
||||
return dylibAutoDep
|
||||
} 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
|
||||
func TestAutoDeps(t *testing.T) {
|
||||
|
||||
|
|
|
@ -80,6 +80,6 @@ func (procMacro *procMacroDecorator) getStem(ctx ModuleContext) string {
|
|||
return stem + String(procMacro.baseCompiler.Properties.Suffix)
|
||||
}
|
||||
|
||||
func (procMacro *procMacroDecorator) autoDep() autoDep {
|
||||
func (procMacro *procMacroDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||
return rlibAutoDep
|
||||
}
|
||||
|
|
|
@ -289,6 +289,8 @@ type compiler interface {
|
|||
|
||||
Disabled() bool
|
||||
SetDisabled()
|
||||
|
||||
static() bool
|
||||
}
|
||||
|
||||
type exportedFlagsProducer interface {
|
||||
|
@ -740,7 +742,7 @@ var (
|
|||
)
|
||||
|
||||
type autoDeppable interface {
|
||||
autoDep() autoDep
|
||||
autoDep(ctx BaseModuleContext) autoDep
|
||||
}
|
||||
|
||||
func (mod *Module) begin(ctx BaseModuleContext) {
|
||||
|
@ -988,8 +990,8 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||
{Mutator: "rust_libraries", Variation: "dylib"}}...),
|
||||
dylibDepTag, deps.Dylibs...)
|
||||
|
||||
if deps.Rustlibs != nil {
|
||||
autoDep := mod.compiler.(autoDeppable).autoDep()
|
||||
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
|
||||
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
|
||||
actx.AddVariationDependencies(
|
||||
append(commonDepVariations, []blueprint.Variation{
|
||||
{Mutator: "rust_libraries", Variation: autoDep.variation}}...),
|
||||
|
|
|
@ -114,7 +114,7 @@ func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
|||
return flags
|
||||
}
|
||||
|
||||
func (test *testDecorator) autoDep() autoDep {
|
||||
func (test *testDecorator) autoDep(ctx BaseModuleContext) autoDep {
|
||||
return rlibAutoDep
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue