From 0a468a4f3b1c9dea9b31ca51cebd3db58d65e771 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Mon, 13 May 2024 21:03:34 -0400 Subject: rust: made-to-order rust staticlibs Whenever any two Rust static libraries are included as static libraries anywhere in a CC dependency tree, we sometimes get duplicate symbol errors. To avoid this, we no longer directly link multiple rust static libs to CC modules. Instead, we build rust_ffi_rlib modules and produce the actual static library that gets linked against the CC module based on that CC module's full list of Rust rlib dependencies. This introduces a new static_rlibs property for cc modules to define the rust_ffi_rlib dependencies, which are then used to generate the module above. This CL is intended to deprecate rust_ffi_static. It leaves rust_ffi_static and rust_ffi static variants in place until the remaining rust_ffi_static declarations and uses can be removed. In the meantime, rust_ffi_static produces rust_ffi_rlib variants as well to make the transition easier. Bug: 254469782 Test: m # with no changes Test: m libapexsupport # with static_rlibs Test: m libunwindstack # with static_rlibs Test: m netsimd # with static_rlibs, no duplicate symbols Test: m blueprint_tests # New Soong tests Change-Id: I47e27ac967ef0cad46d398ebf59d8275929ae28a --- rust/builder.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'rust/builder.go') diff --git a/rust/builder.go b/rust/builder.go index 1281db523..abbf90d83 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -21,6 +21,7 @@ import ( "github.com/google/blueprint" "android/soong/android" + "android/soong/cc" "android/soong/rust/config" ) @@ -118,6 +119,7 @@ type buildOutput struct { func init() { pctx.HostBinToolVariable("SoongZipCmd", "soong_zip") + cc.TransformRlibstoStaticlib = TransformRlibstoStaticlib } type transformProperties struct { @@ -166,6 +168,48 @@ func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib")) } +func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, deps []cc.RustRlibDep, + outputFile android.WritablePath) android.Path { + + var rustPathDeps PathDeps + var rustFlags Flags + + for _, rlibDep := range deps { + rustPathDeps.RLibs = append(rustPathDeps.RLibs, RustLibrary{Path: rlibDep.LibPath, CrateName: rlibDep.CrateName}) + rustPathDeps.linkDirs = append(rustPathDeps.linkDirs, rlibDep.LinkDirs...) + } + + ccModule := ctx.(cc.ModuleContext).Module().(*cc.Module) + toolchain := config.FindToolchain(ctx.Os(), ctx.Arch()) + t := transformProperties{ + // Crate name can be a predefined value as this is a staticlib and + // it does not need to be unique. The crate name is used for name + // mangling, but it is mixed with the metadata for that purpose, which we + // already set to the module name. + crateName: "generated_rust_staticlib", + is64Bit: toolchain.Is64Bit(), + targetTriple: toolchain.RustTriple(), + bootstrap: ccModule.Bootstrap(), + inRecovery: ccModule.InRecovery(), + inRamdisk: ccModule.InRamdisk(), + inVendorRamdisk: ccModule.InVendorRamdisk(), + + // crateType indicates what type of crate to build + crateType: "staticlib", + + // synthetic indicates whether this is an actual Rust module or not + synthetic: true, + } + + rustFlags = CommonDefaultFlags(ctx, toolchain, rustFlags) + rustFlags = CommonLibraryCompilerFlags(ctx, rustFlags) + rustFlags.GlobalRustFlags = append(rustFlags.GlobalRustFlags, "-C lto=thin") + + rustFlags.EmitXrefs = false + + return transformSrctoCrate(ctx, mainSrc, rustPathDeps, rustFlags, outputFile, t).outputFile +} + func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath) buildOutput { flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin") -- cgit v1.2.3-59-g8ed1b