From e604378aed9c09e0f4af4a7b8a407906d76908fc Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 20 May 2024 16:17:39 +0900 Subject: [PATCH] Add multilib.prefer32.deps to packaging base The property is used to prefer the 32-bit variant of a dep over the 64-bit variant. If 64-bit variant is the only available one, it is depended on. This will be used to include 32-bit preferred modules like drmserver and mediaserver in filesystem modules. Bug: N/A Test: go test ./... under soong/android Change-Id: Ic7185eb2044c9987f8d1e9b6cf7f0dbd235cf04c --- android/packaging.go | 51 ++++++++++++++++++++++++----- android/packaging_test.go | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 8 deletions(-) diff --git a/android/packaging.go b/android/packaging.go index a2b875528..ae412e1bb 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -155,11 +155,12 @@ type depsProperty struct { } type packagingMultilibProperties struct { - First depsProperty `android:"arch_variant"` - Common depsProperty `android:"arch_variant"` - Lib32 depsProperty `android:"arch_variant"` - Lib64 depsProperty `android:"arch_variant"` - Both depsProperty `android:"arch_variant"` + First depsProperty `android:"arch_variant"` + Common depsProperty `android:"arch_variant"` + Lib32 depsProperty `android:"arch_variant"` + Lib64 depsProperty `android:"arch_variant"` + Both depsProperty `android:"arch_variant"` + Prefer32 depsProperty `android:"arch_variant"` } type packagingArchProperties struct { @@ -198,8 +199,20 @@ func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []s ret = append(ret, get(p.properties.Deps)...) } else if arch.Multilib == "lib32" { ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...) + // multilib.prefer32.deps are added for lib32 only when they support 32-bit arch + for _, dep := range get(p.properties.Multilib.Prefer32.Deps) { + if checkIfOtherModuleSupportsLib32(ctx, dep) { + ret = append(ret, dep) + } + } } else if arch.Multilib == "lib64" { ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...) + // multilib.prefer32.deps are added for lib64 only when they don't support 32-bit arch + for _, dep := range get(p.properties.Multilib.Prefer32.Deps) { + if !checkIfOtherModuleSupportsLib32(ctx, dep) { + ret = append(ret, dep) + } + } } else if arch == Common { ret = append(ret, get(p.properties.Multilib.Common.Deps)...) } @@ -246,7 +259,7 @@ func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []s return FirstUniqueStrings(ret) } -func (p *PackagingBase) getSupportedTargets(ctx BaseModuleContext) []Target { +func getSupportedTargets(ctx BaseModuleContext) []Target { var ret []Target // The current and the common OS targets are always supported ret = append(ret, ctx.Target()) @@ -258,6 +271,28 @@ func (p *PackagingBase) getSupportedTargets(ctx BaseModuleContext) []Target { return ret } +// getLib32Target returns the 32-bit target from the list of targets this module supports. If this +// module doesn't support 32-bit target, nil is returned. +func getLib32Target(ctx BaseModuleContext) *Target { + for _, t := range getSupportedTargets(ctx) { + if t.Arch.ArchType.Multilib == "lib32" { + return &t + } + } + return nil +} + +// checkIfOtherModuleSUpportsLib32 returns true if 32-bit variant of dep exists. +func checkIfOtherModuleSupportsLib32(ctx BaseModuleContext, dep string) bool { + t := getLib32Target(ctx) + if t == nil { + // This packaging module doesn't support 32bit. No point of checking if dep supports 32-bit + // or not. + return false + } + return ctx.OtherModuleFarDependencyVariantExists(t.Variations(), dep) +} + // PackagingItem is a marker interface for dependency tags. // Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip(). type PackagingItem interface { @@ -278,7 +313,7 @@ func (PackagingItemAlwaysDepTag) IsPackagingItem() bool { // See PackageModule.AddDeps func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) { - for _, t := range p.getSupportedTargets(ctx) { + for _, t := range getSupportedTargets(ctx) { for _, dep := range p.getDepsForArch(ctx, t.Arch.ArchType) { if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) { continue @@ -292,7 +327,7 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter m := make(map[string]PackagingSpec) var arches []ArchType - for _, target := range p.getSupportedTargets(ctx) { + for _, target := range getSupportedTargets(ctx) { arches = append(arches, target.Arch.ArchType) } diff --git a/android/packaging_test.go b/android/packaging_test.go index 0570ec566..89df8efa4 100644 --- a/android/packaging_test.go +++ b/android/packaging_test.go @@ -15,6 +15,8 @@ package android import ( + "fmt" + "strings" "testing" "github.com/google/blueprint" @@ -584,3 +586,69 @@ func TestDebuggableDeps(t *testing.T) { runPackagingTest(t, config, bp, tc.expected) } } + +func TestPrefer32Deps(t *testing.T) { + bpTemplate := ` + component { + name: "foo", + compile_multilib: "both", // not needed but for clarity + } + + component { + name: "foo_32only", + compile_multilib: "prefer32", + } + + component { + name: "foo_64only", + compile_multilib: "64", + } + + package_module { + name: "package", + compile_multilib: "%COMPILE_MULTILIB%", + multilib: { + prefer32: { + deps: %DEPS%, + }, + }, + } + ` + + testcases := []struct { + compileMultilib string + deps []string + expected []string + }{ + { + compileMultilib: "first", + deps: []string{"foo", "foo_64only"}, + expected: []string{"lib64/foo", "lib64/foo_64only"}, + }, + { + compileMultilib: "64", + deps: []string{"foo", "foo_64only"}, + expected: []string{"lib64/foo", "lib64/foo_64only"}, + }, + { + compileMultilib: "32", + deps: []string{"foo", "foo_32only"}, + expected: []string{"lib32/foo", "lib32/foo_32only"}, + }, + { + compileMultilib: "both", + deps: []string{"foo", "foo_32only", "foo_64only"}, + expected: []string{"lib32/foo", "lib32/foo_32only", "lib64/foo_64only"}, + }, + } + for _, tc := range testcases { + config := testConfig{ + multiTarget: true, + depsCollectFirstTargetOnly: true, + } + bp := strings.Replace(bpTemplate, "%COMPILE_MULTILIB%", tc.compileMultilib, -1) + bp = strings.Replace(bp, "%DEPS%", `["`+strings.Join(tc.deps, `", "`)+`"]`, -1) + fmt.Printf("bp = %s\n", bp) + runPackagingTest(t, config, bp, tc.expected) + } +}