From 11200870b0cd84e9bbccb89b66cf59b5ed4db526 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Mon, 28 Sep 2020 11:56:30 -0400 Subject: [PATCH] rust: Add prefer_rlib property for static libstd. Adds the prefer_rlib property to allow linking libstd statically for device rust binaries. This also changes the default behavior of rustlibs to also prefer rlib linkage. This is because dylibs do not provide rlib-libstd variants and always link in libstd dynamically. Thus a binary requesting libstd rlib linkage should not attempt to link against dylibs that link libstd dynamically. Bug: 168729404 Test: New Soong test passes. Change-Id: Idf8dfbbce8fd936f55a3fb323b17a1a7f0ee954e --- rust/binary.go | 11 +++++++++++ rust/binary_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) 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, `