Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee599d66 authored by Kiyoung Kim's avatar Kiyoung Kim
Browse files

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
parent bfa7f261
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -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
}
+36 −9
Original line number Diff line number Diff line
@@ -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()
}