diff options
author | 2024-05-13 21:03:34 -0400 | |
---|---|---|
committer | 2024-05-16 13:00:43 -0400 | |
commit | 0a468a4f3b1c9dea9b31ca51cebd3db58d65e771 (patch) | |
tree | 9ee8007e83b660eb7bb4affcbf6584ea3fdab82e /rust/builder.go | |
parent | 28ed8f4f83551ca651dd3831eb5b0a23567f5fa6 (diff) |
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
Diffstat (limited to 'rust/builder.go')
-rw-r--r-- | rust/builder.go | 44 |
1 files changed, 44 insertions, 0 deletions
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") |