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
diff --git a/cc/library.go b/cc/library.go
index a436649..2fd3ded 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -274,11 +274,12 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
// 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()