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") + } +}