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:
parent
bfa7f261d1
commit
ee599d6694
2 changed files with 60 additions and 12 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue