diff --git a/rust/binary.go b/rust/binary.go index 5d9b0a67b..0dc320e5f 100644 --- a/rust/binary.go +++ b/rust/binary.go @@ -92,12 +92,21 @@ func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Fla func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { deps = binary.baseCompiler.compilerDeps(ctx, deps) + static := Bool(binary.Properties.Static_executable) if ctx.toolchain().Bionic() { - deps = bionicDeps(ctx, deps, Bool(binary.Properties.Static_executable)) - if Bool(binary.Properties.Static_executable) { + deps = bionicDeps(ctx, deps, static) + if static { deps.CrtBegin = []string{"crtbegin_static"} } else { - deps.CrtBegin = []string{"libc_musl_crtbegin_dynamic"} + deps.CrtBegin = []string{"crtbegin_dynamic"} + } + deps.CrtEnd = []string{"crtend_android"} + } else if ctx.Os() == android.LinuxMusl { + deps = muslDeps(ctx, deps, static) + if static { + deps.CrtBegin = []string{"libc_musl_crtbegin_static"} + } else { + deps.CrtBegin = []string{"libc_musl_crtbegin_dynamic", "musl_linker_script"} } deps.CrtEnd = []string{"libc_musl_crtend"} } diff --git a/rust/bindgen.go b/rust/bindgen.go index ef5702bcd..f4c337d69 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -288,6 +288,8 @@ func (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps { deps = b.BaseSourceProvider.SourceProviderDeps(ctx, deps) if ctx.toolchain().Bionic() { deps = bionicDeps(ctx, deps, false) + } else if ctx.Os() == android.LinuxMusl { + deps = muslDeps(ctx, deps, false) } deps.SharedLibs = append(deps.SharedLibs, b.ClangProperties.Shared_libs...) diff --git a/rust/compiler.go b/rust/compiler.go index 3040e5d9e..c5d40f4dc 100644 --- a/rust/compiler.go +++ b/rust/compiler.go @@ -364,7 +364,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { if !Bool(compiler.Properties.No_stdlibs) { for _, stdlib := range config.Stdlibs { // If we're building for the build host, use the prebuilt stdlibs - if ctx.Target().Os == ctx.Config().BuildOS { + if ctx.Target().Os == android.Linux || ctx.Target().Os == android.Darwin { stdlib = "prebuilt_" + stdlib } deps.Stdlibs = append(deps.Stdlibs, stdlib) @@ -394,6 +394,20 @@ func bionicDeps(ctx DepsContext, deps Deps, static bool) Deps { return deps } +func muslDeps(ctx DepsContext, deps Deps, static bool) Deps { + muslLibs := []string{"libc_musl"} + if static { + deps.StaticLibs = append(deps.StaticLibs, muslLibs...) + } else { + deps.SharedLibs = append(deps.SharedLibs, muslLibs...) + } + if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" { + deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins) + } + + return deps +} + func (compiler *baseCompiler) crateName() string { return compiler.Properties.Crate_name } diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go index c10afd86f..760834929 100644 --- a/rust/config/x86_linux_host.go +++ b/rust/config/x86_linux_host.go @@ -22,12 +22,29 @@ import ( var ( LinuxRustFlags = []string{} + LinuxMuslRustFlags = []string{ + // disable rustc's builtin fallbacks for crt objects + "-C link_self_contained=no", + // force rustc to use a dynamic musl libc + "-C target-feature=-crt-static", + "-Z link-native-libraries=no", + } LinuxRustLinkFlags = []string{ "-B${cc_config.ClangBin}", "-fuse-ld=lld", "-Wl,--undefined-version", + } + LinuxRustGlibcLinkFlags = []string{ "--sysroot ${cc_config.LinuxGccRoot}/sysroot", } + LinuxRustMuslLinkFlags = []string{ + "--sysroot /dev/null", + "-nodefaultlibs", + "-nostdlib", + "-Wl,--no-dynamic-linker", + // for unwind + "-lgcc", "-lgcc_eh", + } linuxX86Rustflags = []string{} linuxX86Linkflags = []string{} linuxX8664Rustflags = []string{} @@ -35,15 +52,17 @@ var ( ) func init() { - registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory) - registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory) + registerToolchainFactory(android.Linux, android.X86_64, linuxGlibcX8664ToolchainFactory) + registerToolchainFactory(android.Linux, android.X86, linuxGlibcX86ToolchainFactory) - // TODO: musl rust support - registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxX8664ToolchainFactory) - registerToolchainFactory(android.LinuxMusl, android.X86, linuxX86ToolchainFactory) + registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxMuslX8664ToolchainFactory) + registerToolchainFactory(android.LinuxMusl, android.X86, linuxMuslX86ToolchainFactory) pctx.StaticVariable("LinuxToolchainRustFlags", strings.Join(LinuxRustFlags, " ")) + pctx.StaticVariable("LinuxMuslToolchainRustFlags", strings.Join(LinuxMuslRustFlags, " ")) pctx.StaticVariable("LinuxToolchainLinkFlags", strings.Join(LinuxRustLinkFlags, " ")) + pctx.StaticVariable("LinuxGlibcToolchainLinkFlags", strings.Join(LinuxRustGlibcLinkFlags, " ")) + pctx.StaticVariable("LinuxMuslToolchainLinkFlags", strings.Join(LinuxRustMuslLinkFlags, " ")) pctx.StaticVariable("LinuxToolchainX86RustFlags", strings.Join(linuxX86Rustflags, " ")) pctx.StaticVariable("LinuxToolchainX86LinkFlags", strings.Join(linuxX86Linkflags, " ")) pctx.StaticVariable("LinuxToolchainX8664RustFlags", strings.Join(linuxX8664Rustflags, " ")) @@ -51,19 +70,9 @@ func init() { } -type toolchainLinux struct { - toolchainRustFlags string - toolchainLinkFlags string -} - -type toolchainLinuxX86 struct { - toolchain32Bit - toolchainLinux -} - +// Base 64-bit linux rust toolchain type toolchainLinuxX8664 struct { toolchain64Bit - toolchainLinux } func (toolchainLinuxX8664) Supported() bool { @@ -78,10 +87,6 @@ func (t *toolchainLinuxX8664) Name() string { return "x86_64" } -func (t *toolchainLinuxX8664) RustTriple() string { - return "x86_64-unknown-linux-gnu" -} - func (t *toolchainLinuxX8664) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc return "${cc_config.LinuxLldflags} ${cc_config.LinuxX8664Lldflags} " + @@ -92,8 +97,49 @@ func (t *toolchainLinuxX8664) ToolchainRustFlags() string { return "${config.LinuxToolchainRustFlags} ${config.LinuxToolchainX8664RustFlags}" } -func linuxX8664ToolchainFactory(arch android.Arch) Toolchain { - return toolchainLinuxX8664Singleton +// Specialization of the 64-bit linux rust toolchain for glibc. Adds the gnu rust triple and +// sysroot linker flags. +type toolchainLinuxGlibcX8664 struct { + toolchainLinuxX8664 +} + +func (t *toolchainLinuxX8664) RustTriple() string { + return "x86_64-unknown-linux-gnu" +} + +func (t *toolchainLinuxGlibcX8664) ToolchainLinkFlags() string { + return t.toolchainLinuxX8664.ToolchainLinkFlags() + " " + "${config.LinuxGlibcToolchainLinkFlags}" +} + +func linuxGlibcX8664ToolchainFactory(arch android.Arch) Toolchain { + return toolchainLinuxGlibcX8664Singleton +} + +// Specialization of the 64-bit linux rust toolchain for musl. Adds the musl rust triple and +// linker flags to avoid using the host sysroot. +type toolchainLinuxMuslX8664 struct { + toolchainLinuxX8664 +} + +func (t *toolchainLinuxMuslX8664) RustTriple() string { + return "x86_64-unknown-linux-musl" +} + +func (t *toolchainLinuxMuslX8664) ToolchainLinkFlags() string { + return t.toolchainLinuxX8664.ToolchainLinkFlags() + " " + "${config.LinuxMuslToolchainLinkFlags}" +} + +func (t *toolchainLinuxMuslX8664) ToolchainRustFlags() string { + return t.toolchainLinuxX8664.ToolchainRustFlags() + " " + "${config.LinuxMuslToolchainRustFlags}" +} + +func linuxMuslX8664ToolchainFactory(arch android.Arch) Toolchain { + return toolchainLinuxMuslX8664Singleton +} + +// Base 32-bit linux rust toolchain +type toolchainLinuxX86 struct { + toolchain32Bit } func (toolchainLinuxX86) Supported() bool { @@ -116,10 +162,6 @@ func (toolchainLinuxX8664) LibclangRuntimeLibraryArch() string { return "x86_64" } -func (t *toolchainLinuxX86) RustTriple() string { - return "i686-unknown-linux-gnu" -} - func (t *toolchainLinuxX86) ToolchainLinkFlags() string { // Prepend the lld flags from cc_config so we stay in sync with cc return "${cc_config.LinuxLldflags} ${cc_config.LinuxX86Lldflags} " + @@ -130,9 +172,47 @@ func (t *toolchainLinuxX86) ToolchainRustFlags() string { return "${config.LinuxToolchainRustFlags} ${config.LinuxToolchainX86RustFlags}" } -func linuxX86ToolchainFactory(arch android.Arch) Toolchain { - return toolchainLinuxX86Singleton +// Specialization of the 32-bit linux rust toolchain for glibc. Adds the gnu rust triple and +// sysroot linker flags. +type toolchainLinuxGlibcX86 struct { + toolchainLinuxX86 } -var toolchainLinuxX8664Singleton Toolchain = &toolchainLinuxX8664{} -var toolchainLinuxX86Singleton Toolchain = &toolchainLinuxX86{} +func (t *toolchainLinuxGlibcX86) RustTriple() string { + return "i686-unknown-linux-gnu" +} + +func (t *toolchainLinuxGlibcX86) ToolchainLinkFlags() string { + return t.toolchainLinuxX86.ToolchainLinkFlags() + " " + "${config.LinuxGlibcToolchainLinkFlags}" +} + +func linuxGlibcX86ToolchainFactory(arch android.Arch) Toolchain { + return toolchainLinuxGlibcX86Singleton +} + +// Specialization of the 32-bit linux rust toolchain for musl. Adds the musl rust triple and +// linker flags to avoid using the host sysroot. +type toolchainLinuxMuslX86 struct { + toolchainLinuxX86 +} + +func (t *toolchainLinuxMuslX86) RustTriple() string { + return "i686-unknown-linux-musl" +} + +func (t *toolchainLinuxMuslX86) ToolchainLinkFlags() string { + return t.toolchainLinuxX86.ToolchainLinkFlags() + " " + "${config.LinuxMuslToolchainLinkFlags}" +} + +func (t *toolchainLinuxMuslX86) ToolchainRustFlags() string { + return t.toolchainLinuxX86.ToolchainRustFlags() + " " + "${config.LinuxMuslToolchainRustFlags}" +} + +func linuxMuslX86ToolchainFactory(arch android.Arch) Toolchain { + return toolchainLinuxMuslX86Singleton +} + +var toolchainLinuxGlibcX8664Singleton Toolchain = &toolchainLinuxGlibcX8664{} +var toolchainLinuxGlibcX86Singleton Toolchain = &toolchainLinuxGlibcX86{} +var toolchainLinuxMuslX8664Singleton Toolchain = &toolchainLinuxMuslX8664{} +var toolchainLinuxMuslX86Singleton Toolchain = &toolchainLinuxMuslX86{} diff --git a/rust/library.go b/rust/library.go index 9d79c53f2..baac3f0bc 100644 --- a/rust/library.go +++ b/rust/library.go @@ -426,10 +426,16 @@ func (library *libraryDecorator) compilerProps() []interface{} { func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { deps = library.baseCompiler.compilerDeps(ctx, deps) - if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) { - deps = bionicDeps(ctx, deps, false) - deps.CrtBegin = []string{"crtbegin_so"} - deps.CrtEnd = []string{"crtend_so"} + if library.dylib() || library.shared() { + if ctx.toolchain().Bionic() { + deps = bionicDeps(ctx, deps, false) + deps.CrtBegin = []string{"crtbegin_so"} + deps.CrtEnd = []string{"crtend_so"} + } else if ctx.Os() == android.LinuxMusl { + deps = muslDeps(ctx, deps, false) + deps.CrtBegin = []string{"libc_musl_crtbegin_so"} + deps.CrtEnd = []string{"libc_musl_crtend_so"} + } } return deps