Update linker.config.pb based on package dependency

Current linker.config.pb from the package is generated with
auto-detected provide libs, but this misses require libs which can be
detected from module dependency. This change adds extra require libs to
linker.config.pb generated from system image so it can link with modules
outside of system image.

Bug: 324995772
Test: Link succeeded from Cuttlefish with soong defined system image
Change-Id: I8563ec9ddce2a1648cc9ee55704c9483e137b710
This commit is contained in:
Kiyoung Kim 2024-03-22 18:00:40 +09:00
parent bfa7f261d1
commit ee599d6694
2 changed files with 60 additions and 12 deletions

View file

@ -56,19 +56,40 @@ func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root andr
output := root.Join(ctx, "system", "etc", "linker.config.pb") output := root.Join(ctx, "system", "etc", "linker.config.pb")
// we need "Module"s for packaging items // we need "Module"s for packaging items
var otherModules []android.Module modulesInPackageByModule := make(map[android.Module]bool)
modulesInPackageByName := make(map[string]bool)
deps := s.gatherFilteredPackagingSpecs(ctx) deps := s.gatherFilteredPackagingSpecs(ctx)
ctx.WalkDeps(func(child, parent android.Module) bool { ctx.WalkDeps(func(child, parent android.Module) bool {
for _, ps := range child.PackagingSpecs() { for _, ps := range child.PackagingSpecs() {
if _, ok := deps[ps.RelPathInPackage()]; ok { if _, ok := deps[ps.RelPathInPackage()]; ok {
otherModules = append(otherModules, child) modulesInPackageByModule[child] = true
modulesInPackageByName[child.Name()] = true
return true
} }
} }
return true return true
}) })
provideModules := make([]android.Module, 0, len(modulesInPackageByModule))
for mod := range modulesInPackageByModule {
provideModules = append(provideModules, mod)
}
var requireModules []android.Module
ctx.WalkDeps(func(child, parent android.Module) bool {
_, parentInPackage := modulesInPackageByModule[parent]
_, childInPackageName := modulesInPackageByName[child.Name()]
// When parent is in the package, and child (or its variant) is not, this can be from an interface.
if parentInPackage && !childInPackageName {
requireModules = append(requireModules, child)
}
return true
})
builder := android.NewRuleBuilder(pctx, ctx) builder := android.NewRuleBuilder(pctx, ctx)
linkerconfig.BuildLinkerConfig(ctx, builder, input, otherModules, output) linkerconfig.BuildLinkerConfig(ctx, builder, input, provideModules, requireModules, output)
builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String()) builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
return output return output
} }

View file

@ -89,7 +89,7 @@ func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
builder := android.NewRuleBuilder(pctx, ctx) builder := android.NewRuleBuilder(pctx, ctx)
BuildLinkerConfig(ctx, builder, input, nil, output) BuildLinkerConfig(ctx, builder, input, nil, nil, output)
builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String()) builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String())
l.outputFilePath = output l.outputFilePath = output
@ -101,7 +101,7 @@ func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder, func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
input android.Path, otherModules []android.Module, output android.OutputPath) { input android.Path, provideModules []android.Module, requireModules []android.Module, output android.OutputPath) {
// First, convert the input json to protobuf format // First, convert the input json to protobuf format
interimOutput := android.PathForModuleOut(ctx, "temp.pb") interimOutput := android.PathForModuleOut(ctx, "temp.pb")
@ -111,9 +111,9 @@ func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
FlagWithInput("-s ", input). FlagWithInput("-s ", input).
FlagWithOutput("-o ", interimOutput) FlagWithOutput("-o ", interimOutput)
// Secondly, if there's provideLibs gathered from otherModules, append them // Secondly, if there's provideLibs gathered from provideModules, append them
var provideLibs []string var provideLibs []string
for _, m := range otherModules { for _, m := range provideModules {
if c, ok := m.(*cc.Module); ok && cc.IsStubTarget(c) { if c, ok := m.(*cc.Module); ok && cc.IsStubTarget(c) {
for _, ps := range c.PackagingSpecs() { for _, ps := range c.PackagingSpecs() {
provideLibs = append(provideLibs, ps.FileName()) provideLibs = append(provideLibs, ps.FileName())
@ -122,18 +122,45 @@ func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
} }
provideLibs = android.FirstUniqueStrings(provideLibs) provideLibs = android.FirstUniqueStrings(provideLibs)
sort.Strings(provideLibs) sort.Strings(provideLibs)
var requireLibs []string
for _, m := range requireModules {
if c, ok := m.(*cc.Module); ok && c.HasStubsVariants() && !c.Host() {
requireLibs = append(requireLibs, c.ImplementationModuleName(ctx)+".so")
}
}
requireLibs = android.FirstUniqueStrings(requireLibs)
sort.Strings(requireLibs)
if len(provideLibs) > 0 { if len(provideLibs) > 0 {
prevOutput := interimOutput
interimOutput = android.PathForModuleOut(ctx, "temp_provideLibs.pb")
builder.Command(). builder.Command().
BuiltTool("conv_linker_config"). BuiltTool("conv_linker_config").
Flag("append"). Flag("append").
FlagWithInput("-s ", interimOutput). FlagWithInput("-s ", prevOutput).
FlagWithOutput("-o ", output). FlagWithOutput("-o ", interimOutput).
FlagWithArg("--key ", "provideLibs"). FlagWithArg("--key ", "provideLibs").
FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(provideLibs, " "))) FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(provideLibs, " ")))
} else { builder.Temporary(prevOutput)
// If nothing to add, just cp to the final output
builder.Command().Text("cp").Input(interimOutput).Output(output)
} }
if len(requireLibs) > 0 {
prevOutput := interimOutput
interimOutput = android.PathForModuleOut(ctx, "temp_requireLibs.pb")
builder.Command().
BuiltTool("conv_linker_config").
Flag("append").
FlagWithInput("-s ", prevOutput).
FlagWithOutput("-o ", interimOutput).
FlagWithArg("--key ", "requireLibs").
FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(requireLibs, " ")))
builder.Temporary(prevOutput)
}
// cp to the final output
builder.Command().Text("cp").Input(interimOutput).Output(output)
builder.Temporary(interimOutput) builder.Temporary(interimOutput)
builder.DeleteTemporaryFiles() builder.DeleteTemporaryFiles()
} }