Build Rust Device Sysroots in Soong
In order to ensure we are using current platform Bionic for any platform
Rust binaries, we need to build the sysroot in Soong. This will also
enable us too hook the "test" crate if necessary.
While both a dynamic and static sysroot are available, on device only a
dynamic sysroot will be injected. On host, we continue using the sysroot
used to build the compiler as before.
Bug: 139486496
Change-Id: I127377e5b056610ceb5015a34d266250320fbc31
diff --git a/rust/binary.go b/rust/binary.go
index 52f840e..3f43da0 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -16,7 +16,6 @@
import (
"android/soong/android"
- "android/soong/rust/config"
)
func init() {
@@ -89,12 +88,6 @@
func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
deps = binary.baseCompiler.compilerDeps(ctx, deps)
- if binary.preferDynamic() || len(deps.Dylibs) > 0 {
- for _, stdlib := range config.Stdlibs {
- deps.Dylibs = append(deps.Dylibs, stdlib+"_"+ctx.toolchain().RustTriple())
- }
- }
-
if ctx.toolchain().Bionic() {
deps = binary.baseCompiler.bionicDeps(ctx, deps)
deps.CrtBegin = "crtbegin_dynamic"
diff --git a/rust/builder.go b/rust/builder.go
index 2a7643d..d46f34a 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -93,6 +93,12 @@
rustcFlags = append(rustcFlags, "--target="+targetTriple)
linkFlags = append(linkFlags, "-target "+targetTriple)
}
+ // TODO once we have static libraries in the host prebuilt .bp, this
+ // should be unconditionally added.
+ if !ctx.Host() {
+ // If we're on a device build, do not use an implicit sysroot
+ rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
+ }
// Collect linker flags
linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
linkFlags = append(linkFlags, flags.LinkFlags...)
diff --git a/rust/compiler.go b/rust/compiler.go
index 3f02835..f6e952a 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -31,6 +31,10 @@
return BoolDefault(compiler.Properties.Deny_warnings, config.DefaultDenyWarnings)
}
+func (compiler *baseCompiler) setNoStdlibs() {
+ compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
+}
+
func NewBaseCompiler(dir, dir64 string) *baseCompiler {
return &baseCompiler{
Properties: BaseCompilerProperties{},
@@ -81,6 +85,9 @@
// install to a subdirectory of the default install path for the module
Relative_install_path *string `android:"arch_variant"`
+
+ // whether to suppress inclusion of standard crates - defaults to false
+ No_stdlibs *bool
}
type baseCompiler struct {
@@ -160,6 +167,23 @@
deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
+ if !Bool(compiler.Properties.No_stdlibs) {
+ for _, stdlib := range config.Stdlibs {
+ // If we're building for host, use the compiler's stdlibs
+ if ctx.Host() {
+ stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
+ }
+
+ // This check is technically insufficient - on the host, where
+ // static linking is the default, if one of our static
+ // dependencies uses a dynamic library, we need to dynamically
+ // link the stdlib as well.
+ if (len(deps.Dylibs) > 0) || (!ctx.Host()) {
+ // Dynamically linked stdlib
+ deps.Dylibs = append(deps.Dylibs, stdlib)
+ }
+ }
+ }
return deps
}
diff --git a/rust/config/whitelist.go b/rust/config/whitelist.go
index 8025bcf..1a7b81f 100644
--- a/rust/config/whitelist.go
+++ b/rust/config/whitelist.go
@@ -5,6 +5,7 @@
"external/rust",
"external/crosvm",
"external/adhd",
+ "prebuilts/rust",
}
RustModuleTypes = []string{
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index fa69fbb..45bef9e 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -42,6 +42,7 @@
func NewPrebuiltDylib(hod android.HostOrDeviceSupported) (*Module, *prebuiltLibraryDecorator) {
module, library := NewRustLibrary(hod)
library.BuildOnlyDylib()
+ library.setNoStdlibs()
library.setDylib()
prebuilt := &prebuiltLibraryDecorator{
libraryDecorator: library,
diff --git a/rust/rust_test.go b/rust/rust_test.go
index eb04e72..bbd9111 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -209,6 +209,25 @@
name: "libbar",
srcs: ["foo.rs"],
}
+ // Make a dummy libstd to let resolution go through
+ rust_library_dylib {
+ name: "libstd",
+ crate_name: "std",
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ }
+ rust_library_dylib {
+ name: "libterm",
+ crate_name: "term",
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ }
+ rust_library_dylib {
+ name: "libtest",
+ crate_name: "test",
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ }
rust_proc_macro {
name: "libpm",
rlibs: ["libbar"],
@@ -226,3 +245,18 @@
t.Errorf("Proc_macro is not using host variant of dependent modules.")
}
}
+
+// Test that no_stdlibs suppresses dependencies on rust standard libraries
+func TestNoStdlibs(t *testing.T) {
+ ctx := testRust(t, `
+ rust_binary {
+ name: "fizz-buzz",
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ }`)
+ module := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a_core").Module().(*Module)
+
+ if android.InList("libstd", module.Properties.AndroidMkDylibs) {
+ t.Errorf("no_stdlibs did not suppress dependency on libstd")
+ }
+}