aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiyoung Kim <kiyoungkim@google.com>2024-03-22 18:00:40 +0900
committerKiyoung Kim <kiyoungkim@google.com>2024-03-25 11:20:11 +0900
commitee599d6694cf14bf582559b141d0ecf5b6a07105 (patch)
treefd24e9a1be19381ee1b14799d7fa801f7a00887f
parentbfa7f261d11f232e87d3de7d5c12b75813573a4e (diff)
downloadsoong-ee599d6694cf14bf582559b141d0ecf5b6a07105.tar.gz
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
-rw-r--r--filesystem/system_image.go27
-rw-r--r--linkerconfig/linkerconfig.go45
2 files changed, 60 insertions, 12 deletions
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
index 78ce3770c..5028a493e 100644
--- a/filesystem/system_image.go
+++ b/filesystem/system_image.go
@@ -56,19 +56,40 @@ func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root andr
output := root.Join(ctx, "system", "etc", "linker.config.pb")
// 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)
ctx.WalkDeps(func(child, parent android.Module) bool {
for _, ps := range child.PackagingSpecs() {
if _, ok := deps[ps.RelPathInPackage()]; ok {
- otherModules = append(otherModules, child)
+ modulesInPackageByModule[child] = true
+ modulesInPackageByName[child.Name()] = 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)
- 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())
return output
}
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 78b62d9b8..98aa40805 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -89,7 +89,7 @@ func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
output := android.PathForModuleOut(ctx, "linker.config.pb").OutputPath
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())
l.outputFilePath = output
@@ -101,7 +101,7 @@ func (l *linkerConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
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
interimOutput := android.PathForModuleOut(ctx, "temp.pb")
@@ -111,9 +111,9 @@ func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
FlagWithInput("-s ", input).
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
- for _, m := range otherModules {
+ for _, m := range provideModules {
if c, ok := m.(*cc.Module); ok && cc.IsStubTarget(c) {
for _, ps := range c.PackagingSpecs() {
provideLibs = append(provideLibs, ps.FileName())
@@ -122,18 +122,45 @@ func BuildLinkerConfig(ctx android.ModuleContext, builder *android.RuleBuilder,
}
provideLibs = android.FirstUniqueStrings(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 {
+ prevOutput := interimOutput
+ interimOutput = android.PathForModuleOut(ctx, "temp_provideLibs.pb")
builder.Command().
BuiltTool("conv_linker_config").
Flag("append").
- FlagWithInput("-s ", interimOutput).
- FlagWithOutput("-o ", output).
+ FlagWithInput("-s ", prevOutput).
+ FlagWithOutput("-o ", interimOutput).
FlagWithArg("--key ", "provideLibs").
FlagWithArg("--value ", proptools.ShellEscapeIncludingSpaces(strings.Join(provideLibs, " ")))
- } else {
- // If nothing to add, just cp to the final output
- builder.Command().Text("cp").Input(interimOutput).Output(output)
+ builder.Temporary(prevOutput)
}
+ 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.DeleteTemporaryFiles()
}