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:
Ivan Lozano
2024-05-13 21:03:34 -04:00
parent 28ed8f4f83
commit 0a468a4f3b
22 changed files with 643 additions and 127 deletions

View File

@@ -274,11 +274,12 @@ func LibraryHostSharedFactory() android.Module {
type flagExporter struct {
Properties FlagExporterProperties
dirs android.Paths // Include directories to be included with -I
systemDirs android.Paths // System include directories to be included with -isystem
flags []string // Exported raw flags.
deps android.Paths
headers android.Paths
dirs android.Paths // Include directories to be included with -I
systemDirs android.Paths // System include directories to be included with -isystem
flags []string // Exported raw flags.
deps android.Paths
headers android.Paths
rustRlibDeps []RustRlibDep
}
// exportedIncludes returns the effective include paths for this module and
@@ -339,6 +340,10 @@ func (f *flagExporter) reexportDeps(deps ...android.Path) {
f.deps = append(f.deps, deps...)
}
func (f *flagExporter) reexportRustStaticDeps(deps ...RustRlibDep) {
f.rustRlibDeps = append(f.rustRlibDeps, deps...)
}
// addExportedGeneratedHeaders does nothing but collects generated header files.
// This can be differ to exportedDeps which may contain phony files to minimize ninja.
func (f *flagExporter) addExportedGeneratedHeaders(headers ...android.Path) {
@@ -356,6 +361,8 @@ func (f *flagExporter) setProvider(ctx android.ModuleContext) {
// Used sparingly, for extra files that need to be explicitly exported to dependers,
// or for phony files to minimize ninja.
Deps: f.deps,
// Used for exporting rlib deps of static libraries to dependents.
RustRlibDeps: f.rustRlibDeps,
// For exported generated headers, such as exported aidl headers, proto headers, or
// sysprop headers.
GeneratedHeaders: f.headers,
@@ -1132,9 +1139,14 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil {
deps.StaticLibs = append(deps.StaticLibs, generatedLib)
}
transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles)
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin,
deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs, objs.tidyDepFiles)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
@@ -1594,6 +1606,10 @@ func (library *libraryDecorator) link(ctx ModuleContext,
library.reexportDeps(deps.ReexportedDeps...)
library.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
if library.static() && len(deps.ReexportedRustRlibDeps) > 0 {
library.reexportRustStaticDeps(deps.ReexportedRustRlibDeps...)
}
// Optionally export aidl headers.
if Bool(library.Properties.Aidl.Export_aidl_headers) {
if library.baseCompiler.hasAidl(deps) {
@@ -2121,14 +2137,12 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) {
// Header only
}
} else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
} else if library, ok := mctx.Module().(LinkableInterface); ok && (library.CcLibraryInterface() || library.RustLibraryInterface()) {
// Non-cc.Modules may need an empty variant for their mutators.
variations := []string{}
if library.NonCcVariants() {
variations = append(variations, "")
}
isLLNDK := false
if m, ok := mctx.Module().(*Module); ok {
isLLNDK = m.IsLlndk()