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
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 78b62d9..98aa408 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -89,7 +89,7 @@
 	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 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 @@
 		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 @@
 	}
 	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()
 }