diff options
author | Kiyoung Kim <kiyoungkim@google.com> | 2024-03-22 18:00:40 +0900 |
---|---|---|
committer | Kiyoung Kim <kiyoungkim@google.com> | 2024-03-25 11:20:11 +0900 |
commit | ee599d6694cf14bf582559b141d0ecf5b6a07105 (patch) | |
tree | fd24e9a1be19381ee1b14799d7fa801f7a00887f | |
parent | bfa7f261d11f232e87d3de7d5c12b75813573a4e (diff) | |
download | soong-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.go | 27 | ||||
-rw-r--r-- | linkerconfig/linkerconfig.go | 45 |
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() } |