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:
59
rust/rust.go
59
rust/rust.go
@@ -158,6 +158,8 @@ type Module struct {
|
||||
sourceProvider SourceProvider
|
||||
subAndroidMkOnce map[SubAndroidMkProvider]bool
|
||||
|
||||
exportedLinkDirs []string
|
||||
|
||||
// Output file to be installed, may be stripped or unstripped.
|
||||
outputFile android.OptionalPath
|
||||
|
||||
@@ -234,8 +236,8 @@ func (mod *Module) SelectedStl() string {
|
||||
|
||||
func (mod *Module) NonCcVariants() bool {
|
||||
if mod.compiler != nil {
|
||||
if _, ok := mod.compiler.(libraryInterface); ok {
|
||||
return false
|
||||
if library, ok := mod.compiler.(libraryInterface); ok {
|
||||
return library.buildRlib() || library.buildDylib()
|
||||
}
|
||||
}
|
||||
panic(fmt.Errorf("NonCcVariants called on non-library module: %q", mod.BaseModuleName()))
|
||||
@@ -465,6 +467,11 @@ type PathDeps struct {
|
||||
linkDirs []string
|
||||
linkObjects []string
|
||||
|
||||
// exportedLinkDirs are exported linkDirs for direct rlib dependencies to
|
||||
// cc_library_static dependants of rlibs.
|
||||
// Track them separately from linkDirs so superfluous -L flags don't get emitted.
|
||||
exportedLinkDirs []string
|
||||
|
||||
// Used by bindgen modules which call clang
|
||||
depClangFlags []string
|
||||
depIncludePaths android.Paths
|
||||
@@ -477,6 +484,9 @@ type PathDeps struct {
|
||||
// Paths to generated source files
|
||||
SrcDeps android.Paths
|
||||
srcProviderFiles android.Paths
|
||||
|
||||
// Used by Generated Libraries
|
||||
depExportedRlibs []cc.RustRlibDep
|
||||
}
|
||||
|
||||
type RustLibraries []RustLibrary
|
||||
@@ -543,6 +553,10 @@ func (mod *Module) VndkVersion() string {
|
||||
return mod.Properties.VndkVersion
|
||||
}
|
||||
|
||||
func (mod *Module) ExportedCrateLinkDirs() []string {
|
||||
return mod.exportedLinkDirs
|
||||
}
|
||||
|
||||
func (mod *Module) PreventInstall() bool {
|
||||
return mod.Properties.PreventInstall
|
||||
}
|
||||
@@ -657,15 +671,6 @@ func (mod *Module) UnstrippedOutputFile() android.Path {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mod *Module) IncludeDirs() android.Paths {
|
||||
if mod.compiler != nil {
|
||||
if library, ok := mod.compiler.(*libraryDecorator); ok {
|
||||
return library.includeDirs
|
||||
}
|
||||
}
|
||||
panic(fmt.Errorf("IncludeDirs called on non-library module: %q", mod.BaseModuleName()))
|
||||
}
|
||||
|
||||
func (mod *Module) SetStatic() {
|
||||
if mod.compiler != nil {
|
||||
if library, ok := mod.compiler.(libraryInterface); ok {
|
||||
@@ -914,6 +919,10 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
||||
}
|
||||
|
||||
deps := mod.depsToPaths(ctx)
|
||||
// Export linkDirs for CC rust generatedlibs
|
||||
mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.exportedLinkDirs...)
|
||||
mod.exportedLinkDirs = append(mod.exportedLinkDirs, deps.linkDirs...)
|
||||
|
||||
flags := Flags{
|
||||
Toolchain: toolchain,
|
||||
}
|
||||
@@ -991,6 +1000,9 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
// Export your own directory as a linkDir
|
||||
mod.exportedLinkDirs = append(mod.exportedLinkDirs, linkPathFromFilePath(mod.OutputFile().Path()))
|
||||
|
||||
}
|
||||
|
||||
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
|
||||
@@ -1223,7 +1235,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
return
|
||||
}
|
||||
|
||||
if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
|
||||
if rustDep, ok := dep.(*Module); ok && !rustDep.Static() && !rustDep.Shared() {
|
||||
//Handle Rust Modules
|
||||
makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
|
||||
|
||||
@@ -1249,9 +1261,16 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
|
||||
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
|
||||
|
||||
// rust_ffi rlibs may export include dirs, so collect those here.
|
||||
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, cc.FlagExporterInfoProvider)
|
||||
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
|
||||
depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
|
||||
|
||||
case procMacroDepTag:
|
||||
directProcMacroDeps = append(directProcMacroDeps, rustDep)
|
||||
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
|
||||
// proc_macro link dirs need to be exported, so collect those here.
|
||||
depPaths.exportedLinkDirs = append(depPaths.exportedLinkDirs, linkPathFromFilePath(rustDep.OutputFile().Path()))
|
||||
|
||||
case sourceDepTag:
|
||||
if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
|
||||
@@ -1281,12 +1300,12 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
directSrcProvidersDeps = append(directSrcProvidersDeps, rustDep)
|
||||
}
|
||||
|
||||
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
|
||||
//Append the dependencies exportedDirs, except for proc-macros which target a different arch/OS
|
||||
if depTag != procMacroDepTag {
|
||||
exportedInfo, _ := android.OtherModuleProvider(ctx, dep, FlagExporterInfoProvider)
|
||||
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
|
||||
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
|
||||
depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
|
||||
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
|
||||
}
|
||||
|
||||
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
|
||||
@@ -1296,6 +1315,7 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
||||
lib.exportLinkDirs(linkDir)
|
||||
}
|
||||
}
|
||||
|
||||
if depTag == sourceDepTag {
|
||||
if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() {
|
||||
if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok {
|
||||
@@ -1560,6 +1580,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
}
|
||||
|
||||
rlibDepVariations := commonDepVariations
|
||||
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||
|
||||
if lib, ok := mod.compiler.(libraryInterface); !ok || !lib.sysroot() {
|
||||
rlibDepVariations = append(rlibDepVariations,
|
||||
@@ -1575,6 +1596,8 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
|
||||
// dylibs
|
||||
dylibDepVariations := append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: dylibVariation})
|
||||
dylibDepVariations = append(dylibDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||
|
||||
for _, lib := range deps.Dylibs {
|
||||
actx.AddVariationDependencies(dylibDepVariations, dylibDepTag, lib)
|
||||
}
|
||||
@@ -1594,7 +1617,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
// otherwise select the rlib variant.
|
||||
autoDepVariations := append(commonDepVariations,
|
||||
blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
|
||||
|
||||
autoDepVariations = append(autoDepVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||
if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
|
||||
actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
|
||||
|
||||
@@ -1609,7 +1632,11 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
for _, lib := range deps.Rustlibs {
|
||||
srcProviderVariations := append(commonDepVariations,
|
||||
blueprint.Variation{Mutator: "rust_libraries", Variation: "source"})
|
||||
srcProviderVariations = append(srcProviderVariations, blueprint.Variation{Mutator: "link", Variation: ""})
|
||||
|
||||
// Only add rustlib dependencies if they're source providers themselves.
|
||||
// This is used to track which crate names need to be added to the source generated
|
||||
// in the rust_protobuf mod.rs.
|
||||
if actx.OtherModuleDependencyVariantExists(srcProviderVariations, lib) {
|
||||
actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib)
|
||||
}
|
||||
@@ -1621,7 +1648,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
||||
if deps.Stdlibs != nil {
|
||||
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
|
||||
for _, lib := range deps.Stdlibs {
|
||||
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
|
||||
actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}, {Mutator: "link", Variation: ""}}...),
|
||||
rlibDepTag, lib)
|
||||
}
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user