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
This commit is contained in:
@@ -19,6 +19,7 @@ package cc
|
||||
// functions.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -330,6 +331,15 @@ var (
|
||||
CommandDeps: []string{"$cxxExtractor", "$kytheVnames"},
|
||||
},
|
||||
"cFlags")
|
||||
|
||||
// Function pointer for producting staticlibs from rlibs. Corresponds to
|
||||
// rust.TransformRlibstoStaticlib(), initialized in soong-rust (rust/builder.go init())
|
||||
//
|
||||
// This is required since soong-rust depends on soong-cc, so soong-cc cannot depend on soong-rust
|
||||
// without resulting in a circular dependency. Setting this function pointer in soong-rust allows
|
||||
// soong-cc to call into this particular function.
|
||||
TransformRlibstoStaticlib (func(ctx android.ModuleContext, mainSrc android.Path, deps []RustRlibDep,
|
||||
outputFile android.WritablePath) android.Path) = nil
|
||||
)
|
||||
|
||||
func PwdPrefix() string {
|
||||
@@ -774,6 +784,47 @@ func transformObjToStaticLib(ctx android.ModuleContext,
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a Rust staticlib from a list of rlibDeps. Returns nil if TransformRlibstoStaticlib is nil or rlibDeps is empty.
|
||||
func generateRustStaticlib(ctx android.ModuleContext, rlibDeps []RustRlibDep) android.Path {
|
||||
if TransformRlibstoStaticlib == nil && len(rlibDeps) > 0 {
|
||||
// This should only be reachable if a module defines static_rlibs and
|
||||
// soong-rust hasn't been loaded alongside soong-cc (e.g. in soong-cc tests).
|
||||
panic(fmt.Errorf("TransformRlibstoStaticlib is not set and static_rlibs is defined in %s", ctx.ModuleName()))
|
||||
} else if len(rlibDeps) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
output := android.PathForModuleOut(ctx, "generated_rust_staticlib", "lib"+ctx.ModuleName()+"_rust_staticlib.a")
|
||||
stemFile := output.ReplaceExtension(ctx, "rs")
|
||||
crateNames := []string{}
|
||||
|
||||
// Collect crate names
|
||||
for _, lib := range rlibDeps {
|
||||
// Exclude libstd so this can support no_std builds.
|
||||
if lib.CrateName != "libstd" {
|
||||
crateNames = append(crateNames, lib.CrateName)
|
||||
}
|
||||
}
|
||||
|
||||
// Deduplicate any crateNames just to be safe
|
||||
crateNames = android.FirstUniqueStrings(crateNames)
|
||||
|
||||
// Write the source file
|
||||
android.WriteFileRule(ctx, stemFile, genRustStaticlibSrcFile(crateNames))
|
||||
|
||||
return TransformRlibstoStaticlib(ctx, stemFile, rlibDeps, output)
|
||||
}
|
||||
|
||||
func genRustStaticlibSrcFile(crateNames []string) string {
|
||||
lines := []string{
|
||||
"// @Soong generated Source",
|
||||
}
|
||||
for _, crate := range crateNames {
|
||||
lines = append(lines, fmt.Sprintf("extern crate %s;", crate))
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
|
||||
// and shared libraries, to a shared library (.so) or dynamic executable
|
||||
func transformObjToDynamicBinary(ctx android.ModuleContext,
|
||||
|
Reference in New Issue
Block a user