Dedupe logic to generate linker.config.pb
Between android_filesystem and generic_system_image.
`getLibsForLinkerConfig` will return a list of provideLibs and
requireLibs for the fileystem. `linkerConfig.BuildLinkerConfig` will
then filer out the non-stub libraries.
For `android_filesystem`, requireLibs is ignored for now to match the
logic in the kati built vendor.img
Test: m nothing --no-skip-soong-tests
Test: no diff in out/soong/.intermediates/build/make/target/product/generic/generic_system_image/android_common/gen/root-extra/system/etc/linker.config.pb
paste of cmd: https://diff.googleplex.com/#key=KAqqP9bhKZMD
Change-Id: I1f1d626a3a161fb2e12597909fd287533cbb8482
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index d178710..d0d4825 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -690,27 +690,13 @@
}
func (f *filesystem) buildLinkerConfigFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
- getCStubLibs := func() []android.Module {
- // Determine the list of C stub libraries that are part of this filesystem.
- // These will be added to `provideLibs`.
- // The current implementation assumes that stub libraries are listed explicitly in `deps`
- // (direct deps). If this is not true, ctx.VisitDeps will need to be replaced by ctx.WalkDeps.
- ret := []android.Module{}
- ctx.VisitDirectDeps(func(child android.Module) {
- if c, ok := child.(*cc.Module); ok && c.HasStubsVariants() {
- ret = append(ret, c)
- }
- })
- return ret
- }
-
if len(f.properties.Linker_config_srcs) == 0 {
return
}
- // cp to the final output
+ provideModules, _ := f.getLibsForLinkerConfig(ctx)
output := rebasedDir.Join(ctx, "etc", "linker.config.pb")
- linkerconfig.BuildLinkerConfig(ctx, builder, android.PathsForModuleSrc(ctx, f.properties.Linker_config_srcs), getCStubLibs(), nil, output)
+ linkerconfig.BuildLinkerConfig(ctx, builder, android.PathsForModuleSrc(ctx, f.properties.Linker_config_srcs), provideModules, nil, output)
f.appendToEntry(ctx, output)
}
@@ -823,3 +809,48 @@
func (f *filesystemDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
validatePartitionType(ctx, f)
}
+
+// getLibsForLinkerConfig returns
+// 1. A list of libraries installed in this filesystem
+// 2. A list of dep libraries _not_ installed in this filesystem
+//
+// `linkerconfig.BuildLinkerConfig` will convert these two to a linker.config.pb for the filesystem
+// (1) will be added to --provideLibs if they are C libraries with a stable interface (has stubs)
+// (2) will be added to --requireLibs if they are C libraries with a stable interface (has stubs)
+func (f *filesystem) getLibsForLinkerConfig(ctx android.ModuleContext) ([]android.Module, []android.Module) {
+ // we need "Module"s for packaging items
+ modulesInPackageByModule := make(map[android.Module]bool)
+ modulesInPackageByName := make(map[string]bool)
+
+ deps := f.gatherFilteredPackagingSpecs(ctx)
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ for _, ps := range android.OtherModuleProviderOrDefault(
+ ctx, child, android.InstallFilesProvider).PackagingSpecs {
+ if _, ok := deps[ps.RelPathInPackage()]; ok {
+ 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
+ })
+
+ return provideModules, requireModules
+}