Move prefer_rlib from binary to base compiler.

Moves the prefer_rlib property out from being exclusively a binary
property to one thats part of the base compiler properties. This
provides a little more control over the libstd linkage in our libraries.
Specifically, this enables a usecase where rust_ffi_shared needs to link
against libstd statically rather than dynamically.

Bug: 175121262
Test: New Soong tests pass.
Change-Id: If68014c684a75ba70e9d7dacbb01c7d360dc25a1
diff --git a/rust/compiler.go b/rust/compiler.go
index 8d2f09c..4312452 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -122,6 +122,17 @@
 
 	// whether to suppress inclusion of standard crates - defaults to false
 	No_stdlibs *bool
+
+	// 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.
+	//
+	// This is primarily meant for rust_binary and rust_ffi modules where the default
+	// linkage of libstd might need to be overridden in some use cases. This should
+	// generally be avoided with other module types since it may cause collisions at
+	// linkage if all dependencies of the root binary module do not link against libstd\
+	// the same way.
+	Prefer_rlib *bool `android:"arch_variant"`
 }
 
 type baseCompiler struct {
@@ -154,9 +165,15 @@
 	panic("baseCompiler does not implement coverageOutputZipPath()")
 }
 
+func (compiler *baseCompiler) preferRlib() bool {
+	return Bool(compiler.Properties.Prefer_rlib)
+}
+
 func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
 	// For devices, we always link stdlibs in as dylibs by default.
-	if ctx.Device() {
+	if compiler.preferRlib() {
+		return RlibLinkage
+	} else if ctx.Device() {
 		return DylibLinkage
 	} else {
 		return RlibLinkage