diff options
-rw-r--r-- | android/variable.go | 7 | ||||
-rw-r--r-- | filesystem/filesystem.go | 63 | ||||
-rw-r--r-- | filesystem/filesystem_test.go | 9 | ||||
-rw-r--r-- | filesystem/system_image.go | 35 | ||||
-rw-r--r-- | fsgen/filesystem_creator.go | 25 |
5 files changed, 76 insertions, 63 deletions
diff --git a/android/variable.go b/android/variable.go index 548a7628e..a386473a9 100644 --- a/android/variable.go +++ b/android/variable.go @@ -596,9 +596,10 @@ type PartitionVariables struct { BoardAvbEnable bool `json:",omitempty"` - ProductPackages []string `json:",omitempty"` - ProductPackagesDebug []string `json:",omitempty"` - VendorLinkerConfigSrcs []string `json:",omitempty"` + ProductPackages []string `json:",omitempty"` + ProductPackagesDebug []string `json:",omitempty"` + VendorLinkerConfigSrcs []string `json:",omitempty"` + ProductLinkerConfigSrcs []string `json:",omitempty"` ProductCopyFiles map[string]string `json:",omitempty"` } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index d178710cf..d0d482561 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -690,27 +690,13 @@ func (f *filesystem) buildEventLogtagsFile(ctx android.ModuleContext, builder *a } 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 @@ var _ partition = (*filesystemDefaults)(nil) 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 +} diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go index cb27f6464..8fe5daca0 100644 --- a/filesystem/filesystem_test.go +++ b/filesystem/filesystem_test.go @@ -670,18 +670,21 @@ func TestInstallLinkerConfigFile(t *testing.T) { android_filesystem { name: "myfilesystem", deps: ["libfoo_has_no_stubs", "libfoo_has_stubs"], - linker_config_srcs: ["linker.config.json"] + linker_config_srcs: ["linker.config.json"], + partition_type: "vendor", } cc_library { name: "libfoo_has_no_stubs", + vendor: true, } cc_library { name: "libfoo_has_stubs", stubs: {symbol_file: "libfoo.map.txt"}, + vendor: true, } `) linkerConfigCmd := result.ModuleForTests("myfilesystem", "android_common").Rule("build_filesystem_image").RuleParams.Command - android.AssertStringDoesContain(t, "", linkerConfigCmd, "conv_linker_config proto --force -s linker.config.json") - android.AssertStringDoesContain(t, "", linkerConfigCmd, "--key provideLibs --value libfoo_has_stubs.so") + android.AssertStringDoesContain(t, "Could not find linker.config.json file in cmd", linkerConfigCmd, "conv_linker_config proto --force -s linker.config.json") + android.AssertStringDoesContain(t, "Could not find stub in `provideLibs`", linkerConfigCmd, "--key provideLibs --value libfoo_has_stubs.so") } diff --git a/filesystem/system_image.go b/filesystem/system_image.go index 6200df44d..898987dbc 100644 --- a/filesystem/system_image.go +++ b/filesystem/system_image.go @@ -59,40 +59,7 @@ func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root andr input := android.PathForModuleSrc(ctx, android.String(s.properties.Linker_config_src)) output := root.Join(ctx, "system", "etc", "linker.config.pb") - // we need "Module"s for packaging items - 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 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 - }) - + provideModules, requireModules := s.getLibsForLinkerConfig(ctx) builder := android.NewRuleBuilder(pctx, ctx) linkerconfig.BuildLinkerConfig(ctx, builder, android.Paths{input}, provideModules, requireModules, output) builder.Build("conv_linker_config", "Generate linker config protobuf "+output.String()) diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go index e470e91ca..bf5dfd92c 100644 --- a/fsgen/filesystem_creator.go +++ b/fsgen/filesystem_creator.go @@ -474,8 +474,8 @@ func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partiti return false } - if partitionType == "vendor" { - fsProps.Linker_config_srcs = f.createLinkerConfigSourceFilegroups(ctx) + if partitionType == "vendor" || partitionType == "product" { + fsProps.Linker_config_srcs = f.createLinkerConfigSourceFilegroups(ctx, partitionType) } var module android.Module @@ -509,18 +509,29 @@ func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partiti return true } -// createLinkerConfigSourceFilegroups creates filegroup modules to generate linker.config.pb for _vendor_ -// It creates a filegroup for each file in PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS. +// createLinkerConfigSourceFilegroups creates filegroup modules to generate linker.config.pb for the following partitions +// 1. vendor: Using PRODUCT_VENDOR_LINKER_CONFIG_FRAGMENTS (space separated file list) +// 1. product: Using PRODUCT_PRODUCT_LINKER_CONFIG_FRAGMENTS (space separated file list) +// It creates a filegroup for each file in the fragment list // The filegroup modules are then added to `linker_config_srcs` of the autogenerated vendor `android_filesystem`. -func (f *filesystemCreator) createLinkerConfigSourceFilegroups(ctx android.LoadHookContext) []string { +func (f *filesystemCreator) createLinkerConfigSourceFilegroups(ctx android.LoadHookContext, partitionType string) []string { ret := []string{} partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse - if linkerConfigSrcs := android.FirstUniqueStrings(partitionVars.VendorLinkerConfigSrcs); len(linkerConfigSrcs) > 0 { + var linkerConfigSrcs []string + if partitionType == "vendor" { + linkerConfigSrcs = android.FirstUniqueStrings(partitionVars.VendorLinkerConfigSrcs) + } else if partitionType == "product" { + linkerConfigSrcs = android.FirstUniqueStrings(partitionVars.ProductLinkerConfigSrcs) + } else { + ctx.ModuleErrorf("linker.config.pb is only supported for vendor and product partitions. For system partition, use `android_system_image`") + } + + if len(linkerConfigSrcs) > 0 { // Create a filegroup, and add `:<filegroup_name>` to ret. for index, linkerConfigSrc := range linkerConfigSrcs { dir := filepath.Dir(linkerConfigSrc) base := filepath.Base(linkerConfigSrc) - fgName := generatedModuleName(ctx.Config(), "vendor-linker-config-src"+strconv.Itoa(index)) + fgName := generatedModuleName(ctx.Config(), fmt.Sprintf("%s-linker-config-src%s", partitionType, strconv.Itoa(index))) srcs := []string{base} fgProps := &struct { Name *string |