diff --git a/rust/binary.go b/rust/binary.go index 1d02453db..e95cb3afc 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -24,6 +24,10 @@ func init() { } type BinaryCompilerProperties struct { + // Change the rustlibs linkage to select rlib linkage by default for device targets. + // Also link libstd as an rlib as well on device targets. + // Note: This is the default behavior for host targets. + Prefer_rlib *bool `android:"arch_variant"` } type binaryDecorator struct { @@ -131,9 +135,16 @@ func (binary *binaryDecorator) coverageOutputZipPath() android.OptionalPath { func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep { // Binaries default to dylib dependencies for device, rlib for host. + if Bool(binary.Properties.Prefer_rlib) { + return rlibAutoDep + } if ctx.Device() { return dylibAutoDep } else { return rlibAutoDep } } + +func (binary *binaryDecorator) staticStd(ctx *depsContext) bool { + return binary.baseCompiler.staticStd(ctx) || Bool(binary.Properties.Prefer_rlib) +} diff --git a/rust/binary_test.go b/rust/binary_test.go index 394abfcdd..f31a7fcda 100644 --- a/rust/binary_test.go +++ b/rust/binary_test.go @@ -30,6 +30,13 @@ func TestBinaryLinkage(t *testing.T) { rustlibs: ["libfoo"], host_supported: true, } + rust_binary { + name: "rlib_linked", + srcs: ["foo.rs"], + rustlibs: ["libfoo"], + host_supported: true, + prefer_rlib: true, + } rust_library { name: "libfoo", srcs: ["foo.rs"], @@ -49,6 +56,34 @@ func TestBinaryLinkage(t *testing.T) { } } +// Test that prefer_rlib links in libstd statically as well as rustlibs. +func TestBinaryPreferRlib(t *testing.T) { + ctx := testRust(t, ` + rust_binary { + name: "rlib_linked", + srcs: ["foo.rs"], + rustlibs: ["libfoo"], + host_supported: true, + prefer_rlib: true, + } + rust_library { + name: "libfoo", + srcs: ["foo.rs"], + crate_name: "foo", + host_supported: true, + }`) + + mod := ctx.ModuleForTests("rlib_linked", "android_arm64_armv8-a").Module().(*Module) + + if !android.InList("libfoo.rlib-std", mod.Properties.AndroidMkRlibs) { + t.Errorf("rustlibs dependency libfoo should be an rlib dep when prefer_rlib is defined") + } + + if !android.InList("libstd", mod.Properties.AndroidMkRlibs) { + t.Errorf("libstd dependency should be an rlib dep when prefer_rlib is defined") + } +} + // Test that the path returned by HostToolPath is correct func TestHostToolPath(t *testing.T) { ctx := testRust(t, `