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
This commit is contained in:
Matthew Maurer
2019-10-31 10:44:40 -07:00
parent 940ef19f77
commit 99020b04fb
6 changed files with 66 additions and 7 deletions

View File

@@ -16,7 +16,6 @@ package rust
import (
"android/soong/android"
"android/soong/rust/config"
)
func init() {
@@ -89,12 +88,6 @@ func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Fla
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"

View File

@@ -93,6 +93,12 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path,
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...)

View File

@@ -31,6 +31,10 @@ func getDenyWarnings(compiler *baseCompiler) bool {
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 @@ type BaseCompilerProperties struct {
// 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 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
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
}

View File

@@ -5,6 +5,7 @@ var (
"external/rust",
"external/crosvm",
"external/adhd",
"prebuilts/rust",
}
RustModuleTypes = []string{

View File

@@ -42,6 +42,7 @@ func PrebuiltDylibFactory() android.Module {
func NewPrebuiltDylib(hod android.HostOrDeviceSupported) (*Module, *prebuiltLibraryDecorator) {
module, library := NewRustLibrary(hod)
library.BuildOnlyDylib()
library.setNoStdlibs()
library.setDylib()
prebuilt := &prebuiltLibraryDecorator{
libraryDecorator: library,

View File

@@ -209,6 +209,25 @@ func TestProcMacroDeviceDeps(t *testing.T) {
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 @@ func TestProcMacroDeviceDeps(t *testing.T) {
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")
}
}