From 99020b04fbf5ce97d9a7a5b56b44cadeeb34ca4c Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 31 Oct 2019 10:44:40 -0700 Subject: [PATCH 1/2] 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 --- rust/binary.go | 7 ------- rust/builder.go | 6 ++++++ rust/compiler.go | 24 ++++++++++++++++++++++++ rust/config/whitelist.go | 1 + rust/prebuilt.go | 1 + rust/rust_test.go | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 7 deletions(-) diff --git a/rust/binary.go b/rust/binary.go index 52f840e7a..3f43da076 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -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" diff --git a/rust/builder.go b/rust/builder.go index 2a7643d62..d46f34af1 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -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...) diff --git a/rust/compiler.go b/rust/compiler.go index 3f028350a..f6e952a75 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -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 } diff --git a/rust/config/whitelist.go b/rust/config/whitelist.go index 8025bcf8f..1a7b81f44 100644 --- a/rust/config/whitelist.go +++ b/rust/config/whitelist.go @@ -5,6 +5,7 @@ var ( "external/rust", "external/crosvm", "external/adhd", + "prebuilts/rust", } RustModuleTypes = []string{ diff --git a/rust/prebuilt.go b/rust/prebuilt.go index fa69fbb86..45bef9ea3 100644 --- a/rust/prebuilt.go +++ b/rust/prebuilt.go @@ -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, diff --git a/rust/rust_test.go b/rust/rust_test.go index eb04e7257..bbd911114 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -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") + } +} From 51feafad57da137b3476de84e8e9fd8fd3732cb4 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 31 Oct 2019 10:46:17 -0700 Subject: [PATCH 2/2] Enable x86_64 device support Now that we have sysroots built in Soong, we can enable these devices and they just work. Bug: 141251907 Bug: 141381044 Change-Id: I562256fee372d331db883f7c1b46405945295c24 --- rust/config/x86_64_device.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go index 2aca56a3d..9a6c00b19 100644 --- a/rust/config/x86_64_device.go +++ b/rust/config/x86_64_device.go @@ -41,8 +41,8 @@ var ( func init() { registerToolchainFactory(android.Android, android.X86_64, x86_64ToolchainFactory) - pctx.StaticVariable("x86_64ToolchainRustFlags", strings.Join(x86_64RustFlags, " ")) - pctx.StaticVariable("x86_64ToolchainLinkFlags", strings.Join(x86_64LinkFlags, " ")) + pctx.StaticVariable("X86_64ToolchainRustFlags", strings.Join(x86_64RustFlags, " ")) + pctx.StaticVariable("X86_64ToolchainLinkFlags", strings.Join(x86_64LinkFlags, " ")) for variant, rustFlags := range x86_64ArchVariantRustFlags { pctx.StaticVariable("X86_64"+variant+"VariantRustFlags", @@ -57,11 +57,11 @@ type toolchainX86_64 struct { } func (t *toolchainX86_64) RustTriple() string { - return "x86_64-unknown-linux-gnu" + return "x86_64-linux-android" } func (t *toolchainX86_64) ToolchainLinkFlags() string { - return "${config.x86_64ToolchainLinkFlags}" + return "${config.DeviceGlobalLinkFlags} ${config.X86_64ToolchainLinkFlags}" } func (t *toolchainX86_64) ToolchainRustFlags() string { @@ -69,15 +69,21 @@ func (t *toolchainX86_64) ToolchainRustFlags() string { } func (t *toolchainX86_64) RustFlags() string { - return "${config.x86_64ToolchainRustFlags}" + return "${config.X86_64ToolchainRustFlags}" +} + +func (t *toolchainX86_64) Supported() bool { + return true } func x86_64ToolchainFactory(arch android.Arch) Toolchain { toolchainRustFlags := []string{ - "${config.x86_64ToolchainRustFlags}", + "${config.X86_64ToolchainRustFlags}", "${config.X86_64" + arch.ArchVariant + "VariantRustFlags}", } + toolchainRustFlags = append(toolchainRustFlags, deviceGlobalRustFlags...) + for _, feature := range arch.ArchFeatures { toolchainRustFlags = append(toolchainRustFlags, x86_64ArchFeatureRustFlags[feature]...) }